Errors
Every error response uses the same JSON envelope:
{ "error": "insufficient_scope", "message": "token is missing the `projects:write` scope"}error— a stable machine code you can branch on. It won’t change for a given condition.message— a human-readable detail. Don’t parse it; it may change.
Status codes
Section titled “Status codes”| Status | error code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed or invalid request body / parameters. |
| 401 | unauthorized | Missing, invalid, expired, or revoked token. |
| 403 | forbidden | Authenticated, but you don’t have access to the resource. |
| 403 | insufficient_scope | Your token lacks the scope this operation needs. |
| 404 | not_found | The resource doesn’t exist or you can’t see it. |
| 409 | conflict | The request conflicts with current state (e.g. a duplicate name). |
| 429 | too_many_requests | Rate limit exceeded — see pagination & limits. |
| 500 | internal | Something went wrong on our side. Safe to retry with backoff. |
- 404 vs 403. To avoid leaking whether a resource exists, reads of resources
you can’t access return
404 not_foundrather than403. insufficient_scopevsforbidden.insufficient_scopemeans the token is too narrow (mint or use a token with the needed scope).forbiddenmeans you don’t have access regardless of token.- Retries. Retry
429after theRetry-Afterheader, and5xxwith exponential backoff. Don’t retry4xx(except429) without changing the request. - Request IDs. Every response includes an
X-Request-IDheader. Include it when reporting an issue so we can trace it.