---
title: Errors
description: Every non-2xx answer from api.trlay.dev is one envelope, generated from the contract's closed code vocabulary.
canonical: https://tollrelay.com/docs/errors
lastmod: 2026-09-15
---

# Errors

Every non-2xx answer from api.trlay.dev is one envelope, generated from the contract's closed code vocabulary.

Every non-2xx response carries one envelope, application/problem+json, RFC 9457.

```json
{
  "type": "https://tollrelay.com/problems/mandate-exceeded",
  "title": "This call is over the mandate.",
  "status": 402,
  "detail": "The identity's mandate does not cover this call. The response says what remains.",
  "instance": "/verify",
  "code": "mandate_exceeded",
  "receipt": "rcpt_eu_...",
  "request_id": "req_..."
}
```

## Fields

| Field | Type | Description |
| --- | --- | --- |
| `type` | string | The problem's address under https://tollrelay.com/problems/. |
| `title` | string | One sentence for a person. Changes without notice. |
| `status` | integer | The HTTP status, repeated in the body. |
| `detail` | string | What happened and what to do next. Changes without notice. |
| `instance` | string, optional | The path of the request that failed. |
| `code` | string | The machine name, from the closed vocabulary below. A caller branches on this, never on title or detail. |
| `receipt` | string, optional | The receipt id this response reflects, when it reflects one. |
| `request_id` | string | The id of this request, echoed from x-request-id. |

## Codes

A caller branches on `status` and `code`, never on `title` or `detail`: both change without notice. Adding a code is a deliberate change to the contract's vocabulary.

| Status | Code | Title |
| --- | --- | --- |
| 400 | `idempotency_key_missing` | This write needs an Idempotency-Key. |
| 400 | `validation_failed` | The request does not fit the schema. |
| 401 | `credential_invalid` | That credential cannot be used. |
| 401 | `credential_missing` | This request needs a credential. |
| 401 | `token_invalid` | That identity token cannot be verified. |
| 402 | `mandate_exceeded` | This call is over the mandate. |
| 403 | `credential_revoked` | This credential is revoked. |
| 403 | `credential_untrusted` | This credential is not on the trust list. |
| 403 | `delegation_invalid` | This agent is not delegated by its organisation. |
| 403 | `identity_revoked` | This identity is revoked. |
| 403 | `membership_missing` | This person is not a member of the organisation. |
| 403 | `organisation_not_verified` | This identity's organisation has not passed verification. |
| 403 | `scope_missing` | This credential cannot do that. |
| 403 | `seller_not_allowed` | This seller is outside the mandate. |
| 403 | `seller_sanctioned` | This seller is on a sanctions list. |
| 404 | `identity_not_found` | There is no identity with that id. |
| 404 | `organisation_not_found` | There is no organisation with that id. |
| 404 | `route_not_found` | No route answers this path. |
| 404 | `verifier_not_found` | There is no verifier with that id. |
| 409 | `billing_not_configured` | This organisation has no billing set up. |
| 409 | `handle_taken` | That handle is taken. |
| 409 | `idempotency_conflict` | That Idempotency-Key was used with a different body. |
| 409 | `idempotency_in_flight` | A write with that Idempotency-Key is still running. |
| 409 | `region_immutable` | An organisation's region cannot change. |
| 422 | `envelope_binding_failed` | The envelope does not match the payment. |
| 422 | `settlement_unverifiable` | The settlement cannot be verified. |
| 422 | `subject_unresolvable` | The subject cannot be read. |
| 429 | `rate_limited` | Too many requests. |
| 500 | `internal` | Something went wrong on our side. |
| 501 | `not_implemented` | This surface is not live yet. |
