# Text
Source: https://docs.simpleserve.ai/docs/text
Summary: OpenAI-compatible chat completions, completions, and responses, with streaming. Embeddings on their own page.
Availability: available
Last reviewed: 2026-08-25

## Create a chat completion

Use the OpenAI SDK with `base_url` set to `https://api.simpleserve.ai/openai/v1`.

**Python**

```python
from openai import OpenAI

client = OpenAI(base_url="https://api.simpleserve.ai/openai/v1", api_key="ss_live_your_key")

response = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[
        {"role": "system", "content": "Be brief."},
        {"role": "user", "content": "Write one sentence about GPUs."},
    ],
    temperature=0.2,
    max_tokens=64,
)
print(response.choices[0].message.content)
```

**JavaScript**

```ts
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.simpleserve.ai/openai/v1", apiKey: "ss_live_your_key" });

const response = await client.chat.completions.create({
  model: "qwen3.8-27b",
  messages: [
    { role: "system", content: "Be brief." },
    { role: "user", content: "Write one sentence about GPUs." },
  ],
  temperature: 0.2,
  max_tokens: 64,
});
console.log(response.choices[0].message.content);
```

**cURL**

```bash
curl https://api.simpleserve.ai/openai/v1/chat/completions \
  -H "Authorization: Bearer $SIMPLESERVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.8-27b",
    "messages": [
      {"role": "system", "content": "Be brief."},
      {"role": "user", "content": "Write one sentence about GPUs."}
    ],
    "temperature": 0.2,
    "max_tokens": 64
  }'
```

## Stream tokens

Set `stream` to `true`. Chunks arrive as server-sent events. With `stream_options.include_usage`, the final chunk carries `usage` and an empty `choices` list.

**Python**

```python
stream = client.chat.completions.create(
    model="qwen3.8-27b",
    messages=[{"role": "user", "content": "Count to five."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="")
    if chunk.usage:
        print("\ntokens:", chunk.usage.total_tokens)
```

**JavaScript**

```ts
const stream = await client.chat.completions.create({
  model: "qwen3.8-27b",
  messages: [{ role: "user", content: "Count to five." }],
  stream: true,
  stream_options: { include_usage: true },
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  if (chunk.usage) console.log("\ntokens:", chunk.usage.total_tokens);
}
```

## Thinking

`qwen3.8-27b` thinks by default. Reasoning tokens are billed as output tokens. Turn thinking off for latency with `reasoning_effort: "minimal"`, the same field the Realtime API uses.

```python
response = client.chat.completions.create(model="qwen3.8-27b", messages=msgs, reasoning_effort="minimal")
```

## Completions and responses

`POST /openai/v1/completions` and `POST /openai/v1/responses` work the same way. Responses covers text in, text out, and streaming. Stateful features return `400` (see [Compatibility](/docs/resources/compatibility)).

```python
r = client.responses.create(model="qwen3.8-27b", input="Write one sentence about GPUs.")
print(r.output_text)
```

## Models

`GET /openai/v1/models` lists the text and embedding models. With `xi-api-key` auth the same path returns the ElevenLabs models list.

## Supported parameters

Rejected parameters per route are on [Compatibility](/docs/resources/compatibility).

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `model` | `string` | yes |  | A text model id. See Pricing. |
| `messages` | `Message[]` | yes |  | System, user, assistant, and tool messages. |
| `stream` | `boolean` | no | `false` | Server-sent events. |
| `stream_options` | `{ include_usage: boolean }` | no |  | Adds a final usage chunk. |
| `reasoning_effort` | `"minimal" | "low" | "medium" | "high"` | no |  | minimal turns thinking off. |
| `temperature` | `number` | no |  | Sampling temperature. Out-of-range values return 400. |
| `top_p` | `number` | no |  | Nucleus sampling. |
| `seed` | `integer` | no |  | Best-effort deterministic sampling. |
| `max_tokens` | `integer` | no |  | Completion length cap. max_completion_tokens is also accepted. |
| `stop` | `string | string[]` | no |  | Up to four stop sequences. |
| `presence_penalty` | `number` | no |  | Penalize tokens already present. |
| `frequency_penalty` | `number` | no |  | Penalize tokens by frequency. |
| `logit_bias` | `Record<string, number>` | no |  | Per-token bias, by token id. |
| `logprobs` | `boolean` | no |  | Return log probabilities. Pair with top_logprobs. |
| `response_format` | `{ type: "json_object" | "json_schema" }` | no |  | Constrained output. |
| `tools` | `Tool[]` | no |  | Function calling. Pair with tool_choice. |
| `n` | `integer` | no | `1` | Number of choices. |
| `user` | `string` | no |  | Your end-user id, for your own tracking. |

## Capacity errors

#### 503 model_booting

The model is starting. The response carries a `Retry-After` header in seconds. Retry after that.

```json
{ "error": { "message": "Model 'qwen3.8-27b' is starting. Retry in 20 seconds.", "type": "server_error", "param": null, "code": "model_booting" } }
```

#### 503 no_capacity

No capacity for the model right now. Retry with exponential backoff.

#### 502 upstream_error

The model did not answer. Nothing is billed. Retry with backoff.

## Pricing

| Model | Model id | Input per 1M tokens | Output per 1M tokens |
| --- | --- | --- | --- |
| Qwen3.8 27B | `qwen3.8-27b` | $0.30 | $2.50 |
