Errors and troubleshooting
Common response shapes#
Depending on where a failure happens, the JSON error structure may differ.| Layer | Typical status | Example shape |
|---|
| Request validation | 422 | { "field": ["message"] } |
Token endpoint (/oauth/access-token) | 400, 401, 403, 422 | { "success", "message", "details" } |
Introspect (/oauth/introspect) | 422 | { "success", "message", "data" } |
Revoke (/oauth/revoke) | 422 | { "success", "message", "data" } |
Protected resource route (/api/*) | 401, 403, 404 | { "message": "..." } |
Quick reference#
| Symptom | Likely cause | Action |
|---|
400 on token request | Access token invalid or expired | Request a new token |
401 with invalid_client on token request | Wrong client ID or secret | Fix stored credentials |
401 on /api/* | Missing, invalid, or expired token | Request a new token and verify the Authorization header |
403 on token request | Enterprise account is inactive | Contact your account administrator |
403 on /api/* | Token is missing required scopes | Request a token using the documented helper endpoint |
404 on /api/* | Company linked to this client could not be found | Verify the OAuth client is associated with an active company |
422 on token request | Missing required fields | Send full JSON body with client_id and client_secret |
422 on introspect or revoke | Token is invalid, expired, or not provided | Re-authenticate and pass a valid token |
429 | Rate limit exceeded | Back off and retry |
Common examples#
Invalid client credentials#
Returned by POST /oauth/access-token when the client_id or client_secret is incorrect.{
"success": false,
"message": "Client authentication failed. Check client ID/secret.",
"details": {
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}
}
Inactive enterprise#
Returned by POST /oauth/access-token when the enterprise account is inactive.{
"success": false,
"message": "Inactive enterprise."
}
Invalid or expired token on a protected route#
Returned by /api/* routes when the Authorization header is missing or the token is no longer valid.{
"message": "Unauthenticated."
}
Insufficient scope#
Returned by /api/* routes when the token does not include the required scopes.{
"message": "Token does not have the required scope."
}
Company not found#
Returned by /api/* routes such as GET /api/tags when no company is linked to the OAuth client.{
"message": "Company not found."
}
Invalid or missing token on introspect / revoke#
Returned by POST /oauth/introspect or POST /oauth/revoke when the token body is missing or the token is not recognized.{
"success": false,
"message": "Token required."
}
{
"success": false,
"message": "Invalid or expired token."
}
Token not found on revoke#
Returned by POST /oauth/revoke when the provided token cannot be found.{
"success": false,
"message": "Token not found."
}
Rate limiting#
/api/* routes are rate limited. Expect approximately 60 requests per minute per IP. Confirm the actual limit for your deployment before publishing this value.Modified at 2026-04-09 14:14:08