> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.truvo.com/llms.txt.

# Errors

When a request fails, the body tells you what went wrong, which fields caused it, and what to do about it. Branch your code on `error.code` and `error.retry_action.type`. The `message` is written for a person.

## The error envelope

```json
{
  "error": {
    "code": "needs_information",
    "message": "The quote request needs more information.",
    "field_errors": [
      {
        "path": "application.applicant.email",
        "message": "This fact is required."
      }
    ],
    "retry_action": {
      "type": "supply_facts",
      "summary": "Supply the missing facts and send the request again."
    },
    "doc_url": "https://docs.truvo.com/v1/errors/needs_information"
  },
  "request_id": "req_..."
}
```

| Field                | What it holds                                                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `error.code`         | One of the codes in the table below.                                                                                     |
| `error.message`      | A short explanation for a person.                                                                                        |
| `error.field_errors` | A list of fields, each with a `path` and a `message`, or `null`.                                                         |
| `error.retry_action` | What to do next, as a `type` and a `summary`.                                                                            |
| `error.doc_url`      | A link for the code, in the form `https://docs.truvo.com/v1/errors/<code>`. Each link opens the code table on this page. |
| `request_id`         | The ID of this response. It starts with `req_`. Include it when you contact Truvo support.                               |

Every answer, success or error, carries its ID in a `Request-Id` header, and an error body repeats it as `request_id`.

## Error codes

| Code                     | HTTP | What it means                                                                                                                                                                                                                                                                                                  |
| ------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_json`           | 400  | The request body isn't valid JSON.                                                                                                                                                                                                                                                                             |
| `invalid_cursor`         | 400  | The `cursor` isn't one that this list or feed returned. It applies to every paged read: `GET /v1/quote-requests`, `GET /v1/requests`, `GET /v1/event-subscriptions`, and the event feed, `GET /v1/events`. Send a `next_cursor` from an earlier page of the same read, or leave the cursor out to start again. |
| `authentication_failed`  | 401  | The key is missing or isn't valid.                                                                                                                                                                                                                                                                             |
| `forbidden`              | 403  | The key doesn't have authority for this action.                                                                                                                                                                                                                                                                |
| `not_found`              | 404  | The resource doesn't exist, or it's outside your authority.                                                                                                                                                                                                                                                    |
| `conflict`               | 409  | A request key conflict or a version conflict.                                                                                                                                                                                                                                                                  |
| `quote_expired`          | 409  | The quote has expired.                                                                                                                                                                                                                                                                                         |
| `price_changed`          | 409  | The quote has a newer version with a different price.                                                                                                                                                                                                                                                          |
| `purchase_not_supported` | 409  | The quote has no purchase through the API.                                                                                                                                                                                                                                                                     |
| `event_cursor_expired`   | 410  | The event feed, `GET /v1/events`, keeps events for 30 days. It can't resume from this cursor because retention deleted an event after it, or a sandbox reset voided it. Read each resource you track, then read the feed again without a cursor.                                                               |
| `request_too_large`      | 413  | The request body is too large.                                                                                                                                                                                                                                                                                 |
| `invalid_input`          | 422  | The input isn't valid. `field_errors` lists the fields.                                                                                                                                                                                                                                                        |
| `needs_information`      | 422  | Required facts are missing. Truvo returns this before it asks any carrier.                                                                                                                                                                                                                                     |
| `rate_limited`           | 429  | The key or its organization reached a rate limit, per minute or, in the sandbox, per day. The message names the limit.                                                                                                                                                                                         |
| `internal_error`         | 500  | Something went wrong inside Truvo.                                                                                                                                                                                                                                                                             |
| `service_unavailable`    | 503  | A service that Truvo needs is down. Try the request again later, after the seconds in the `Retry-After` header.                                                                                                                                                                                                |

Only the purchase operations return `quote_expired`, `price_changed`, and `purchase_not_supported`. The API doesn't have those operations yet.

## Retry actions

| Type                  | What to do                                                            |
| --------------------- | --------------------------------------------------------------------- |
| `none`                | Don't send the request again.                                         |
| `retry`               | Try the request again later.                                          |
| `correct_input`       | Fix the fields in `field_errors`, then send the request again.        |
| `supply_facts`        | Add the missing facts in `field_errors`, then send the request again. |
| `read_status`         | Read the resource again.                                              |
| `use_new_request_key` | Send the request with a new `Idempotency-Key`.                        |
| `wait`                | Wait, then send the request again.                                    |
| `contact_support`     | Contact Truvo support with the `request_id`.                          |