> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kymaapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a completion (legacy)

> OpenAI's deprecated text-completion shape, served for compatibility.

<Warning>
  OpenAI deprecated this endpoint. It exists so older SDK pins and scripts keep working — use [`/v1/chat/completions`](/api-reference/chat-completions) for anything new.
</Warning>

## What it is

An adapter over the chat endpoint, not a separate path. `prompt` becomes a single user message, and `choices[].message.content` comes back as `choices[].text`. Models, pricing, streaming, failover and `usage.cost` are identical, because the request goes through exactly the same pipeline.

```python theme={null}
from openai import OpenAI

client = OpenAI(api_key="ky-...", base_url="https://api.kymaapi.com/v1")

r = client.completions.create(
    model="qwen3.7-flash",
    prompt="Write a haiku about routing",
    max_tokens=64,
)
print(r.choices[0].text)
```

## Three things return 400 instead of guessing

| You sent                | Why it is refused                                                                                                                                              |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prompt: ["a", "b"]`    | In the original API that means two **independent** completions. Concatenating them would return one answer where you expect two — send one request per prompt. |
| `suffix`                | Fill-in-the-middle. No chat model does it, so honouring it would return a plausible completion that is wrong for the purpose.                                  |
| `echo` **and** `stream` | `echo` prepends your prompt, which has nowhere to go in a token stream without inventing a frame you did not ask for.                                          |

`best_of` and `logprobs` are accepted and ignored — their absence is visible in the response, so there is nothing to guess about.

## Streaming

Supported, in the legacy chunk shape:

```
data: {"id":"...","object":"text_completion","choices":[{"text":"One","index":0,"logprobs":null,"finish_reason":null}]}
```

A frame that carries only a role or a tool call has no text and no `finish_reason`, so it is dropped rather than emitted as an empty chunk.
