# Chat requests Source: https://docs.getworg.com/chat-completions 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 ```bash 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/. 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 `model` or an empty `messages`. - A message role outside system, developer, user, assistant and tool. - A `reasoning_effort` Worg 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 `temperature` outside 0 to 2, or a request no lane of that model handles in full (see [Model name alone](https://docs.getworg.com/models#model-without-a-lane)). 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": true` for 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`. Next: [Responses and usage](https://docs.getworg.com/responses) · [Streaming](https://docs.getworg.com/streaming) · [Tool calling](https://docs.getworg.com/tool-calling)