Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.busha.io/llms.txt

Use this file to discover all available pages before exploring further.

Error envelopes

Errors come in two shapes depending on which surface returned them. OAuth2 protocol endpoints (/oauth2/auth, /oauth2/token, /oauth2/revoke) return RFC 6749 §5.2 shape:
{
  "error": "invalid_grant",
  "error_description": "code has already been used"
}
Busha resource API errors return:
{
  "status": "error",
  "message": "Insufficient scope",
  "error": {
    "name": "insufficient_scope",
    "message": "this endpoint requires balances:read"
  }
}
error_description is human-readable diagnostic text — do not surface it verbatim to end users.

OAuth2 errors

ErrorSurfaceCauseFix
invalid_requestAll OAuth2 endpointsMalformed request — missing parameter, bad encoding, wrong content type.Validate your request shape against the Endpoints reference.
invalid_client/oauth2/tokenWrong client_id, wrong client_secret, or wrong authentication method.Use HTTP Basic auth with URL-encoded client_id:client_secret.
invalid_grant/oauth2/tokenCode reused, code expired (10 min window), PKCE mismatch, or refresh token already rotated (family revoked).For codes: make your callback handler idempotent — deduplicate on state or the code itself. For refresh tokens: treat as a hard disconnect and prompt re-authorization.
invalid_scope/oauth2/authScope not in the catalog, or not in your approved_scopes.Compare your requested scopes against the catalog and your approved set on the dashboard.
unauthorized_client/oauth2/authClient status is pending, rejected, or suspended.Check your app status on the dashboard.
access_deniedCallback (/callback)User clicked Cancel on the consent screen.Render a “continue without connecting” path in your UI.
redirect_uri does not matchOAuth2 endpointsredirect_uri is not byte-identical to a registered URI.Compare bytes against the dashboard value. Check trailing slash, scheme, port, path casing.

Resource API errors

HTTP statusError nameCauseFix
401 UnauthorizedAccess token expired, revoked, or signature verification failed.Refresh the access token. Force a JWKS refetch if the kid is unknown.
403 Forbiddeninsufficient_scopeThe token does not include the scope required by this endpoint.Inspect the scp claim in the access token. Re-authorize with the broader scope set.

Common gotchas

invalid_grant on code exchange Token exchange is not idempotent — authorization codes are single-use. If your callback handler runs twice (user double-clicks, browser retry), the second exchange returns invalid_grant. Deduplicate on the state value or the code itself in your callback handler. invalid_grant on refresh A refresh token can only be used once. If you replay a previously-used refresh token, Busha revokes the entire token family — all tokens for that user are immediately invalidated. Handle any invalid_grant on a refresh as a hard disconnect and send the user through the authorization flow again. Access token still works after refresh token revocation Revoking a refresh token prevents new tokens from being minted, but does not invalidate an already-issued access token. JWTs self-expire at exp (~1 hour). This is by design. If you need instant invalidation, layer a server-side allowlist on critical endpoints. openid scope not shown on consent screen openid and offline_access are protocol scopes that Busha hides from the consent UI. If you received an id_token and refresh_token, they were granted successfully.