{"openapi":"3.0.3","info":{"description":"A stand-in for a customer's own protected service — what sits behind `atria-proxy` in the sandbox, not part of Atria itself. It has no database and no Atria awareness: a real customer backend never checks for an Atria credential, the proxy in front of it does.\n\n**The happy path is three calls:**\n\n1. `POST /mock-login` — any login and password, back comes a JWT.\n2. `GET|POST|PUT|DELETE /mock-bl` — send that JWT as a bearer token; it echoes your payload and names you back.\n3. `POST /mock-logout` — same JWT; there is no server-side session to end, so it just answers `200`.\n\n**Nothing here is real.** The session key is random per process restart, so every token minted before one stops verifying after it, and no request is ever persisted past process memory. This is not `mock-cloud` (the CA sandbox at `sandbox.trustatria.com`) — the two are unrelated services documented separately.","title":"Atria sandbox — protected business endpoint","version":"0.1.11"},"servers":[{"description":"This service","url":".."}],"tags":[{"description":"A generic customer backend, independent of the Atria story — its own login, its own JWT. A-48..A-53.","name":"business-logic"}],"paths":{"/mock-bl":{"delete":{"description":"A-49..A-51. Every verb lands on the same handler — a business endpoint's method doesn't change what a mock owes the caller. Shares the 10 req/sec budget across all of `/mock-login`, `/mock-bl` and `/mock-logout` together (A-53), sliding window, not per caller.","operationId":"mockBlDelete","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockBlResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MISSING_JWT` (no bearer token) or `INVALID_JWT` (expired, forged, or signed by a different process)"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MOCK_RATE_LIMIT`"}},"security":[{"mockSessionJwt":[]}],"summary":"DELETE /mock-bl — requires the mock-login JWT, echoes the payload","tags":["business-logic"]},"get":{"description":"A-49..A-51. Every verb lands on the same handler — a business endpoint's method doesn't change what a mock owes the caller. Shares the 10 req/sec budget across all of `/mock-login`, `/mock-bl` and `/mock-logout` together (A-53), sliding window, not per caller.","operationId":"mockBlGet","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockBlResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MISSING_JWT` (no bearer token) or `INVALID_JWT` (expired, forged, or signed by a different process)"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MOCK_RATE_LIMIT`"}},"security":[{"mockSessionJwt":[]}],"summary":"GET /mock-bl — requires the mock-login JWT, echoes the payload","tags":["business-logic"]},"post":{"description":"A-49..A-51. Every verb lands on the same handler — a business endpoint's method doesn't change what a mock owes the caller. Shares the 10 req/sec budget across all of `/mock-login`, `/mock-bl` and `/mock-logout` together (A-53), sliding window, not per caller.","operationId":"mockBlPost","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockBlResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MISSING_JWT` (no bearer token) or `INVALID_JWT` (expired, forged, or signed by a different process)"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MOCK_RATE_LIMIT`"}},"security":[{"mockSessionJwt":[]}],"summary":"POST /mock-bl — requires the mock-login JWT, echoes the payload","tags":["business-logic"]},"put":{"description":"A-49..A-51. Every verb lands on the same handler — a business endpoint's method doesn't change what a mock owes the caller. Shares the 10 req/sec budget across all of `/mock-login`, `/mock-bl` and `/mock-logout` together (A-53), sliding window, not per caller.","operationId":"mockBlPut","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockBlResponse"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MISSING_JWT` (no bearer token) or `INVALID_JWT` (expired, forged, or signed by a different process)"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"`MOCK_RATE_LIMIT`"}},"security":[{"mockSessionJwt":[]}],"summary":"PUT /mock-bl — requires the mock-login JWT, echoes the payload","tags":["business-logic"]}}},"components":{"schemas":{"MockBlResponse":{"description":"The caller's own token already proved who they are, so this names them back rather than echoing the raw token.","properties":{"api_version":{"example":"0.1.11","type":"string"},"exp":{"description":"The token's `exp` claim, unix seconds.","type":"integer"},"name":{"description":"The `sub` claim from the bearer JWT — the `login` originally sent to `/mock-login`.","type":"string"},"payload":{"description":"The request body if present and JSON; else the query string as an object; else `null`."}},"type":"object"},"Error":{"description":"Every failure on this service has this shape. The `error` value is a stable reason code, never a description of which rule matched.","properties":{"error":{"example":"INVALID_JWT","type":"string"}},"type":"object"}},"securitySchemes":{"mockSessionJwt":{"description":"The token from `POST /mock-login`. This service's own JWT, opaque to Atria — nothing here validates an Atria credential.","scheme":"bearer","type":"http"}}}}