Base URL
Production:https://api.stoutdata.ai
All endpoints are prefixed with /api/. For example, the job list for an org is GET https://api.stoutdata.ai/api/orgs/:orgId/jobs.
Authentication
There are two primary schemes:User Bearer tokens
Users authenticate with JWT access tokens in theAuthorization header:
/api/auth/login with email and password, or complete the SSO flow.
Box API keys
Boxes authenticate with a static API key in a custom header:/etc/lager/control_plane.json. Stout stores an HMAC-SHA256 hash of each key keyed by a server-side pepper, so a database leak alone can’t yield working keys. (Older rows may still be bare SHA-256 and are transparently upgraded on next use.) A lost key cannot be recovered, only rotated by re-running install-stout.
Rate limits
- 100 requests per minute per IP across all endpoints.
- Auth endpoints (
/api/auth/login,/api/auth/register,/api/auth/refresh) have stricter per-route limits on top of the global cap. - Backed by Redis in production so limits apply across control-plane replicas.
- Exceeding the limit returns
429 Too Many Requestswith aRetry-Afterheader.
Error format
Every error response has a JSON body with at least these fields:issues array from Zod:
409 Conflict with a message identifying which field clashed.
Conventions
- IDs — all resources use UUIDs.
- Timestamps — ISO 8601 with time zone offsets (e.g.
2026-04-21T14:32:11.000Z). - Pagination — list endpoints accept
?page=<n>&limit=<n>and return{ items, total, page, limit }. Default limit 20, max 100. - Correlation IDs — every response includes an
x-request-idheader. Include it when reporting bugs so Stout support can find your request in the logs.
Coming soon
A per-endpoint reference — request/response shapes for every route — is in the works. Until then, the control-plane source atstout/services/control-plane/src/routes/ is authoritative, and the dashboard’s network panel is the quickest way to see a worked example of any endpoint.