Completions
OpenAI's legacy prompt completion, routed exactly like chat.
POST /v1/completions takes a prompt rather than a message list and answers with an object of type text_completion. It exists so that code written against OpenAI's original completion API keeps working when the base URL changes, which is the whole point of the compatibility surface.
POST/v1/completionsAvailable
OpenAI's legacy prompt completion, translated onto the same routing as chat.
A request
curl https://api.routehook.ai/v1/completions \
-H "Authorization: Bearer $ROUTEHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"prompt": "Write one sentence about harbour fog.",
"max_tokens": 64
}'
Request parameters
| PARAMETER | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
| model | string | required | Model slug from GET /v1/models. The same catalogue chat uses. |
| prompt | string | string[] | required | The prompt, or a batch of them. A batch answers with one choice per prompt, in order. |
| max_tokens | integer | optional | Ceiling on generated tokens. Also caps what is reserved before the call runs. |
| stream | boolean | optional | Emit server-sent events instead of one body. Default false. |
| temperature | number | optional | 0 to 2. Forwarded unchanged. |
| top_p | number | optional | 0 to 1. Forwarded unchanged. |
| stop | string | string[] | optional | Up to eight sequences that end generation when produced. |
| n | integer | optional | 1 to 8 completions. Multiplies the reservation and the bill. |
| seed | integer | optional | Best-effort determinism, where the model supports it. |
| user | string | optional | An opaque end-user identifier, forwarded upstream. |
| models | string[] | optional | Fallback model slugs, tried in order after model. |
| suffix | string | optional | Up to 4,000 characters, forwarded to the upstream. Only insertion-capable models read it. |
| presence_penalty | number | optional | -2 to 2. Forwarded unchanged. |
| frequency_penalty | number | optional | -2 to 2. Forwarded unchanged. |
| stream_options | object | optional | Only include_usage is read. It adds a final frame carrying usage and cost. |
| logprobs | integer | optional | 0 to 5: this route's meaning, not chat's boolean. Translated on the way out; see below. |
| echo | boolean | optional | Accepted and discarded. Chat has no equivalent, so it changes nothing. |
| best_of | integer | optional | 1 to 8. Accepted and discarded, for the same reason as echo. |
| transforms | string[] | optional | Accepted and discarded here, unlike chat, which refuses it outright. |
The translation
This route is planned, billed and failed over exactly like chat: the same model catalogue, the same routing, the same reservation and settlement, and the same models field. The only difference is what happens at the edges of the call when the endpoint chosen for the model speaks chat and nothing else, which is nearly all of them.
| ON THE WAY OUT | ON THE WAY BACK |
|---|---|
| prompt becomes a single message: { role: "user", content: <prompt> } | choices[].message.content is unwrapped back into choices[].text |
| max_tokens, temperature, top_p, stop, seed and n are passed through under the same names | finish_reason, index and usage are passed back under the same names |
| logprobs: 0-5 becomes chat's logprobs: true plus top_logprobs: <n> | The log probabilities come back under chat's names, unwrapped into this route's choices |
| echo, best_of and transforms are consumed here and never sent | Nothing in the answer reflects them |
| A prompt array becomes one request per prompt | object is text_completion, and the choices come back in the order the prompts went out |
The response
{
"id": "cmpl_5f81c0",
"object": "text_completion",
"created": 1786312455,
"model": "openai/gpt-4o-mini",
"choices": [
{
"index": 0,
"text": "Fog rolled off the water and swallowed the cranes one by one.",
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 8,
"completion_tokens": 14,
"total_tokens": 22,
"cost": "0.0000038"
}
}
Streaming
stream: true works here and uses OpenAI's legacy chunk shape: the object stays text_completion and each frame carries choices[].text rather than a delta. The framing, the [DONE] sentinel, the error frame and the stream_options.include_usage opt-in are all as described on the streaming page.
Cost
Identical to chat, on the same rates: prompt tokens on the input axis, generated tokens on the output axis, and usage.cost in the response with what was settled. A prompt array is charged as the requests it becomes. Batching prompts saves round trips, not money.