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

# Request identifiers

> Every answer of the HTS Pilot API carries an identifier in X-Request-ID - what it is, how to send a reference of your own, and what to quote when asking for help.

Every answer the API writes, successful or not, carries the header `X-Request-ID`: an identifier the API makes
for that one call, 32 hexadecimal characters. It names one request, and it is what to quote when you report a
problem.

```
HTTP/1.1 404 Not Found
Content-Language: en
X-Request-ID: 6d2d12f6e4ef4ec18f5588be89fa12dc

{"detail":"Lookup not found","code":"not_found"}
```

The API always makes this identifier itself. A caller cannot choose it.

## Sending a reference of your own

To match a call with your own logs, send your own reference in the request header `X-Request-ID`. It does not
replace the identifier of the API: it comes back in a second header, `X-Client-Request-ID`, and is recorded next
to the call.

```bash
curl -i https://htspilot.com/api/usage/me \
  -H "X-API-Key: hts_EXAMPLE_KEY_REPLACE_ME" \
  -H "X-Request-ID: order-sync-2026-10-03.0042"
```

```
HTTP/1.1 200 OK
X-Request-ID: 08fe1d6ee53049d8a3c3df42f9bccfd8
X-Client-Request-ID: order-sync-2026-10-03.0042
```

| Header | Direction | Value |
| --- | --- | --- |
| `X-Request-ID` | Answer | The identifier the API made for this call: 32 hexadecimal characters. On every answer the API writes |
| `X-Request-ID` | Request, optional | Your own reference: 8 to 64 characters of letters, digits, `.`, `_` and `-`, the first one a letter or a digit |
| `X-Client-Request-ID` | Answer | Your reference, returned as sent. Only when you sent a valid one |

A reference of any other shape is ignored without an error: the call runs, and no `X-Client-Request-ID` comes
back. The reference is yours: it need not be unique, and the API never uses it to recognise a repeated call
(there is no idempotency key, see [Errors](/errors.md#handling-errors)).

## Unexpected failures

An unexpected failure answers `500` and repeats the identifier in the body, so that it survives in a log that
keeps bodies and drops headers:

```json
{
  "detail": "System error, please try again later",
  "code": "internal_error",
  "request_id": "5f0c2a9e4b7d4e0f9a1b2c3d4e5f6a7b"
}
```

(The shape as the specification gives it: no `500` could be captured for these pages.) `request_id` is in the
body of a `500` only. For every other answer, read the header.

## Answers that have no identifier

An answer that was produced before the request reached the API may carry neither the header nor a `code`: a
`502`, `503` or `504` during an outage or a release, or a refusal at the edge of the network. Fall back on the
HTTP status then, and quote the time of the call.

## What to quote when asking for help

- the value of `X-Request-ID` from the answer; that alone is enough to find the call;
- without it: the method and path, the time of the request in UTC to the second, and the HTTP status;
- never the API key. Its first characters, as the application shows them, identify it.

Log `X-Request-ID` with every failed call, and with successful ones where you can afford it.

## Other identifiers

| Where | Identifier | Use |
| --- | --- | --- |
| A webhook delivery | `X-HTS-Delivery` header, the same number as `id` in the body | Ignore a delivery you have already processed ([Webhooks](/webhooks.md)) |
| A lookup | `id` | Everything that happened to it is in its `events` |
| A batch row | `row_index`, with `lookup_id` once it was classified | Follow a row from the file to its lookup |
| A SKU | `external_ref` | Your own reference (an ERP or PIM id), stored and returned as sent |
