Skip to content

Errors

Every error has one JSON shape. Branch on its code, show its details and quote its request id. The table lists each code the API returns and when.

When the API refuses a request it answers with a status of 400 or above and the same JSON shape on every endpoint. Your code reads code. A person reads message.

A request to create a webhook endpoint without a url, for example:

422 Unprocessable EntityJSON
{"error": {"code": "validation_error","message": "The request could not be validated","details": [{ "field": "url", "message": "Invalid input: expected string, received undefined" }],"request_id": "req_790d3c81de2a406395e413a56865b6f1"}}
codestring

A stable name in snake_case. Branch on this, never on the message.

messagestring

One plain sentence about what went wrong. The wording can change.

detailsarray

Zero or more { "field", "message" } pairs that point at the part of the request that caused the error.

request_idstring

The id of the request, the same value as the X-Request-Id response header. Quote it when you ask for help.

Error codes

StatusCodeWhen
400invalid_jsonThe body is not valid JSON, or is not a JSON object or array.
400invalid_requestThe Idempotency-Key header is longer than 255 characters.
400invalid_cursorcursor is not a value a list returned.
400not_supported_yetThe content is audio or video, which the API does not screen yet. Nothing is stored or charged.
401missing_api_keyThere is no Authorization header, or it is not a bearer token.
401invalid_api_keyThe key is malformed, unknown, revoked or expired.
402quota_exceededThe monthly checks and the extra checks are used up. details says how many the request needs and how many are left.
403insufficient_scopeThe key lacks the scope the endpoint asks for.
403plan_limitThe plan does not include what was asked, or its limit is reached: a named template on the Free plan, one endpoint, guideline or wordlist too many, a batch larger than the plan takes. details names the limit.
404not_foundNo such path, or no such resource in the key's project. A resource of another project answers the same.
404template_not_foundNo template of the project has that slug.
409idempotency_key_reusedThe Idempotency-Key was already used with another body.
409idempotency_in_progressA request with the same Idempotency-Key is still running.
409template_not_publishedThe template exists and has no published version.
409input_not_storedRe-moderating a moderation whose content was not stored, or has been removed.
409is_childRe-moderating one field of a form. Re-moderate the form.
409not_resolvedReopening a queue item that is not resolved.
409action_disabledExecuting an action that is disabled.
409slug_takenA guideline or wordlist of the project already has that slug.
409conflictAnother record already holds a value that must be unique.
413payload_too_largeThe body is larger than 2 MB.
422validation_errorThe request does not fit the endpoint, or a value in it is refused. details lists each problem.
429rate_limitedThe key passed its requests a minute. The Retry-After header says how long to wait.
500internal_errorSomething failed on Infrared's side.

The pages on authentication, idempotency, rate limits and checks cover their own codes in depth. Statuses and failures covers what a moderation can answer without an HTTP error, such as status: "invalid".

Validation errors

A 422 carries one entry in details per problem.

  • field is the path of the value, joined with dots: url, event_types.0, items.3.input. A problem with the body as a whole reads body, and one with the query string reads query.
  • message says what is wrong with it. Most messages come from the schema check and can change wording, so match on field.
The problemfieldmessage
A required value is missingurlInvalid input: expected string, received undefined
A field the endpoint does not knowbodyUnrecognized key: "secret"
A number out of rangelimitToo big: expected number to be <=100
An id of the wrong kindmoderation_idmust be a mod_ id

Some values are checked after the schema, and then message at the top says what was refused: url: Target resolves to a private address (localhost).

A submission that fails a template's own validation is not an HTTP error. It answers 200 with a moderation whose status is invalid.

Server errors

A fault on Infrared's side answers 500 and reads the same, whatever failed:

500 Internal Server ErrorJSON
{
  "error": {
    "code": "internal_error",
    "message": "Something went wrong on our side",
    "details": [],
    "request_id": "req_660bf6f2a3dd480e8a20bec694ba90ea"
  }
}

The cause is logged on Infrared's side under the request id. Retry the request, and send the id to support if it keeps failing.

A few requests answer 500 today where you would expect a 4xx:

  • A body that is not UTF-8, or that uses a Content-Encoding the API cannot read.
  • A reason longer than 255 characters on the author endpoints that block, suspend or enable. Keep it to 255.
  • A filter value outside its list on two lists: status on GET /v1/moderations and priority on GET /v1/queue.

Errors inside a batch

One bad item does not fail a batch. The batch answers 200 or 202, and the item that was refused takes its place in data as an error:

One entry of dataJSON
{"object": "error","index": 1,"error": { "code": "template_not_found", "message": "Template old-listing not found", "details": [] }}

index is the item's position in the request, counted from 0. The entry has no request_id of its own: use the one of the batch.

What to retry

AnswerWhat to do
429 rate_limitedWait the number of seconds in Retry-After, then send it again.
5xx, or no answerSend it again after a short wait that grows with each try. When you create a moderation, reuse the same Idempotency-Key.
409 idempotency_in_progressThe first request is still running. Wait, then send it again.
402 quota_exceededSending it again will not help until checks are added. Decide what your product does with unscreened content.
Any other 4xxDo not retry as it is. Change the request, the key or the plan.

When a moderation carried an Idempotency-Key, a refusal such as 402, 404 or 422 is stored under it. Once the cause is fixed, send the moderation with a new key, or the stored refusal comes back.

Next

Something missing or unclear on this page? Write to support@useinfrared.com.