# Legacy Completions

> POST /v1/completions পুরোনো ধাঁচের endpoint: prompt দিন, text পান। request-এর field, streaming, billing, কোন model এটা নেয়, আর একই call কীভাবে chat completions-এ নিয়ে যাবেন।

`POST https://tokens.bd/v1/completions` হলো OpenAI-র আদি text completions endpoint: আপনি একটা `prompt` string পাঠান, আর model সেই text-টার পরের অংশ লিখে দেয়। যেসব পুরোনো tool আর script এখনো এটা call করে, তাদের জন্য Tokens এটা পাস করে দেয়। নতুন কিছু বানালে [chat completions](/docs/chat-completions) ব্যবহার করুন। সব chat model সেটা সমর্থন করে, আর বেশির ভাগ coding agent সেটাই আশা করে।

:::warning[সব model এই endpoint চালায় না]
Tokens request-টা model-এর provider-এর কাছে পাঠিয়ে দেয়, আর model সাধারণ text completion করতে পারে কি না সেটা provider ঠিক করে। অনেক chat model পারে না, আর যেগুলো পারে তাদের কোনো তালিকাও নেই। এর ওপর কিছু দাঁড় করানোর আগে নিচের মতো ছোট একটা request দিয়ে আপনার model পরীক্ষা করে নিন।
:::

## Completions request পাঠানো

:::code-tabs

```bash title="cURL"
curl https://tokens.bd/v1/completions \
  -H "Authorization: Bearer $TOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "prompt": "A one-line definition of HTTP 429:",
    "max_tokens": 40,
    "temperature": 0
  }'
```

```python title="Python"
import os
from openai import OpenAI

client = OpenAI(base_url="https://tokens.bd/v1", api_key=os.environ["TOKENS_API_KEY"])

resp = client.completions.create(
    model="deepseek/deepseek-v4.1-flash",
    prompt="A one-line definition of HTTP 429:",
    max_tokens=40,
    temperature=0,
)
print(resp.choices[0].text)
print(resp.usage)
```

```typescript title="Node.js"
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://tokens.bd/v1", apiKey: process.env.TOKENS_API_KEY });

const resp = await client.completions.create({
  model: "deepseek/deepseek-v4.1-flash",
  prompt: "A one-line definition of HTTP 429:",
  max_tokens: 40,
  temperature: 0,
});
console.log(resp.choices[0].text, resp.usage);
```

:::

error এলে [কোন model চলে](#which-models-work) section-টা পড়ুন। `Content-Type: application/json` header-টা জরুরি: এটা না থাকলে gateway body পড়তে পারে না, আর `model` field নেই বলে 400 `invalid_request` দেয়।

## Request-এর field

body চলে OpenAI-র completions format মেনে। OpenAI-র API reference-এর সাথে 2026 সালের অক্টোবরে মিলিয়ে দেখা হয়েছে।

| Field                                                                 | Type            | নোট                                                                                                         |
| --------------------------------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------- |
| `model`                                                               | string          | বাধ্যতামূলক। catalog-এর একটা id। আপনার key-র list দেখতে `GET /v1/models` চালান।                            |
| `prompt`                                                              | string or array | OpenAI-র format-এ বাধ্যতামূলক। একটা string, বা string-এর array। token id-র array-ও এই format-এ চলে।        |
| `max_tokens`                                                          | integer         | তৈরি হওয়া token-এর ওপরের সীমা। এটা দিয়ে দিন, কারণ জানতে নিচে reservation-এর কথাটা দেখুন।                   |
| `temperature`, `top_p`                                                | number          | Sampling। OpenAI যেমন বলে, একটাই বদলান, দুটো একসাথে নয়।                                                    |
| `n`                                                                   | integer         | প্রতি prompt-এ কয়টা completion চান। gateway 1 থেকে 4 পর্যন্ত নেয়, নইলে 400 `invalid_request` দেয়।        |
| `stop`                                                                | string or array | OpenAI-র format-এ সর্বোচ্চ 4টা stop sequence।                                                               |
| `stream`                                                              | boolean         | `true` দিলে Server-Sent Events আসে।                                                                         |
| `stream_options.include_usage`                                        | boolean         | `stream: true`-র সাথে দিলে শেষে `usage`-সহ একটা বাড়তি chunk আসে।                                           |
| `suffix`, `echo`, `logprobs`, `best_of`                               | various         | OpenAI-র format-এ এগুলো আছে। model এগুলো মানবে কি না, সেটা তার provider-এর ওপর।                              |
| `seed`, `presence_penalty`, `frequency_penalty`, `logit_bias`, `user` | various         | যেমন পাঠানো হয় তেমনই provider-এর কাছে যায়।                                                                |

:::note[Parameter নির্ভর করে upstream model-এর ওপর]
`model` আর `n` ছাড়া বাকি field gateway যাচাইও করে না, বদলায়ও না। এগুলো সরাসরি model-এর provider-এর কাছে যায়, আর provider কোনো field উপেক্ষা করতে পারে বা পুরো request ফিরিয়ে দিতে পারে। যেমন OpenAI-র নিজের docs-এ `suffix` শুধু একটা model-এর সাথে চলে। [catalog](/models)-এ model-এর পেজ দেখুন, আর নিজে চালিয়ে পরীক্ষা করুন।
:::

request body 10 MB পর্যন্ত হতে পারে। এর চেয়ে বড় হলে 413 `request_entity_too_large` আসে।

## Response-এর উদাহরণ

id আর সংখ্যাগুলো বোঝানোর জন্য দেওয়া।

```json
{
  "id": "cmpl-a1b2c3",
  "object": "text_completion",
  "created": 1790000000,
  "model": "deepseek/deepseek-v4.1-flash",
  "choices": [
    {
      "index": 0,
      "text": " The server is rate limiting you; wait and retry.",
      "finish_reason": "stop",
      "logprobs": null
    }
  ],
  "usage": { "prompt_tokens": 12, "completion_tokens": 11, "total_tokens": 23 }
}
```

তৈরি হওয়া text থাকে `choices[].text`-এ, chat completions-এর মতো `choices[].message.content`-এ নয়। model নিজে থেমে গেলে বা stop sequence-এ পৌঁছালে `finish_reason` হয় `stop`, আর `max_tokens`-এ ঠেকে গেলে `length`। body আসে provider থেকে, তাই `system_fingerprint`-এর মতো বাড়তি field model ভেদে আলাদা হতে পারে।

## Streaming

`"stream": true` দিলে response আসে Server-Sent Events হিসেবে। প্রতিটা event-এ `choices[].text`-এর একটা অংশ থাকে, আর stream শেষ হয় `data: [DONE]` দিয়ে:

```text
data: {"id":"cmpl-a1b2c3","object":"text_completion","choices":[{"index":0,"text":" The server","finish_reason":null}]}

data: {"id":"cmpl-a1b2c3","object":"text_completion","choices":[{"index":0,"text":" is rate limiting you.","finish_reason":"stop"}]}

data: [DONE]
```

billing-এর জন্য gateway provider-কে বলে, stream করা completion-এর শেষে যেন একটা usage chunk পাঠায়। এই chunk-এর `choices` array ফাঁকা থাকে আর থাকে একটা `usage` object, তাই আপনার stream parser যেন এটা সামলাতে পারে। disconnect, timeout আর proxy buffering [streaming](/docs/streaming) পেজে যেভাবে লেখা আছে সেভাবেই চলে।

## Billing আর সীমা

- **হিসাব।** provider-এর জানানো `prompt_tokens` আর `completion_tokens` ধরে, model-এর input ও output price-এ বিল হয়। provider usage না পাঠালে gateway request আর response-এর size দেখে আন্দাজ করে নেয়।
- **Reservation।** forward করার আগে gateway request-এর সবচেয়ে খারাপ ক্ষেত্রের খরচ ধরে রাখে, আর output-এর দিকে হিসাব করে `max_tokens` দিয়ে। এটা না দিলে reservation ধরে নেয় 8,192 output token, যদিও provider-এর নিজের default অনেক কম হতে পারে। তাই কোনো key-র monthly spend cap প্রায় শেষ থাকলে বা ব্যালান্স প্রায় শূন্য হলে, `max_tokens`-ছাড়া request ফিরে যেতে পারে, অথচ ছোট `max_tokens`-সহ request ঠিকই চলে যায়। আপনার চাওয়া `max_tokens` ব্যালান্সে না কুলালে gateway সেটা কমিয়ে ব্যালান্সে যতটা কুলায় ততটা করে দিতে পারে। চার্জ হয় আসল usage-এর, reservation-এর নয়।
- **Rate limit।** অন্য inference request-এর মতো completions request-ও আপনার per-minute limit আর concurrency-তে গোনা হয়। [rate limits](/docs/rate-limits) পেজ দেখুন।
- **Fail করা request-এর বিল হয় না।** provider 400 বা তার ওপরের status দিলে সেটা কোনো চার্জ ছাড়াই ফেরত আসে।

## কোন model চলে

gateway call-টা যেমন আছে তেমনই পাঠায়। completions request-কে chat request-এ বদলায় না, আর model সাধারণ completion পারে কি না তাও যাচাই করে না। কী ফিরে আসবে, সেটা model-এর provider-এর ওপর নির্ভর করে:

| Response                               | সম্ভাব্য কারণ                                                                                                |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| 200 with text                          | provider এই model-এর জন্য `/completions` চালায়।                                                             |
| 400 `invalid_request`                  | provider request ফিরিয়ে দিয়েছে, যেমন model শুধু chat-এর জন্য, বা কোনো field অনুমোদিত নয়।                   |
| 404 `model_not_found`                  | এই model-এর জন্য provider-এর কাছে completions route নেই। catalog-এ নেই এমন id দিলেও এটাই আসে।               |
| 400 `endpoint_not_supported_for_model` | model-টা শুধু এমন provider-এর মাধ্যমে চলে যে Anthropic Messages protocol বোঝে। কিছুই পাঠানো হয়নি।            |
| 502 `upstream_unreachable`             | model-এর কয়েকটা provider আছে, আর প্রতিটাই fail করেছে বা request ফিরিয়ে দিয়েছে।                            |

upstream-এর message বদলে একটা সাধারণ message বসানো হয়, তাই কোনো failure Support-কে দেখাতে চাইলে `x-tokens-request-id` header-টা রেখে দিন। পুরো তালিকা [errors](/docs/errors) পেজে।

## Chat completions-এ চলে যাওয়া

completions call fail করলে, বা নতুন code লিখলে, একই request chat completion হিসেবে পাঠাতে শুধু আকারটা বদলাতে হয়:

```python
# Before: /v1/completions
resp = client.completions.create(model=model, prompt="A one-line definition of HTTP 429:", max_tokens=40)
text = resp.choices[0].text

# After: /v1/chat/completions
resp = client.chat.completions.create(
    model=model,
    messages=[{"role": "user", "content": "A one-line definition of HTTP 429:"}],
    max_tokens=40,
)
text = resp.choices[0].message.content
```

completions model একটা text-এর জের টানে, আর chat model প্রশ্ন বা নির্দেশের উত্তর দেয়। তাই যে prompt জের টানার ওপর ভর করে ছিল সেটা নতুন করে লিখুন (যেমন "The three causes are:" হয়ে যাবে "List the three causes.")। যে feature শুধু completions-এ আছে, যেমন `suffix` আর `echo`, chat-এ তার সমতুল্য কিছু নেই।

## আরও পড়ুন

- [Chat completions](/docs/chat-completions): নতুন কাজের জন্য যে endpoint ব্যবহার করবেন।
- [Responses](/docs/responses) আর [Messages](/docs/messages): বাকি দুটো inference endpoint-এর জন্য।
- [Token counting](/docs/token-counting): prompt-এর size আন্দাজ করতে আর `usage` পড়তে।

---
Page: https://tokens.bd/bn/docs/legacy-completions
