The hidden prompt tokens in cheap LLM APIs

One fixed prompt of about 90 tokens went to every route of every model on 2026-10-12. Some routes reported 4,469 input tokens. Two reported 14,111.

·UplinkSwitch·All posts

The check

Every day UplinkSwitch sends one fixed prompt of about 90 tokens to every route of every model it lists, and reads back usage.prompt_tokens. A clean route reports 76 to 127 input tokens for it, depending on the developer's tokenizer. A route that reports hundreds or thousands is counting something the prompt did not contain.

On 2026-10-12 the check covered 107 routes across four hosts. The counts below are what those routes reported.

What came back

HostRoutesOver 200 tokensLargest count
Host A66174,471
Host B321114,111
Host C8at least 18,938
Host D111,171

Input tokens reported for the same prompt of about 90 tokens, 2026-10-12. One sample per route.

  • Host A, 66 routes: GPT routes about 4,469; Gemini routes 352; one Gemini route 2,213.
  • Host B, 32 routes: GPT routes 4,280 to 4,469; Claude routes 380 and 540 (clean Claude routes 76 to 127); Grok 289; a Grok 4.7 route 1,325; two GLM routes serving third-party modified builds 14,111 each.
  • Host C, 8 routes: one GPT route 8,938.
  • Host D, 1 route: its one route 1,171.

The same models on other routes report 89. The GPT counts land near 4,469 on two hosts. The two GLM routes at 14,111 serve third-party modified builds, not the developer's own weights.

What it means

The simplest explanation for a fixed extra count is that the host prepends its own system prompt to every request before it reaches the model. The model's tokenizer counts it, and on a per-token API the host's customer pays for it on every request.

A 4,400-token prefix on a 300-token request is 93% of the input bill. For a short request, the prefix is the request.

It also changes what the model sees. Your system prompt is no longer the first thing in the context, and the instructions ahead of it are not yours.

No host is named here, and this is not an accusation. A count can have other causes. The point is that it can be measured, and that the measurement is cheap.

How UplinkSwitch handles it

  • You are billed no more input tokens than your request could hold, whatever a route reports (how tokens are counted).
  • The daily check publishes whether each model's count held, at /proof. GET https://api.uplinkswitch.com/v1/proof carries the canary text and the verdicts, so the check can be repeated.
  • Since today, a request smaller than a route's own prompt is sent to a cleaner route first.

Check your own provider

Send a tiny prompt with max_tokens set to 1 and read usage.prompt_tokens. A handful of tokens is your prompt plus the chat template. Hundreds or thousands is something the host added. Run it against the developer's own endpoint for the same model to get the baseline.

shell
curl https://YOUR_PROVIDER/v1/chat/completions \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "MODEL_ID", "max_tokens": 1,
       "messages": [{"role": "user", "content": "Reply with one word."}]}' \
  | jq .usage.prompt_tokens

Run it once a day and keep the numbers. A count that moves means something changed on the route.

Method and limits

One fixed prompt, one sample per route per day, read from the usage field of the response. The counts above are from the check on 2026-10-12.

The limits: a count is what the route reports, and a route can report whatever it likes. A clean count does not prove the route runs the model it names; a smaller model from the same family, or quantized weights, would not show up this way. One sample a day misses anything that changes between samples. It is evidence, not proof.

Price index and model launches, once a month. Unsubscribe in one click.