Chat requests
POST /v1/chat/completions takes the OpenAI request format and answers in it. This page lists every field Worg reads or has tested, and where the lanes differ.


A request
cURL
curl https://api.getworg.com/v1/chat/completions \
-H "Authorization: Bearer $WORG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4.1-flash:cached",
"messages": [{"role": "user", "content": "Say hello in Indonesian."}],
"max_tokens": 512
}'Python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.getworg.com/v1",
api_key=os.environ["WORG_API_KEY"],
)
response = client.chat.completions.create(
model="deepseek-v4.1-flash:cached",
messages=[{"role": "user", "content": "Say hello in Indonesian."}],
max_tokens=512,
)
print(response.model)
print(response.choices[0].message.content)TypeScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.getworg.com/v1",
apiKey: process.env.WORG_API_KEY,
});
const response = await client.chat.completions.create({
model: "deepseek-v4.1-flash:cached",
messages: [{ role: "user", content: "Say hello in Indonesian." }],
max_tokens: 512,
});
console.log(response.model);
console.log(response.choices[0].message.content);Send the key as Authorization: Bearer. Clients that use an x-api-key header work too.
Request fields
model- Required. A lane ID or a model name alone from GET /v1/models, or combo/<name>. The name alone tries each lane of that model. A renamed ID still works until the date on Models and compatibility.
messages- Required. A non-empty array. Roles: system, developer, user, assistant, tool (function is read as the older name of tool). content is text, or an array of text and image_url parts.
max_tokens- Upper limit on output tokens. A value above the model's output limit is lowered to that limit. Set it: it also caps the amount Worg sets aside for the request.
max_completion_tokens- The same limit under its newer name. When you send both, the lower value applies.
stream- true sends the answer as server-sent events. See Streaming.
stream_options- {"include_usage": true} adds a last chunk with token usage.
reasoning_effort- none, low, medium, high or max. See Reasoning.
reasoning- The object form some clients send: {"enabled": false} is read as none, {"enabled": true} as high, {"effort": "low"} as low. reasoning_effort wins when both are set.
tools- Functions the model may call. See Tool calling.
tool_choice- auto, required, or {"type": "function", "function": {"name": "..."}} to force one function.
parallel_tool_calls- false asks for one call per reply. Only deepseek-v4.1-flash:standard follows it; the other lanes may still return several calls.
response_format- {"type": "json_object"} or {"type": "json_schema", ...}. See Structured output.
temperature- Use 0 to 2. deepseek-v4.1-flash:cached refuses a value outside that range with 400. The other lanes accept it, and the output turns into noise above 2.
stop- An array of strings; the output ends where one appears. On deepseek-v4.1-flash:standard the stop text stays at the end of the output; remove it in your code.
n- Number of choices. deepseek-v4.1-flash:standard accepts only 1 and answers 400 to more. Each choice is billed as output.
logprobs- With top_logprobs, the log probability of each output token. deepseek-v4.1-flash:standard accepts the fields but returns logprobs: null.
top_p, seed, presence_penalty, frequency_penalty, logit_bias, user- Passed to the model as sent. Every lane accepted them in testing.
Fields not listed are passed to the model as you send them, and the model may ignore them. The request body can be up to 16 MB (413 body_too_large above that).
What Worg checks before sending
These are refused with 400 invalid_request before any lane is called, and are not billed:
- A body that is not a JSON object, or has no
modelor an emptymessages. - A message role outside system, developer, user, assistant and tool.
- A
reasoning_effortWorg does not accept. - More than 8 images, or an image URL that is not a public http(s) host or a
data:image/URL. - For a model name alone: a
temperatureoutside 0 to 2, or a request no lane of that model handles in full (see Model name alone).
Anything else the model rejects, such as "temperature": 5 on deepseek-v4.1-flash:cached, comes back with the model's status and message under the code invalid_request. Such a request is not billed either, and a combo does not move on to its next lane.
Long requests
- A request that sends nothing back for 100 seconds is cut by Worg's edge network with HTTP 524. Use
"stream": truefor long outputs: the stream keeps sending. - If a lane does not start answering within 60 seconds, Worg treats it as unavailable: a combo moves to its next lane, otherwise the answer is
502 upstream_unavailable. - A request is ended after 300 seconds in total.
Other endpoints
The API has two endpoints: POST /v1/chat/completions and GET /v1/models. Any other path under /v1, such as embeddings or the Responses API, answers 404 not_found.