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: bd3bd07b7db548ebaa8f9c7e76803fc3
{"detail":"Lookup not found","code":"not_found"}
The API always makes this identifier itself. A caller cannot choose it.
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.
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: 19143318d520426083bd8fc57e297232
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).
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:
{
"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.
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.
- the value of
X-Request-IDfrom 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.
| 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) |
| 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 |