Request Tracing and Cost Headers
Every inference response carries the ids and, where it can, the price of the call that produced it. That is enough to attribute spend per request without polling a reporting endpoint afterwards β and enough to tie our records to yours when something needs explaining.
This works on all inference endpoints; it is a property of the transport, not of a particular model.
Attaching your own identifier
Send X-Client-Request-Id with the request and we store it, echo it back, and report it as client_request_id in Usage Logs. Use whatever identifies the work on your side β an order number, a job id, a customer reference.
curl -sS -D - -o /dev/null \
--url 'https://api.aimlapi.com/v1/chat/completions' \
--header 'Authorization: Bearer <YOUR_AIMLAPI_KEY>' \
--header 'Content-Type: application/json' \
--header 'X-Client-Request-Id: order-8f21c4' \
--data '{"model": "openai/gpt-5", "messages": [{"role": "user", "content": "Hi"}]}'The value must be 1β128 characters from AβZ, aβz, 0β9, ., _, : and -.
A value outside that alphabet β or longer than 128 characters β is silently dropped. Your request still runs and is still billed exactly as normal; you simply get no correlation back, and client_request_id stays null in the logs. A malformed header is never a reason to fail a request, so nothing in the response tells you it was ignored. If you generate these ids from user input, sanitise them on your side.
What comes back
x-inference-id
Always
x-client-request-id
When you sent a valid X-Client-Request-Id
x-aimlapi-credits-used
Non-streaming JSON responses
x-aimlapi-usd-spent
Non-streaming JSON responses
x-inference-id is the handle for everything downstream. It is the id the charge is recorded under, so it comes back as reference_id in GET /v2/billing/transactions and as inference_id in Usage Logs. For an asynchronous generation it is the same id that submit returned as generation_id, so a submit and its polls share one id.
x-aimlapi-credits-used is an integer count of credits; x-aimlapi-usd-spent is the same amount in USD.
When the cost is not in a header
Two response types deliberately carry no cost headers, because the price is not known by the time headers are sent.
Streaming responses. Headers flush before the first token, so the total cannot be there yet. The cost arrives in the final SSE chunk instead, under meta.usage:
Binary audio (wav). The cost only arrives in a summary after the audio itself, and holding the whole response back to fill in a header would mean buffering it in memory. Read the cost of these calls from Usage Logs instead.
The correlation headers β x-inference-id and x-client-request-id β are present in both cases; it is only the cost that moves.
Following one request end to end
Send the request with your own
X-Client-Request-Id.Read
x-inference-idfrom the response and keep it next to your own record.Later, find the request in Usage Logs β by
client_request_idif you sent one, otherwise byinference_idβ for its status, tokens and cost.Find the money it moved in
GET /v2/billing/transactions, where the same inference id appears asreference_id.
The charge is recorded after your response was delivered β and, for async video, after the generation reports completed. A ledger entry that is not there yet the moment a call returns is expected, not missing.
Last updated
Was this helpful?