Skip to main content

Request headers

Two rules about everything else you send:
  • x-hopscotch-* request headers are reserved. We remove every inbound header in that namespace before doing anything with your request. Sending one has no effect, and no header you send can change how a request is routed or served.
  • Your headers do not reach the model provider. The upstream request is built from your body, and from nothing else you sent. If a parameter matters to a provider, send it in the body, which is forwarded as you wrote it.

Response headers

The four diagnostic headers are set when there is something to say and are absent otherwise. Treat them as diagnostics: read them in logs, do not build behaviour on them, and expect the set to grow. Nothing else from upstream reaches you. In particular, provider rate-limit headers are not forwarded: the limits you are subject to are ours, so a provider’s remaining-quota headers would describe a budget that is not yours and tell you nothing you can act on. Read our own limits from the 429 codes in Errors instead.
Every response carries the same id on two headers: x-hopscotch-request-id, which is ours, and x-request-id, which is the one the official OpenAI SDKs surface on their error objects. Every error envelope repeats it as request_id. Quote it when you ask us about a request. Without it we are guessing at which of your requests you mean.

Token counts

A non-streamed response carries token counts where an OpenAI-compatible client already looks for them: the usage object in the response body, as the provider reported it. A streamed response cannot do that, because the body is a sequence of events and the counts are only final at the end. So a streamed response carries one extra line, immediately before its terminating data: [DONE]:
A line beginning with a colon is a comment that the server-sent events specification requires a parser to ignore, so this is invisible to your SDK and to any conforming client. It is there for anybody who wants the counts without waiting for them to appear in the dashboard. A streamed response carries Hopscotch’s own token counts as a server-sent events comment line, written immediately before data: [DONE]:
The usage line
A line beginning with a colon is a comment the server-sent events specification requires a parser to ignore, so your SDK does not see it and nothing in your streaming loop needs to change. Read it only if you want it.
Counts not reported
Fields are omitted rather than set to zero when a provider did not report them, so “the provider did not say” stays distinguishable from “nothing was used”. reported: true with zeros means zero. An absent field means unknown. The counts are the provider’s own. Nothing is re-counted or estimated. A stream that is cut off carries no usage line, because there are no final counts to report. On a response that is not streamed there is no separate counts line. The provider’s own usage object inside the JSON body is what you read, exactly as you would from OpenAI. Either way, the figures we settle your balance against are the ones on your Activity screen. Where to read the counts, stated once so there is no doubt: on a streamed response, the comment line above. On a response that is not streamed, the usage object in the body, which is where an OpenAI-compatible client already looks. Two rules that make the difference between reading this correctly and quietly mis-reading it:
  • Absent is not zero. A count the provider did not report is omitted rather than sent as 0, because “we were not told” and “none were used” are different facts and only one of them is free.
  • reported: false means we have no counts, not that the request was free. It carries no token fields at all.
Ignore fields you do not recognise. This object gains fields, and v moves only when a reader would have to behave differently.