Skip to content
docs/completionsCore API

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.

AUTHENTICATION
Bearer token, Authorization header
REQUIRED SCOPE
api-key

A request

cURL
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

PARAMETERTYPEREQUIREDDESCRIPTION
modelstringrequiredModel slug from GET /v1/models. The same catalogue chat uses.
promptstring | string[]requiredThe prompt, or a batch of them. A batch answers with one choice per prompt, in order.
max_tokensintegeroptionalCeiling on generated tokens. Also caps what is reserved before the call runs.
streambooleanoptionalEmit server-sent events instead of one body. Default false.
temperaturenumberoptional0 to 2. Forwarded unchanged.
top_pnumberoptional0 to 1. Forwarded unchanged.
stopstring | string[]optionalUp to eight sequences that end generation when produced.
nintegeroptional1 to 8 completions. Multiplies the reservation and the bill.
seedintegeroptionalBest-effort determinism, where the model supports it.
userstringoptionalAn opaque end-user identifier, forwarded upstream.
modelsstring[]optionalFallback model slugs, tried in order after model.
suffixstringoptionalUp to 4,000 characters, forwarded to the upstream. Only insertion-capable models read it.
presence_penaltynumberoptional-2 to 2. Forwarded unchanged.
frequency_penaltynumberoptional-2 to 2. Forwarded unchanged.
stream_optionsobjectoptionalOnly include_usage is read. It adds a final frame carrying usage and cost.
logprobsintegeroptional0 to 5: this route's meaning, not chat's boolean. Translated on the way out; see below.
echobooleanoptionalAccepted and discarded. Chat has no equivalent, so it changes nothing.
best_ofintegeroptional1 to 8. Accepted and discarded, for the same reason as echo.
transformsstring[]optionalAccepted 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 OUTON 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 namesfinish_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 sentNothing in the answer reflects them
A prompt array becomes one request per promptobject is text_completion, and the choices come back in the order the prompts went out

The response

JSON200 OK
{
  "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.