Shape
{
"error": {
"code": "quota_exceeded",
"message": "This upload would exceed your storage quota.",
"details": { "usedBytes": 107374182400, "quotaBytes": 107374182400 }
}
}details is present only when there is something actionable in it, and its contents vary by code — treat it as advisory.
Codes
| Code | Status | What to do |
|---|---|---|
unauthorized | 401 | Check the key. Missing, malformed, unknown, revoked and expired all look the same on purpose. |
upgrade_required | 402 | The workspace is on the free plan. Nothing to retry. |
insufficient_scope | 403 | The key lacks a scope. `details.required` names it; create a key that has it. |
not_found | 404 | No such resource, or it belongs to another workspace — deliberately the same answer. |
invalid_request | 400 | Bad body. `details.issues` lists field paths and reasons. |
folder_error | 400 | Duplicate or invalid folder name, or too deep. `details.code` says which. |
conflict | 409 | Already exists — a contact with that email, typically. Usually safe to skip. |
not_editable | 410 | The transfer has been sent, revoked or expired. Composing is over. |
quota_exceeded | 413 | Storage is full. `details` carries used and total bytes. Delete something. |
transfer_too_large | 413 | One transfer exceeded the plan ceiling. `details.limitBytes` is the cap. |
rate_limited | 429 | Back off. Honour the `Retry-After` header. |
email_budget_exhausted | 429 | Daily outbound email spent. The transfer is still live — share its link. |
internal_error | 500 | Ours. `details.requestId` ties it to our logs — quote it if you get in touch. |
Retrying
Retry 429 after the interval and 500 with backoff. Do not retry any other 4xx — they are deterministic and the same request will fail identically.
Writes are safe to retry when a response is lost. Finalizing a transfer twice does not re-send it, and registering the same folder path twice lands in the folder that already exists. The one exception is creating a transfer, which makes a new draft each time — drafts you abandon are swept after 24 hours, so the cost of a duplicate is nothing.
A note on 404
A resource that exists but belongs to another workspace returns 404, not 403. A 403 would confirm the id is real, which turns any endpoint into a way of finding out what other people's ids are. You cannot tell the two apart, and that is intended.