> For the complete documentation index, see [llms.txt](https://docs.tryterra.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tryterra.co/vantage-api-docs/documentation/errors.md).

# Errors

## Error format

All error responses follow the [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) problem-detail format:

```json
{
  "type": "https://docs.tryterra.co/errors/not-found-error",
  "title": "Resource Not Found",
  "status": 404,
  "detail": "resource not found",
  "instance": "/api/v1/orders"
}
```

| Field      | Meaning                                       |
| ---------- | --------------------------------------------- |
| `type`     | A URI identifying the error category          |
| `title`    | Short human-readable summary                  |
| `status`   | The HTTP status code, repeated in the body    |
| `detail`   | Human-readable explanation of this occurrence |
| `instance` | The request path that produced the error      |

## Status codes

| Status | When you'll see it                                                                                                                                                                                  |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Malformed request: invalid JSON, missing required fields or query parameters (e.g. `test_taker_id`), invalid IDs or pagination parameters                                                           |
| `401`  | Missing or invalid credentials - check your `dev-id` / API key and the auth scheme ([Account setup](/vantage-api-docs/account-setup-and-api-keys.md#authentication))                                |
| `403`  | Credentials are valid but the action is not allowed: suspended account, account without Vantage access, ordering a product disabled in your catalog, or calling the simulate endpoint in production |
| `404`  | Resource not found - includes orders that exist but do not belong to you                                                                                                                            |
| `409`  | Conflict - e.g. activating a kit that is already activated                                                                                                                                          |
| `422`  | Semantically invalid - e.g. a simulate event that is not a valid transition from the current status                                                                                                 |
| `500`  | Something went wrong on Terra's side - retry with backoff, and contact support if it persists                                                                                                       |
| `503`  | An upstream supplier service is temporarily unavailable - retry with backoff                                                                                                                        |

### Payment and idempotency errors

* `402` - the payment could not be authorized when creating an order. Nothing was created and nothing was charged; it is safe to retry (e.g. after the end user updates their payment details).
* `409` - an `Idempotency-Key` you already used was sent with a different request body. Generate a fresh key for a genuinely new order.

## Validation errors on order creation

`POST /api/v1/orders` returns a problem-detail body extended with a per-field breakdown:

```json
{
  "type": "https://api.terra-diagnostics.com/errors/validation-error",
  "title": "Validation Failed",
  "status": 400,
  "detail": "One or more required fields are missing or invalid",
  "instance": "/api/v1/orders",
  "invalid_fields": [
    {
      "field": "PhoneNumber",
      "message": "PhoneNumber is not a valid phone number for the provided country code",
      "tag": "phone_with_country",
      "value": "1234567890"
    }
  ]
}
```

Surface `invalid_fields[].message` to fix the request; each entry names the offending field, the failed validation rule (`tag`), and the rejected value.

## Handling errors well

* **Retry `5xx` and `503` with exponential backoff**; do not retry `4xx` (fix the request instead).
* **Retry `POST /api/v1/orders` safely with an `Idempotency-Key` header.** Send a unique key per order attempt (a UUID is fine); retrying with the same key and the same body returns the original result instead of creating a second order or charge. The same key with a *different* body returns `409`. Without the header, creation is not deduplicated - fall back to checking `GET /api/v1/orders` for your `client_order_reference_id` before retrying (see [Best practices](/vantage-api-docs/documentation/best-practices.md)).
* On `401`/`403`, verify which environment you are calling: sandbox and production access are enabled separately ([Account setup](/vantage-api-docs/account-setup-and-api-keys.md)).
