Skip to content

Authentication#

Every request to a versioned route (/api/v1/...) carries a Bearer credential and accepts an optional API version header, except provider OAuth callback routes that are reached by external provider redirects. The /health probes are unauthenticated.

There are two ways to authenticate, both sent as Authorization: Bearer <...>:

Method How Scope
Service API key Authorization: Bearer <service-api-key> (API_KEY, or optional API_KEY_2), validated at the edge. Not organization-scoped.
User token Authorization: Bearer <user-token> plus ?organization_id=<id>. The token + org are validated against the TeamBoost platform API; the request proceeds only if the user belongs to that organization. Scoped to the given organization.

The Bearer credential is matched against the configured service keys first; if it is not a service key, it is treated as a user token, which requires organization_id.

Header / param Value Notes
Authorization Bearer <service-api-key> or Bearer <user-token> Required.
organization_id (query) Organization id, e.g. 590789 Required for user tokens; ignored for service keys.
X-Api-Version CalVer YYYY.M.MICRO, e.g. 2026.6.2 Optional — omit to use the latest supported version.
# Service API key
curl https://<host>/api/v1/providers \
  -H "Authorization: Bearer <service-api-key>"

# User token scoped to an organization
curl "https://<host>/api/v1/providers?organization_id=590789" \
  -H "Authorization: Bearer <user-token>"

Authentication outcomes#

Situation Response
Valid service key 200, request proceeds
Valid user token, member of the organization 200, request proceeds (org-scoped)
User token without organization_id 400 missing_parameter
Non-integer organization_id 422 validation_error
Invalid / unrecognized credential 401 invalid_api_key
Valid user token, not a member of the organization 403 insufficient_permissions
TeamBoost platform API unreachable 503 service_unavailable

Version header behavior#

When X-Api-Version is omitted, the service uses the latest supported version. Send an explicit version to pin client behavior across releases. A version below the minimum or above the latest is rejected with 400 invalid_api_version.

On a successful authenticated request the response echoes the supported range:

  • X-Api-Latest-Version — newest version the service supports
  • X-Api-Minimum-Version — oldest version still accepted

Provider credentials

The Bearer auth above governs access to this service. It is separate from the per-provider credentials (e.g. a Linear API key) an organization stores for sync — those are encrypted at rest and managed via the credential endpoints; see the Linear page. OAuth-backed providers such as Basecamp, Google Calendar, and Zoho Projects use the OAuth install endpoints instead of direct token upload. Plane supports either direct PAT storage or bot OAuth installation. Their encrypted OAuth material uses the same credential store. Webhook secrets are planned — see the Roadmap.

OAuth callback exception

GET /api/v1/providers/{provider}/oauth/callback is unauthenticated so an OAuth provider can redirect to it. The callback must include the signed, expiring state returned by the authenticated authorization URL route; invalid state returns invalid_oauth_state.

OAuth install callback contract#

Start an organization-scoped OAuth install with the generic authorization route:

GET /api/v1/providers/{provider}/oauth/authorize?organization_id=<id>

When a provider requires an account or workspace to be selected before consent, also send targetAccountId (maximum 256 characters). The service signs that value into the ten-minute OAuth state; callback requests cannot replace it. State is signed, not encrypted, so the target id must not contain a secret.

Providers can redirect directly to the unauthenticated callback:

GET /api/v1/providers/{provider}/oauth/callback?state=<state>&code=<code>&location=<value>

The callback accepts one state, at most one code, and at most one error. Code-based providers require code; structural providers can instead require bounded provider callback parameters. For example, Plane's bot flow requires exactly one app_installation_id and does not use the callback code. Up to 16 additional, single-valued provider callback parameters fit the shared envelope. Parameter names are 1–128 ASCII letters, digits, dots, underscores, or hyphens; values are 1–2048 characters. code, state, error, organization, and target-account names are reserved. Duplicate, reserved, malformed, or oversized values are rejected.

An authenticated frontend can relay the equivalent callback through POST:

{
  "state": "<signed-state>",
  "code": "<authorization-code>",
  "callbackParameters": {
    "location": "<provider-value>"
  }
}

For a provider error, omit code and send error instead. For a structural code-less callback such as Plane, omit both and send the provider's required callbackParameters. The relay requires the same organization-scoped user token used to start authorization; the organization must match signed state. Callback codes, errors, and extra callback values are not returned, logged, or generically persisted. Successful token payloads and provider refresh handles are encrypted at rest, and callback responses contain credential metadata only.