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

# Request IDs

> Identify every request so a problem can be traced end to end.

# Request IDs

Every API response includes an `X-Request-ID` header identifying that specific request. It
is what turns "it failed yesterday afternoon" into something we can actually look up.

## Receiving it

Nothing to do: the header comes back on every response, including the `401`, `403`, `404`,
`422`, `429` and `502` errors.

```bash theme={null}
curl -i https://api.ya.onl/v1/orders -H "X-API-Key: yv_live_v1_your_api_key"
```

```
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-ID: 9f2c1a7b4e8d4c3fa1b6e5d0c7a92341
```

<Note>
  Store this value in your logs alongside the response. If you need to report a problem, the
  `X-Request-ID` of the failing request is the first thing we will ask for — with it we find
  the exact request in our records in seconds, instead of guessing.
</Note>

<Warning>
  **The one exception is `500 InternalServerError`.** An unhandled exception is answered
  from a layer that sits outside where the header is added, so that response carries **no**
  `X-Request-ID` — precisely the case where it is most needed. On our side the identifier is
  still recorded; to report a `500`, send us the exact timestamp with its timezone and the
  endpoint, and we can still locate it.
</Warning>

## Sending your own

If your system already generates request identifiers, send them and we adopt them: they
land in our logs and in the audit record, so your identifier and ours are the same one and
the trace crosses the boundary between both systems.

```bash theme={null}
curl https://api.ya.onl/v1/orders \
  -H "X-API-Key: yv_live_v1_your_api_key" \
  -H "X-Request-ID: 550e8400-e29b-41d4-a716-446655440000"
```

<Warning>
  **It must be a version 4 UUID** (with or without hyphens). A value in any other format is
  **silently discarded** and we generate one of our own instead: the response will carry an
  `X-Request-ID` that is not the one you sent, and your identifier will not be recorded
  anywhere.
</Warning>

The identifiers we generate are 32 hexadecimal characters without hyphens
(`9f2c1a7b4e8d4c3fa1b6e5d0c7a92341`); both forms are valid.

## One per attempt, not per operation

A request ID identifies **one request attempt**. If you retry after a timeout, that new
request carries a **new** request ID — which is what keeps the two attempts distinguishable
in the records.

That is the exact opposite of an **idempotency key**, which must be **the same** across
every retry so the operation does not run twice. Do not use the same value for both:

| | Request ID | Idempotency key |
| - | - | - |
| **Header or field** | `X-Request-ID` | endpoint-specific (for example `event_id` in [Template Messages](/en/outbound/cart-abandonment)) |
| **Changes across retries** | Yes, one per attempt | **No**, it must repeat |
| **What it is for** | Tracing what happened | Preventing the operation from happening twice |
| **Who chooses it** | You or us | Always you, from your own domain |

<Warning>
  Using a fresh per-attempt identifier as an idempotency key breaks duplicate protection
  without raising any error: each retry looks like a distinct operation. On an endpoint that
  sends messages, that means your customer receives the message twice.
</Warning>


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