Skip to main content

Authentication

Every protected endpoint expects an Authorization header. Two credential types are accepted, and you choose whichever matches how you're calling the API.

API keys

API keys look like sk_ followed by 32 base64url characters. They're intended for scripts and server-side integrations — anything that runs without a human at the keyboard. Every key is long-lived: it stays valid until you revoke it, which is what makes it suitable for unattended automation.

There are two kinds of sk_ key, and they differ in who owns them and how much throughput they get:

  • Personal API keys. Every seat comes with one. It's a per-seat, low-throughput key for light, occasional scripting — handy for a quick one-off automation alongside your interactive work. It is tied to you as an individual rather than to automation that runs at scale.
  • Service-account API keys. These are org-level keys built for headless, unattended use — CI pipelines, agents, and backend services that run with no human present. They belong to the organization rather than to any one person and run at a higher throughput tier. Service-account keys are available only on the API plan — see API plan for what it unlocks and how to turn it on. The official SDKs authenticate with this kind of key; personal seat keys and browser sessions are not supported there.

Both kinds are sent the same way: the key goes verbatim in the Authorization header, with no Bearer prefix.

Authorization: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

In practice — calling /me with a key:

curl https://api.slothbox.dev/me \
-H "Authorization: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

If the API plan lapses

Service-account keys are an entitlement of the API plan, so they follow it. If the organization's API plan lapses, its service-account keys are suspended, not deleted: a request made with one is rejected with 403 and the machine-readable error code api_plan_lapsed:

{ "error": { "message": "…", "code": "api_plan_lapsed" } }

If the organization resubscribes, the same keys resume working automatically — there is nothing to re-issue and nothing to rotate. Authorization results are cached briefly at the edge, so both suspension and resumption can take up to five minutes to propagate. Personal API keys belong to the seat, not the API plan, and are unaffected.

Notes:

  • Keys are shown once at creation time and stored as a SHA-256 hash on our side. If you lose one, revoke it and create another.
  • Every key is associated with an organization. A personal key belongs to a seat within an organization; a service-account key is owned by the organization itself. A key's access is scoped to the organization it belongs to.
  • Keys cannot mint more keys — see Quickstart.

Cognito ID tokens

Browsers and the official web app sign in through a Cognito user pool and send the raw ID token in the same header — again verbatim, with no Bearer prefix. The CLI and the MCP server authenticate the same way, exchanging an OAuth sign-in for a session token.

Authorization: eyJraWQ...

Unlike sk_ keys, these JWT sessions are short-lived and TTL-scoped: each token expires after a fixed window and has to be refreshed. The web app, CLI, and MCP server refresh silently for you; if you're building a custom integration against the user pool you'll need to do the same. For anything that runs unattended, reach for a long-lived sk_ key instead.

Public endpoints

A small handful of routes are reachable without any credential — health checks, the GitHub OAuth callback, the public invite preview, and the CloudFormation template that customers deploy into their own account. The API reference marks these with an open lock icon.