Source: https://docs.sogni.ai/api-reference/chat-completions/

# Chat Completions

OpenAI-compatible chat with optional server-side Sogni creative tools. Any client that speaks the OpenAI chat shape works as-is. Supports streaming over SSE, vision input as inline data URIs, custom function tools, and the Sogni tool families.

### POST /v1/chat/completions

Returns a single JSON response, or a stream of OpenAI-style SSE events when `stream: true`.

### [#](https://docs.sogni.ai/api-reference/chat-completions/#body)Body

| Name | Type | In | Description |
| --- | --- | --- | --- |
| messagesrequired | array | body | Non-empty OpenAI-style message array. The `developer` role is normalized to `system`. User messages may carry mixed `text` and `image_url` parts for vision. |
| model | string | body | LLM model id from [`GET /v1/models`](https://docs.sogni.ai/api-reference/llm-models/). Defaults to `qwen3.6-35b-a3b-gguf-iq4xs`. An unknown id returns `404` with `code: "model_not_found"`. Media models such as `gpt-image-2` are not valid here; name them in the prompt or in tool arguments. |
| stream | boolean | body | When `true`, returns OpenAI-style SSE chunks. |
| max\_tokens | integer | body | Maximum output tokens. `max_completion_tokens` is accepted as an OpenAI-SDK alias. |
| temperature | number | body | Sampling temperature. Forwarded to the LLM worker. |
| top\_p | number | body | Nucleus sampling. Forwarded to the LLM worker. |
| tools | array | body | Standard OpenAI function-tool array. Merged with the auto-injected Sogni tool family unless `sogni_tools` is `"none"`. |
| tool\_choice | string | object | body | OpenAI tool choice. Defaults to `"auto"` when Sogni tools are injected. |
| sogni\_tools | string | boolean | body | Sogni tool family. `"creative-tools"` or `true` (default) covers media generation, editing, analysis, and composition. `"creative-agent"` adds workflow planners and asset-manifest tools. `false` or `"none"` is text-only. Unrecognized values are treated as `"creative-tools"`. |
| sogni\_tool\_execution | boolean | body | When `true` (default), the API executes Sogni tool calls server-side and returns the final assistant message with media URLs. Set `false` to receive raw `tool_calls` and run the loop yourself. Media tools run server-side only with API-key auth; with a session token, only the synchronous composition tools run (non-streaming) and other tool calls are returned raw. |
| task\_profile | string | body | Optional task profile: `general`, `coding`, or `reasoning`. Defaults to `coding` when any message uses the `developer` role. |
| token\_type | string | body | `spark`, `sogni`, or `auto` (default). The `X-Token-Type` header is accepted; the body wins. Unrecognized values fall back to `auto`. |
| billing\_mode | string | body | `auto` (default), `subscription`, or `tokens`. `subscription` bills eligible work against an active Unlimited plan; a request the plan can't cover fails with `code: "subscription_limit"`. Other values return `400`. |
| safe\_content\_filter | boolean | body | Sensitive Content Filter for the media tools this request runs. Defaults to `true`. `false` requires an eligible account and is checked again when each job renders; some models keep their own content policy. See [Sensitive Content Filter](https://docs.sogni.ai/sogni-intelligence/chat-completions/#sensitive-content-filter). |
| media\_references | array | body | Optional uploaded or request media metadata available to hosted creative tools. |
| chat\_template\_kwargs | object | body | Forwarded to the worker. An explicit `enable_thinking` boolean wins; otherwise thinking is on, and `reasoning_effort: "minimal"` turns it off. `<think>` blocks are removed from returned content. |
| reasoning\_effort | string | body | Optional reasoning hint: `minimal`, `low`, `medium`, or `high`. Also accepts `reasoning.effort`. |
| response\_format | object | body | OpenAI structured-output or JSON-mode hint. Forwarded. |
| app\_source | string | body | Optional caller label. Values longer than 128 characters are truncated. The `X-App-Source` header is accepted; the body wins. |

**Vision limits.** Up to 20 images per request, on `user` messages only; each image at most 10 MB and 1024 px on its longest side; PNG or JPEG only, as an inline base64 `data:` URI whose declared type matches the image data. Remote image URLs return `400`.

### [#](https://docs.sogni.ai/api-reference/chat-completions/#tool-families)Tool families

| Value | What's injected |
| --- | --- |
| "creative-tools" | Default. Image, video, speech, and music generation and editing; video upscaling, background removal, object selection, and image-to-3D (see [Media Utilities, 3D and Speech](https://docs.sogni.ai/api-reference/media-utilities/)); media analysis; plus the synchronous composition tools `enhance_prompt`, `compose_script`, `compose_lyrics`, and `compose_instrumental`. |
| "creative-agent" | Everything in `creative-tools` plus workflow control, asset-manifest tools, and the workflow planners `compose_workflow` and `compose_workflow_template`. |
| false / "none" | No Sogni tools injected. Text-only, or your own custom `tools`. |

### [#](https://docs.sogni.ai/api-reference/chat-completions/#request)Request

```bash
curl https://api.sogni.ai/v1/chat/completions \
  -H "Authorization: Bearer $SOGNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"role": "user", "content": "Generate a cinematic image of a neon alley in Tokyo during rain."}
    ],
    "sogni_tools": "creative-tools"
  }'
```

```javascript
import { SogniClient } from '@sogni-ai/sogni-client';

const sogni = await SogniClient.createInstance({
  appId: 'your-app',
  apiKey: process.env.SOGNI_API_KEY,
});

const result = await sogni.chat.hosted.create({
  messages: [
    { role: 'user', content: 'Generate a cinematic image of a neon alley in Tokyo during rain.' },
  ],
  sogni_tools: 'creative-tools',
});

console.log(result.choices[0].message);
```

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.sogni.ai/v1",
    api_key=os.environ["SOGNI_API_KEY"],
)

response = client.chat.completions.create(
    model="qwen3.6-35b-a3b-gguf-iq4xs",
    messages=[
        {"role": "user", "content": "Generate a cinematic image of a neon alley in Tokyo during rain."},
    ],
    extra_body={"sogni_tools": "creative-tools"},
)

print(response.choices[0].message)
```

### [#](https://docs.sogni.ai/api-reference/chat-completions/#response)Response

```json
{
  "id": "chatcmpl-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "object": "chat.completion",
  "created": 1731950400,
  "model": "qwen3.6-35b-a3b-gguf-iq4xs",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "Here's your image:\n\n![Generated image](https://…/image.png)"
      }
    }
  ],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 18,
    "total_tokens": 60,
    "prompt_tokens_details": { "cached_tokens": 0 }
  }
}
```

**Media URLs.** When the API executes Sogni tools server-side, generated media URLs are injected into the assistant message as Markdown: `![alt](url)` for images, `[▶ Generated video](url)` for video, `[▶ Generated music](url)` for audio (including speech), and `[⬇ Generated 3D model](url)` for 3D models. Set `sogni_tool_execution: false` to receive raw `tool_calls` and run the loop yourself.

**Streaming.** Set `stream: true` and consume OpenAI-compatible `text/event-stream` chunks until `data: [DONE]`. With API-key auth and server-side tool execution (the default), assistant text can arrive in larger chunks rather than token by token. When a Sogni tool runs, the stream adds a progress delta, a media Markdown chunk, and chunks carrying a top-level `creative_workflows` reference. Lines starting with `:` are keepalive comments. An error after the stream opens arrives as a `data: {"error": {…}}` chunk before `[DONE]`. For token-by-token output with your own tool loop, set `sogni_tool_execution: false`.

**Differences from a plain OpenAI model.** Unless you set `sogni_tools: false` or send your own non-empty `system` message, Sogni adds its creative-assistant system prompt. Server-side tool execution runs up to 5 model rounds per request. When tools run, the response includes a `creative_workflows` reference to the persisted media jobs. Send Sogni fields in snake\_case; camelCase forms such as `tokenType` or `mediaReferences` return `400`.
