# Create chat completion

> Creates a model response for the given conversation. Set `stream: true` to receive the response as a stream of server-sent events; the final chunk carries the `usage` object when `stream_options.include_usage` is `true`.

Source: https://docs.serenityedge.ai/docs/api/edge/create-chat-completion/

`POST https://api.serenityedge.ai/v1/chat/completions`

Creates a model response for the given conversation. Set `stream: true` to receive the response as a stream of server-sent events; the final chunk carries the `usage` object when `stream_options.include_usage` is `true`.

## Request body (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | yes | Id of the model to use. See the list of models for the available ids. |
| `messages` | array of one of SystemMessage (object), UserMessage (object), AssistantMessage (object), ToolMessage (object) | yes | The conversation so far, oldest first. At least 1 item. |
| `messages[] (SystemMessage).role` | string | yes | Always `system`. |
| `messages[] (SystemMessage).content` | string | yes | Instructions that steer the behaviour of the model. |
| `messages[] (SystemMessage).name` | string | no | Optional name of the participant. |
| `messages[] (UserMessage).role` | string | yes | Always `user`. |
| `messages[] (UserMessage).content` | one of string, array of one of TextContentPart (object), ImageContentPart (object) | yes | The message, as a plain string or as an array of text and image parts (up to the model's limit of 1 to 8 images per request, `references.max` in `GET /v1/models`; base64 data URLs only; image URLs are refused with 400). |
| `messages[] (UserMessage).name` | string | no | Optional name of the participant. |
| `messages[] (AssistantMessage).role` | string | yes | Always `assistant`. |
| `messages[] (AssistantMessage).content` | string or null | no | The text of the message. `null` when the message only carries tool calls. |
| `messages[] (AssistantMessage).tool_calls` | array of ToolCall (object) | no | Tool calls the model made in a previous turn. |
| `messages[] (AssistantMessage).tool_calls[].id` | string | yes | Identifier to echo back in the `tool_call_id` of the tool message. |
| `messages[] (AssistantMessage).tool_calls[].type` | string | yes | Always `function`. |
| `messages[] (AssistantMessage).tool_calls[].function` | object | yes |  |
| `messages[] (AssistantMessage).tool_calls[].function.name` | string | yes |  |
| `messages[] (AssistantMessage).tool_calls[].function.arguments` | string | yes | JSON-encoded arguments. Always validate before use. |
| `messages[] (AssistantMessage).name` | string | no | Optional name of the participant. |
| `messages[] (ToolMessage).role` | string | yes | Always `tool`. |
| `messages[] (ToolMessage).content` | string | yes | The result returned by your function, as a string (usually JSON). |
| `messages[] (ToolMessage).tool_call_id` | string | yes | The `id` of the tool call this message answers. |
| `stream` | boolean | no | If `true`, partial deltas are sent as server-sent events. The stream ends with `data: [DONE]`. Default `false`. |
| `stream_options` | StreamOptions (object) | no | Options that only apply when `stream` is `true`. |
| `stream_options.include_usage` | boolean | no | When `true`, one extra chunk with an empty `choices` array and the `usage` object is sent before `data: [DONE]`. Default `false`. |
| `max_tokens` | integer | no | Upper bound on the number of tokens to generate. The maximum output for every model is 32,768 tokens. At least 1. At most 32768. |
| `temperature` | number | no | Sampling temperature. Lower values make the output more deterministic. Default `1`. At least 0. At most 2. |
| `top_p` | number | no | Nucleus sampling: only tokens within the top `top_p` probability mass are considered. Default `1`. At least 0. At most 1. |
| `n` | integer | no | Number of completions to generate for each request. Default `1`. At least 1. |
| `stop` | one of string, array of string | no | Up to four sequences at which generation stops. |
| `presence_penalty` | number | no | Penalises tokens that already appear in the text so far. Default `0`. At least -2. At most 2. |
| `frequency_penalty` | number | no | Penalises tokens in proportion to how often they already appear. Default `0`. At least -2. At most 2. |
| `seed` | integer | no | Best-effort deterministic sampling. Repeated requests with the same seed and parameters aim to return the same result. |
| `tools` | array of Tool (object) | no | Functions the model may call. See the tool calling guide. |
| `tools[].type` | string | yes | Always `function`. |
| `tools[].function` | FunctionDefinition (object) | yes |  |
| `tools[].function.name` | string | yes | Function name. Letters, digits, underscores and dashes; at most 64 characters. |
| `tools[].function.description` | string | no | What the function does. The model uses it to decide when to call the function. |
| `tools[].function.parameters` | object | no | JSON Schema object describing the arguments. |
| `tools[].function.strict` | boolean | no | When `true`, the arguments are guaranteed to match `parameters` exactly. Default `false`. |
| `tool_choice` | one of string, object | no | Controls whether and which tool the model calls. `none` disables tools, `auto` lets the model decide, `required` forces at least one call, and an object forces a specific function. |
| `tool_choice.type` | string | yes | Always `function`. |
| `tool_choice.function` | object | yes |  |
| `tool_choice.function.name` | string | yes |  |
| `parallel_tool_calls` | boolean | no | Whether the model may return several tool calls in one response. Default `true`. |
| `response_format` | one of object, object, object | no | Format of the output. `text` (default), `json_object` for any valid JSON, or `json_schema` to constrain the output to a schema. |
| `response_format (Text).type` | string | yes | Always `text`. |
| `response_format (JSON object).type` | string | yes | Always `json_object`. |
| `response_format (JSON schema).type` | string | yes | Always `json_schema`. |
| `response_format (JSON schema).json_schema` | JsonSchemaFormat (object) | yes |  |
| `response_format (JSON schema).json_schema.name` | string | yes | Name of the schema. |
| `response_format (JSON schema).json_schema.description` | string | no |  |
| `response_format (JSON schema).json_schema.schema` | object | yes | A JSON Schema object the output must satisfy. |
| `response_format (JSON schema).json_schema.strict` | boolean | no | When `true`, the output is guaranteed to match the schema exactly. Default `false`. |
| `reasoning` | ReasoningOptions (object) | no | Reasoning settings for models that support it. Reasoning tokens are billed as output tokens. |
| `reasoning.effort` | string | no | How much reasoning the model should do before answering. One of `low`, `medium`, `high`. |
| `reasoning.exclude` | boolean | no | When `true`, the model reasons but the reasoning text is not returned. Default `false`. |
| `user` | string | no | An opaque identifier for your end user, useful for abuse detection on your side. Not stored beyond the request metadata retention period. |

Example:

```json
{
  "model": "orion-pro",
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant."
    },
    {
      "role": "user",
      "content": "Summarise the benefits of EU data residency in two sentences."
    }
  ]
}
```

## Responses

### 200: A chat completion. When `stream` is `true` the body is a `text/event-stream` of `ChatCompletionChunk` objects terminated by `data: [DONE]`.

Body (`application/json`): `ChatCompletion`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Unique identifier of the completion. |
| `object` | string | yes | Always `chat.completion`. |
| `created` | integer | yes | Unix timestamp (seconds) of creation. |
| `model` | string | yes | The model that generated the response. |
| `choices` | array of ChatCompletionChoice (object) | yes |  |
| `choices[].index` | integer | yes |  |
| `choices[].message` | AssistantResponseMessage (object) | yes |  |
| `choices[].message.role` | string | yes | Always `assistant`. |
| `choices[].message.content` | string or null | no | The generated text, or `null` when the response only carries tool calls. |
| `choices[].message.tool_calls` | array of ToolCall (object) | no |  |
| `choices[].message.tool_calls[].id` | string | yes | Identifier to echo back in the `tool_call_id` of the tool message. |
| `choices[].message.tool_calls[].type` | string | yes | Always `function`. |
| `choices[].message.tool_calls[].function` | object | yes |  |
| `choices[].message.tool_calls[].function.name` | string | yes |  |
| `choices[].message.tool_calls[].function.arguments` | string | yes | JSON-encoded arguments. Always validate before use. |
| `choices[].message.reasoning` | string or null | no | Reasoning text, when the request enabled reasoning and did not exclude it. |
| `choices[].finish_reason` | FinishReason (string or null) | yes | `stop`: natural end or stop sequence. `length`: `max_tokens` or the context window was reached. `tool_calls`: the model wants to call a tool. `content_filter`: output was withheld. `null` in streaming chunks that are not the last one. One of `stop`, `length`, `tool_calls`, `content_filter`, `null`. |
| `usage` | Usage (object) | no |  |
| `usage.prompt_tokens` | integer | yes | Tokens in the prompt, including cached tokens. |
| `usage.completion_tokens` | integer | yes | Tokens generated, including reasoning tokens. |
| `usage.total_tokens` | integer | yes |  |
| `usage.prompt_tokens_details` | object | no |  |
| `usage.prompt_tokens_details.cached_tokens` | integer | no | Prompt tokens served from the prompt cache, billed at the cached input price. |
| `usage.completion_tokens_details` | object | no |  |
| `usage.completion_tokens_details.reasoning_tokens` | integer | no | Tokens spent on reasoning. |
| `system_fingerprint` | string | no | Identifier of the backend configuration that served the request. |

Body (`text/event-stream`): `ChatCompletionChunk`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Same for every chunk of one completion. |
| `object` | string | yes | Always `chat.completion.chunk`. |
| `created` | integer | yes |  |
| `model` | string | yes |  |
| `choices` | array of ChatCompletionChunkChoice (object) | yes | Empty in the final usage chunk when `stream_options.include_usage` is `true`. |
| `choices[].index` | integer | yes |  |
| `choices[].delta` | ChatCompletionDelta (object) | yes | The incremental change carried by this chunk. Concatenate `content` across chunks to rebuild the message. |
| `choices[].delta.role` | string | no | Present in the first chunk only. Always `assistant`. |
| `choices[].delta.content` | string or null | no |  |
| `choices[].delta.reasoning` | string or null | no |  |
| `choices[].delta.tool_calls` | array of ToolCallDelta (object) | no | Tool call fragments. Match fragments by `index` and concatenate `function.arguments`. |
| `choices[].delta.tool_calls[].index` | integer | yes |  |
| `choices[].delta.tool_calls[].id` | string | no | Present in the first fragment of each tool call. |
| `choices[].delta.tool_calls[].type` | string | no | Always `function`. |
| `choices[].delta.tool_calls[].function` | object | no |  |
| `choices[].delta.tool_calls[].function.name` | string | no | Present in the first fragment of each tool call. |
| `choices[].delta.tool_calls[].function.arguments` | string | no | A fragment of the JSON-encoded arguments. |
| `choices[].finish_reason` | FinishReason (string or null) | no | `stop`: natural end or stop sequence. `length`: `max_tokens` or the context window was reached. `tool_calls`: the model wants to call a tool. `content_filter`: output was withheld. `null` in streaming chunks that are not the last one. One of `stop`, `length`, `tool_calls`, `content_filter`, `null`. |
| `usage` | one of Usage (object), null | no | Present only in the final chunk when `stream_options.include_usage` is `true`; `null` or absent otherwise. |
| `usage (Usage).prompt_tokens` | integer | yes | Tokens in the prompt, including cached tokens. |
| `usage (Usage).completion_tokens` | integer | yes | Tokens generated, including reasoning tokens. |
| `usage (Usage).total_tokens` | integer | yes |  |
| `usage (Usage).prompt_tokens_details` | object | no |  |
| `usage (Usage).prompt_tokens_details.cached_tokens` | integer | no | Prompt tokens served from the prompt cache, billed at the cached input price. |
| `usage (Usage).completion_tokens_details` | object | no |  |
| `usage (Usage).completion_tokens_details.reasoning_tokens` | integer | no | Tokens spent on reasoning. |

### 400: The request is malformed or a parameter is invalid. More images than the model reads, counted over the whole conversation (from 1 to 8 depending on the model: `references.max` in `GET /v1/models`), are refused with `code: too_many_images` and `param: messages`.

Body (`application/json`): `ErrorResponse`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | Error (object) | yes | OpenAI-style error object. |
| `error.message` | string | yes | Human-readable description of the problem. |
| `error.type` | string | yes | Error category. One of `invalid_request_error`, `authentication_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`. |
| `error.code` | string or null | no | Machine-readable error code, when available. |
| `error.param` | string or null | no | The request parameter the error refers to, when applicable. |

### 401: Missing or invalid API key.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 404: The requested model does not exist or is not available to this key.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 413: The request body is larger than the gateway accepts (4 MB).

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 429: Rate limit exceeded, or the service is temporarily at capacity for this model. Wait for the number of seconds in the `Retry-After` header before retrying.

Header `Retry-After`: Seconds to wait before retrying.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 500: Unexpected server error: the model service returned an unexpected response (`upstream_error`), the request got no answer within 600 seconds (`timeout`), or an error in the gateway. Retry with backoff.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 503: The model service is temporarily unavailable. Retry later and check the status page at https://status.serenityedge.ai.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.
