Reference
Problem types
Every error the API returns is a problem document with a stable code. This page lists them all.
The shape of an error
Errors use application/problem+json (RFC 9457). Match on code: it never changes within /v1. The type URI opens the page for that code, and requestId is what to quote when you report a problem.
application/problem+json
{
"type": "https://api.tobie.team/problems/validation_failed",
"title": "Validation failed",
"status": 400,
"detail": "1 field failed validation",
"code": "validation_failed",
"instance": "/v1/tasks",
"requestId": "01JC0S7Z5F3X9QK2M4N6P8R0TV",
"errors": [
{
"path": "body.title",
"rule": "too_small",
"message": "Must contain at least 1 character"
}
]
}errors[] appears only on validation failures and never echoes the values you sent. Server errors say Internal error and nothing more. See Errors for the full guide.
All problem types
| Code | Status | Title | Meaning | Retry |
|---|---|---|---|---|
| bad_request | 400Bad Request | Bad request | The request could not be read: bad JSON, a wrong content type or a malformed value. | No |
| validation_failed | 400Bad Request | Validation failed | The request was readable, but one or more fields broke a rule. errors[] names each one. | No |
| idempotency_key_required | 400Bad Request | Idempotency key required | This write needs an Idempotency-Key header and the request did not send one. | No |
| unauthorized | 401Unauthorized | Unauthorized | The request needs a credential and was not authenticated. | No |
| invalid_token | 401Unauthorized | Invalid token | The bearer credential is missing, unknown, expired or revoked, or was not issued for this API. | No |
| oauth_token_required | 401Unauthorized | OAuth token required | The token is a sign-in session, not an OAuth access token issued to an app. | No |
| grant_revoked | 401Unauthorized | Grant revoked | The person revoked this app’s access, or never finished granting it. | No |
| wrong_environment | 401Unauthorized | Wrong environment | A test key was sent to the live API, or a live key to a test environment. | No |
| forbidden | 403Forbidden | Forbidden | The credential is valid, but it may not perform this operation. | No |
| insufficient_scope | 403Forbidden | Insufficient scope | The credential is valid but does not hold the scope this operation needs. | No |
| client_not_allowed | 403Forbidden | Client not allowed | This OAuth app is not allowed to connect, or may not act for this kind of user. | No |
| suspended | 403Forbidden | Suspended | Access is suspended for this credential, its owner, the employer or the app. | No |
| no_principal | 403Forbidden | No principal | The token is valid, but no active Tobie user or admin stands behind it. | No |
| csrf_failure | 403Forbidden | CSRF validation failed | A browser request that uses a session cookie failed its cross-site check. | No |
| dry_run_only | 403Forbidden | Dry run only | This credential may preview this write with dryRun, but may not run it. | No |
| approvals_require_human | 403Forbidden | Approvals require a human | Approvals are decided by a person at the keyboard, never by a key or an agent. | No |
| not_found | 404Not Found | Not found | The resource does not exist, or you may not see it. The API does not say which. | No |
| conflict | 409Conflict | Conflict | The request conflicts with the current state of the resource. | No |
| idempotency_in_progress | 409Conflict | Idempotent request in progress | A request with the same Idempotency-Key is still running. | After a pause |
| approval_required | 409Conflict | Approval required | This write can only run through an approved proposal. | No |
| approval_stale | 409Conflict | Approval stale | The approved plan no longer matches the resource, because it changed after the plan was made. | No |
| approval_principal_invalid | 409Conflict | Approval principal invalid | The credential that proposed this write is no longer valid, so the approval cannot run. | No |
| version_conflict | 412Precondition Failed | Version conflict | The If-Match version does not match the current version of the resource. | No |
| idempotency_payload_mismatch | 422Unprocessable Content | Idempotency payload mismatch | The Idempotency-Key was already used with a different request body. | No |
| rate_limited | 429Too Many Requests | Rate limited | This credential used up its request budget for the current window. | After a pause |
| internal_error | 500Internal Server Error | Internal error | Something failed on Tobie’s side. The response says nothing more, by design. | After a pause |
| not_configured | 503Service Unavailable | Not configured | Something this request depends on is not set up or not reachable right now. | After a pause |
| unavailable | 503Service Unavailable | Unavailable | The API, or this part of it, is switched off or temporarily down. | After a pause |
Retrying safely
- Retry only the codes marked After a pause. Every other code fails the same way until you change the request, the credential or the resource.
- Honor
Retry-Afterwhen it is present, and back off further on each attempt. - Retry a write with the same
Idempotency-Keyand the same body, so it cannot run twice. - Over MCP, a failed tool call carries the same
codeand aretryableflag that matches this table.