Skip to the content

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-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)
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