> ## Documentation Index
> Fetch the complete documentation index at: https://telluvian.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Responses API

> The stateful /v1/responses endpoint, with server-side conversation history.

Source: https://telluvian.ai/docs/responses

Telluvian implements OpenAI's **Responses API** as well as Chat Completions. The
official SDKs work against it unchanged:

```python
from openai import OpenAI

client = OpenAI(
    api_key="sk_live_...",
    base_url="https://api.telluvian.ai/v1",
)

response = client.responses.create(
    model="google/gemma-4-31b-it",
    input="Who was the first person on Mars?",
)

print(response.output_text)
```

## What makes it different

Chat Completions is **stateless**: you re-send the whole conversation on every
call. The Responses API is **stateful**. You send only the new input plus the
id of the previous response, and we rebuild the history server-side.

```python
first = client.responses.create(
    model="google/gemma-4-31b-it",
    input="My favourite colour is crimson.",
)

second = client.responses.create(
    model="google/gemma-4-31b-it",
    previous_response_id=first.id,
    input="What is my favourite colour?",   # the colour is not re-sent
)

print(second.output_text)   # "Crimson."
```

> **Which should you use?**
>
> Use **Chat Completions** if you already keep the conversation in your own
> application state. It is one fewer thing for us to hold, and it is what most
> existing code and frameworks expect.
>
> Use **Responses** if you would otherwise be storing the transcript purely to
> replay it to us, or if you are following OpenAI examples written against it.

## Probe scores

Scoring is off by default. Set `include_scores: true` to enable it. The per-token output rides on
the content part, next to the text it describes:

```python
response = client.responses.create(
    model="google/gemma-4-31b-it",
    extra_body={"include_scores": True},
    input="Who was the first person on Mars?",
)

part = response.output[0].content[0]
for token, score in zip(part.tokens, part.scores["hallucination"]):
    if score is not None and score > 0.5:
        print(f"flagged: {token!r}")
```

The same `null`-entry rule applies as in [Reading the scores](https://telluvian.ai/docs/scores.md): the
array is always as long as `tokens`, but an individual entry may be `null`.

Omit `include_scores`, or pass `include_scores: false` through `extra_body`,
for an unscored request without the verification fee.

## Streaming

The stream is a sequence of **typed events**, not the uniform chunks of Chat
Completions:

```python
stream = client.responses.create(
    model="google/gemma-4-31b-it",
    input="Tell me about Ada Lovelace.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "response.completed":
        print(f"\n{event.response.usage.output_tokens} tokens")
```

Events emitted, in order:

| Event | Carries |
| --- | --- |
| `response.created` | The response object, `status: "in_progress"` |
| `response.in_progress` | Same |
| `response.output_text.delta` | `delta` (text), and available `scores` when probing is enabled |
| `response.output_text.done` | The complete `text` |
| `response.completed` | The final response, with `usage` |

## Managing stored responses

Responses are stored by default so they can be continued.

```python
fetched = client.responses.retrieve(response.id)   # GET
client.responses.delete(response.id)               # DELETE
```

Pass `store=False` to make the response unavailable for retrieval or continuation
with `previous_response_id`. This is not a no-storage setting: request auditing,
billing, and configured transcript logging still apply.

```python
client.responses.create(
    model="google/gemma-4-31b-it",
    input="Nothing to keep.",
    store=False,
)
```

## Field mapping

If you are porting from Chat Completions:

| Chat Completions | Responses |
| --- | --- |
| `messages` | `input` (a string, or a list of messages) |
| a leading `system` message | `instructions` |
| `max_tokens` | `max_output_tokens` |
| `choices[0].message.content` | `output_text` |
| `usage.prompt_tokens` | `usage.input_tokens` |
| `usage.completion_tokens` | `usage.output_tokens` |
| `finish_reason: "length"` | `status: "incomplete"` |

> **instructions apply to one call only**
>
> `instructions` is **not** inherited by a response that continues this one. If
> a later call in the chain needs the same instruction, pass it again. This
> matches OpenAI's behaviour, and it means a system prompt can never become
> silently sticky across a conversation.

## Pricing

Identical to Chat Completions: the same per-token rates, the same verification
fee when explicitly enabled. Routing adds $0.05 per 1M input tokens when
`telluvian/gallery-1` picks the model. See
[Pricing](https://telluvian.ai/docs/pricing.md). Continuing a chain re-sends the stored
history to the model, so **input tokens grow with the conversation**, exactly as
they would if you had re-sent it yourself.
