Errors#
Every error response carries a stable, machine-readable error code and a
human-readable message:
{ "status": "error", "error": "invalid_api_key", "message": "Invalid API key." }
Match on error, not on the message text — messages may be reworded, codes won't.
Current error codes#
These are the codes reachable through the endpoints that exist today:
error |
Status | Likely cause | Fix |
|---|---|---|---|
invalid_api_version |
400 | Unsupported X-Api-Version (below minimum, above latest, or malformed CalVer) |
Send a valid YYYY.M.MICRO version in [minimum, latest], or omit the header to use latest (see Authentication) |
bad_request |
400 | A request is structurally valid but uses a disallowed current path, such as direct OAuth-token upload | Follow the provider's documented endpoint path; Basecamp OAuth tokens must be installed through OAuth |
missing_parameter |
400 | Authenticating with a user token but organization_id is absent |
Add ?organization_id=<id> (see Authentication) |
oauth_not_supported |
400 | OAuth was requested for a provider that does not implement OAuth install | Use the provider's documented credential method |
invalid_oauth_state |
400 | OAuth callback state is malformed, expired, tampered, or for a different provider | Restart the provider OAuth authorization flow |
oauth_authorization_failed |
400 | The OAuth provider redirected back with an authorization error | Retry authorization or check provider consent/client settings |
oauth_token_exchange_failed |
400 | The generic OAuth callback is missing or has invalid code/structural parameters | Retry authorization; confirm the callback shape, redirect URI, and OAuth client settings |
oauth_exchange_failed |
400 | Provider-specific OAuth exchange, installation binding, or stored bundle parsing failed | Restart authorization; verify the OAuth app redirect URI and provider installation |
invalid_webhook_payload |
400 | A provider delivery body is malformed, oversized, or does not match the configured subscription | Check provider push configuration and the documented envelope |
invalid_api_key |
401 | Missing or unrecognized Bearer credential (service key or user token) | Check Authorization: Bearer <...>; for a user token confirm it is valid |
oauth_token_refresh_failed |
401 | Stored OAuth token is expired/revoked or cannot be refreshed | Re-authorize the provider for that organization |
webhook_authentication_failed |
401 | The provider delivery credential is missing, invalid, expired, or does not match configured claims | Check authenticated push/OIDC configuration and retry with a valid provider token |
insufficient_permissions |
403 | Valid user token, but the user is not a member of the requested organization | Use an organization_id the user belongs to |
unknown_provider |
404 | The provider name in the URL isn't a registered provider | Check the spelling against GET /api/v1/providers |
credential_not_found |
404 | Sync or credential verification was requested before an organization stored/installed provider credentials | Store an API credential or complete OAuth install for that provider |
webhook_subscription_not_found |
404 | Webhook status/disable was requested before this organization enabled a provider subscription | Enable the provider webhook subscription first |
projection_errors_remain |
409 | Confirm was requested while one or more imported task entries still have blocking projection errors | Resolve user mappings or edit the affected task entries, then confirm again |
active_webhook_subscription |
409 | Credential deletion or a cross-account OAuth replacement was attempted while a provider watch is routable | Disable the webhook subscription before changing the credential |
webhook_account_ambiguous |
409 | More than one organization attempted to route the same provider account, or durable routing state is ambiguous | Disable the conflicting registration and investigate the subscription index/state |
oauth_not_configured |
503 | Provider OAuth app settings are missing or unusable in the service environment | Configure the provider OAuth env vars and restart the service |
capability_not_supported |
400 | The provider exists but does not support the requested capability or OAuth flow | Check the provider's declared capabilities and docs page |
oauth_provider_not_configured |
503 | Provider OAuth app environment variables are missing or incomplete | Configure the provider OAuth client id, secret, redirect URI, and scopes |
service_unavailable |
503 | A dependency (Mongo, Redis, or the TeamBoost platform API) is temporarily unreachable | Retry with backoff; check /health/ready |
Provider authentication errors
invalid_signature remains available for providers whose webhook contract
signs the request body. Gmail uses webhook_authentication_failed because
Cloud Pub/Sub supplies a Google-signed OIDC Bearer token instead.