Skip to content

Errors

Errors use HTTP status codes and a JSON body with a stable, machine-readable code, a message for people, and the request's ID.

402 application/json
{
  "error": {
    "code": "quota_exceeded",
    "message": "This organisation has used all 1,000 marks of this month on its plan. Upgrade the plan for more, or wait for the 1st of next month (UTC).",
    "request_id": "req_7Hc2kQm0Zt1L"
  }
}

Branch on code, never on message: codes are part of API v1 and won't change; messages may get clearer. Every response, success or not, carries the same ID in its X-Request-Id header. Quote it when you write to us.

Codes

Error codes
StatusCodeMeaningWhat to do
400invalid_requestThe request is malformed or a field is out of range.Fix the request; the message names the field.
400unknown_fieldA field the endpoint doesn't know.Check the field's spelling against the reference.
400option_not_availableAn option of a later release.Leave it out for now; the changelog says when it arrives.
401missing_api_keyNo bearer key in the Authorization header.Send Authorization: Bearer sk_….
401invalid_api_keyThe key isn't one of ours.Check the key; create a new one if it's lost.
401api_key_revokedThe key was revoked or its project deleted.Use another key.
402quota_exceededThe month's allowance is used up.Wait for the 1st of the month (UTC), or upgrade.
403insufficient_scopeThe key lacks this endpoint's scope.Use a key with the scope, or create one.
403ip_not_allowedThe address isn't on the key's IP allowlist.Call from an allowed address, or update the allowlist.
403key_not_allowed_in_urlA key with scopes beyond tsa was sent in a URL.Use a tsa-only key, and rotate the one you sent.
404not_foundNo endpoint at this path.Check the path and the API version.
404upload_not_foundThe upload named in "upload" isn't one this key can use: unknown, used, older than an hour, or made by another key.Make a new upload with this key (POST /v1/uploads).
405method_not_allowedThe endpoint doesn't take this method.See the Allow header.
413payload_too_largeThe body is over the endpoint's limit.4 MB per request: send larger files (up to 25 MB) through POST /v1/uploads. 4 KB for time-stamp queries.
415unsupported_media_typeThe file or the request's Content-Type isn't accepted.Send PNG, JPEG or WebP as multipart/form-data.
422content_blockedPOST /v1/mark: the safety check blocked the picture; nothing was marked. The body's "safety" says why.Don't retry the same picture. The checks it ran count; the mark doesn't.
429rate_limitedToo many calls this minute for this key.Wait Retry-After seconds, then retry.
500internal_errorSomething failed on our side.Retry with backoff; nothing was charged.
502mark_failedThe file couldn't be marked and verified; no file was returned.Retry once; if it persists, contact support with the request ID.
503marker_unavailableThe marking service is briefly unavailable.Retry with backoff; nothing was charged.
503tsa_unavailableThe time-stamp server is briefly unavailable.Retry with backoff; nothing was charged.
503storage_unavailableUploads are briefly unavailable.Retry with backoff; nothing was charged, and the upload is kept.

Retrying

  • 429: wait the number of seconds in Retry-After.
  • 500, 502, 503: retry with exponential backoff (1 s, 2 s, 4 s…), up to a few times. Failed calls are never counted against your allowance.
  • Other 4xx: don't retry unchanged; fix the request first.