Skip to main content
Every response from the Exo API carries an X-Request-Id header. It is the one handle that resolves a single call.
The same value appears inside every problem body as requestId, so a logged error payload is self-describing even if you discarded the headers.

It is on every response, including the empty ones

This matters more than it sounds. Four routes return 204 No Content, and a 204 has no body to put a requestId in. Those routes are written to return no body at all rather than an empty response object, precisely so the header the dependency stack stamps survives. So DELETE /v1/keys/{key_id}, DELETE /v1/sandbox/keys/{key_id}, DELETE /v1/subjects/{subject_id} and DELETE /v1/me all give you a request id even though they give you nothing else.

Capturing it

The habit worth forming: log the request id on every call, not only on failures. When something looks wrong two days later, the successful call is often the one that needs explaining.

What to do with it

  • Quote it in support. With a request id, one specific call can be found. Without it, the answer starts with “which one”.
  • Attach it to your own traces. Putting the Exo request id on your span turns a cross-system investigation into a lookup.
  • Include it in user-facing error surfaces, quietly. A support ticket that arrives with the id already in it skips a round trip.

The format

Request ids look like req_ followed by a hex string. Treat the whole value as opaque: match on it, do not parse it, and do not assume the length is fixed.

Sending your own

There is no supported way to set the request id from the client in v1. The value on the response is the one Exo assigned, and it is the one to quote.

Next

Errors

The problem envelope that repeats this id as requestId.

Rate limits

The other headers on every response, and what to do with them.