> ## Documentation Index
> Fetch the complete documentation index at: https://developers.argosidentity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Codes and Retries

> Unit API error response format, what each error code means and how to respond, response headers, retry rules, and the versioning policy.

When a call cannot produce a result, Unit API returns a non-`200` HTTP status and an error body. **Error responses are not billed.** The call is still recorded, and for trial projects it counts toward the monthly limit.

## Error response format

```json theme={null}
{
  "code": "MISSING_PARAMETER",
  "message": "idImage: Invalid input: expected string, received undefined"
}
```

| Field | Description |
| - | - |
| `code` | An English code that identifies the error type. **Branch on this value.** |
| `message` | A human-readable description. It often names the field at fault, but it can change without notice, so do not branch on it. |

***

## Response headers

| Header | When it is sent | Description |
| - | - | - |
| `X-Request-Id` | Every response | ID of a single HTTP request |
| `X-Trace-Id` | Every response | ID of the whole internal processing flow the request created |
| `X-Tx-Id` | Calls that were read and entered processing | Same value as `txId` in a successful response. It is also sent with error responses, so you can record the TX ID even if you cannot read the body |
| `Retry-After` | `429`, some `503` | Seconds to wait before calling again (integer) |

`X-Tx-Id` is not sent for requests rejected before the body is read: malformed JSON (`400 REQUEST_INVALID`) and an oversized body (`413 REQUEST_TOO_LARGE`). When contacting support, include `X-Request-Id` and `X-Trace-Id` along with `X-Tx-Id`.

***

## Error codes

### Request problems (4xx)

The same request returns the same result until you fix it. **Do not retry as is.**

| HTTP | code | Meaning | What to do |
| :-: | - | - | - |
| 400 | `MISSING_PARAMETER` | A required field was not sent | Add the missing field and call again |
| 400 | `INVALID_PARAMETER_FORMAT` | A field has the wrong type or format. Empty strings and `null` also fall here | Fix the value and call again |
| 400 | `UNKNOWN_PARAMETER` | A field or query parameter that is not in the contract was sent | Check field names for typos |
| 400 | `PARAMETER_OUT_OF_RANGE` | A value is outside the allowed range. Oversized images fall here | Bring the value within range |
| 400 | `REQUEST_INVALID` | The request cannot be parsed. Malformed JSON and Base64 that does not decode to an image fall here | Check the request body and image encoding |
| 401 | `AUTHENTICATION_FAILED` | The `x-api-key` header is missing or cannot be parsed | Check the header name and value |
| 401 | `INVALID_API_KEY` | The key does not exist or was revoked by a reissue. Calling another region's host also returns this error | Check the current key and the project region in the dashboard |
| 403 | `ACCESS_FORBIDDEN` | The key is valid, but the project status does not allow the call (closed project) | Check the project status |
| 409 | `STATE_CONFLICT` | The same request is still being processed by the source. Occurs only for ID authenticity checks and stay status checks | Call again after a short wait |
| 413 | `REQUEST_TOO_LARGE` | The request body exceeds the limit | Reduce the image size |
| 415 | `UNSUPPORTED_MEDIA_TYPE` | `Content-Type` is not `application/json` | Fix the header |
| 422 | `ADDITIONAL_AUTH_UNSUPPORTED` | The source requested additional identity authentication, which Unit API does not support | Retrying returns the same result. Verify by other means |
| 429 | `TRIAL_LIMIT_EXCEEDED` | The trial project has used up its monthly limit | Call after `Retry-After` (00:00 UTC on the first of next month), or switch the project |
| 429 | `RATE_LIMIT_EXCEEDED` | The call rate limit was exceeded | Call after `Retry-After` |

### Input image problems (502)

The engine responded normally but could not find what it needed in the image you sent. Sending the same image again returns the same result, so **call again with a newly captured image.**

| HTTP | code | Meaning | What to do |
| :-: | - | - | - |
| 502 | `ID_NOT_RECOGNIZED` | ID-OCR could not find text on the front of the ID | Recapture with less cropping, blur, and glare. Also check that the issuing country and ID type are correct |
| 502 | `FACE_NOT_DETECTED` | FACE-COM or FACE-LIVE-PSV could not find a face in an image | `message` names the image (`originFace`, `targetFace`, or `faceImage`). Recapture that image |

### Server and source problems (5xx)

These are not caused by your request. Retry using the rules below.

| HTTP | code | Meaning | What to do |
| :-: | - | - | - |
| 500 | `INTERNAL_SERVER_ERROR` | Internal server error | Retry a few times with a delay. Contact support if it persists |
| 502 | `UPSTREAM_ERROR` | The verification engine or source could not process the request | Retry with a delay. Contact support if it repeats for the same input |
| 502 | `AGENCY_REQUEST_REJECTED` | The source rejected the request ARGOS sent. You do not need to change your request | Do not retry. Contact support with the TX ID |
| 503 | `UPSTREAM_UNAVAILABLE` | The source or engine is temporarily unavailable. Common during source maintenance windows | Retry after `Retry-After` if present; otherwise retry with increasing delays |
| 504 | `UPSTREAM_TIMEOUT` | The engine or source did not respond in time. **Whether it was processed is unknown** | Do not retry right away. Follow [Duplicate calls and retries](#duplicate-calls-and-retries) below |

> [!NOTE]
>
> New error codes can be added within `v1`. If you receive an unknown `code`, handle it by its HTTP status (4xx or 5xx).

***

## Duplicate calls and retries

Unit API does not accept idempotency keys. **Sending the same request twice is processed and billed as two calls.**

* A call for which you received no response, or `504 UPSTREAM_TIMEOUT`, may have been processed. Before retrying, check whether the call appears in the dashboard call history.
  * If you received the `X-Tx-Id` header, search by TX ID.
  * If not, find it in the `referenceId` column of the call history CSV. For this to work, **send a different `referenceId` for each call.**
* Limit 5xx retries to about three, with increasing delays. Example: after 1, 2, and 4 seconds
* Trial projects count error calls toward the monthly limit, so limit retries even more strictly.

### Response time

Record checks wait for the source's response and can take several seconds. For example, a driver's license check can take 5–12 seconds. Set a generous client timeout (60 seconds or more). A short timeout can make you treat a processed call as failed and retry it, which bills it twice.

***

## Versioning policy

The `v1` in the path is the contract version.

**Changes applied within the same version**: make sure unknown values do not break your code.

* New APIs, new optional request fields, new response fields
* A required request field becoming optional
* New enum values, new error `code`s, improved `message` wording

**Changes released as a new version**: `v1` is not overwritten.

* Removing an API, or changing a path or method
* Adding a required request field, or making an optional field required
* Removing or renaming response fields; removing, renaming, or changing the meaning of enum values or error `code`s
* Changing field types, `null` rules, success conditions, or HTTP statuses

Fields marked "not covered by the contract", such as `agency` and `data.raw`, are outside this policy. They can change without notice when the source or engine changes.

***

## When contacting support

Include the following values.

* TX ID (`txId` or `X-Tx-Id`)
* `X-Request-Id` and `X-Trace-Id`
* Call time (UTC) and the API you called
* The HTTP status and `code` you received


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.