Skip to content

Errors

Every failure returns the same envelope with a machine-readable type and a plain-language message. The API never guesses a verdict.

API access is not on sale yet.

The endpoint is live and these docs describe it accurately. Access belongs to the Pro plan, which we have not opened for purchase — so a key cannot be issued today, and these pages are here to be read rather than acted on. Free accounts have no API access, and requests from one are refused with a 403. Nothing here is a waiting list; there is simply nothing to join yet.

The error envelope

Errors come back as { "error": { "type", "message" } }:

Error response
{
  "error": {
    "type": "invalid_request_error",
    "message": "`modality` must be one of: text, code, image, video"
  }
}

Status codes

StatusTypeWhen
400invalid_request_errorMalformed JSON or missing/invalid fields.
401authentication_errorMissing or invalid bearer key.
403permission_errorThe key is valid but lacks the scope the endpoint requires. The message names the missing scope — detection needs detect:write.
402quota_exceededThe account has spent its monthly detection quota. The cap is measured per account, not per key, so minting a second key does not raise it.
413invalid_request_errorThe request is too large: text exceeds 200,000 characters, mediaRef exceeds 25 MB of decoded media, or the request body exceeds that plus a small envelope. An oversize body is refused from the Content-Length header before it is read.
429rate_limit_errorToo many requests from this key. The limit is per key, per minute — 60 unless the key sets its own rate_limit_per_min. The response carries a Retry-After header in seconds.
500api_errorSomething broke on our side. Nothing is billed and no verdict is stored — retry, and if it persists, send us the response.
503service_unavailableThe engine for that modality could not be reached. Image and video run on a separate hosted inference service, so this is what you get when that service is down or misconfigured — never a guessed verdict.

Retries

429, 500 and 503 are the statuses worth retrying — everything else describes something about the request that will not change on a second attempt.

On 429, wait for the number of seconds in the Retry-After header before trying again. On 500 and 503, back off exponentially rather than retrying immediately.