Errors
Every error has the same shape and a fixed code, so your code can decide what to do without reading messages.
Error
{
"error": {
"code": "not_found",
"message": "Table not found",
"retryable": false
}
}code | One of the codes below. Decide on this. |
message | A short explanation for people. It may change; don’t match on it. |
retryable | true when the same call may succeed if you try again later. |
details | Sometimes: extra facts, such as the current values in a conflict. |
Codes
| Code | Status | Means | What to do |
|---|---|---|---|
invalid | 400 | The input doesn’t match the reference: a missing or unknown field, a wrong type, a bad id. | Fix the request. Retrying won’t help. |
forbidden | 401, 403 | 401: no key, or not valid for this workspace. 403: the key may not do this. | Check the key and its access in Settings → Agents. |
not_found | 404 | It doesn’t exist, or this key can’t see it. | Check the id and the key’s project access. |
conflict | 409 | It changed since you read it, it’s in Trash, or an Idempotency-Key was reused with a different body. | Read it again, then decide. details.conflicts holds the current values when there are any. |
limit | 429 | Too many calls, or the daily write limit is used up. | Wait for Retry-After, then retry. |
in_progress | 409 | The same Idempotency-Key is still running. | Retry the same call in a few seconds. |
unknown_outcome | 409 | An earlier attempt with this key may have written; its outcome is unknown. | Read the objects before writing again. |
unavailable | 500, 503 | Something failed on our side. | Retry reads. Retry writes only with the same Idempotency-Key. |
An example: a conflict
When you update cells with the values you last read and someone changed them first, nothing is written and you get the current values back:
Response 409
{
"error": {
"code": "conflict",
"message": "Cells changed",
"retryable": false,
"details": {
"conflicts": [{ "recordId": "tr_…", "fieldId": "tf_status", "current": "refunded" }]
}
}
}Every answer, error or not, has an x-request-id header. Log it; it’s the quickest way for us to find a call.