> For the complete documentation index, see [llms.txt](https://docs.ionos.com/cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ionos.com/cloud/ai/ai-model-hub/how-tos/responses.md).

# Responses API

The <code class="expression">space.vars.ionos\_cloud\_ai\_model\_hub</code> provides a Responses API at `/v1/responses` as an alternative to standard chat completions for text generation. Instead of a message array, it accepts a flat list of input items and returns a list of typed output items. This structure isolates the model's reasoning and tool calls into distinct, readable objects rather than bundling them into a single message.

## Supported models

All Large Language Models (LLMs) shown on the AI Model Hub [<mark style="color:blue;">Models</mark>](/cloud/ai/ai-model-hub/models.md) can be used with the Responses API. Reasoning-capable models return an additional reasoning item, described in [<mark style="color:blue;">Read the output</mark>](#read-the-output).

## Overview

In this guide, you will learn how to generate responses using the Responses API. It targets developers who already understand:

* REST APIs.
* A programming language for interacting with REST endpoints, such as Python or Bash.

By the end, you will be able to:

1. Send a request to the Responses API and read the result.
2. Tell the output item types apart, including the model's reasoning.
3. Call a tool and return its result to the model.
4. Recognize which parts of the OpenAI Responses API are not available.

## Getting started

Provide a `model` and an `input`. The input is either a string, for a single turn, or an array of items for a conversation.

{% tabs %}
{% tab title="Python" %}

```python
import requests

IONOS_API_TOKEN = "[YOUR API TOKEN HERE]"
MODEL_NAME = "[MODEL NAME HERE]"

endpoint = "https://openai.inference.de-txl.ionos.com/v1/responses"

header = {
    "Authorization": f"Bearer {IONOS_API_TOKEN}",
    "Content-Type": "application/json"
}
body = {
    "model": MODEL_NAME,
    "input": "Name three cities on the Rhine."
}
result = requests.post(endpoint, json=body, headers=header).json()
```

{% endtab %}

{% tab title="Bash" %}

```bash
#!/bin/bash

IONOS_API_TOKEN=[YOUR API TOKEN HERE]
MODEL_NAME=[MODEL NAME HERE]

BODY='{
    "model": "'"$MODEL_NAME"'",
    "input": "Name three cities on the Rhine."
}'

curl -X POST -H "Authorization: Bearer ${IONOS_API_TOKEN}" \
     -H "Content-Type: application/json" \
     -d "$BODY" \
     https://openai.inference.de-txl.ionos.com/v1/responses
```

{% endtab %}
{% endtabs %}

To send a conversation instead of a single string, pass an array of items with a `role` and `content`:

```python
body = {
    "model": MODEL_NAME,
    "input": [
        {"role": "user", "content": "Name three cities on the Rhine."},
        {"role": "assistant", "content": "Cologne, Bonn, and Mainz."},
        {"role": "user", "content": "Which of those is furthest south?"}
    ]
}
```

Use `instructions` for a system prompt. It applies to the whole request and does not need a message of its own.

## Read the output

The response carries an `output` array rather than a single message. Each item has a `type`, and the fields that apply depend on it:

| `type`          | What it holds                                                                                          |
| --------------- | ------------------------------------------------------------------------------------------------------ |
| `message`       | The answer. Its `content` array holds parts of type `output_text`.                                     |
| `reasoning`     | The model's reasoning trace, in parts of type `reasoning_text`. Only reasoning-capable models emit it. |
| `function_call` | A tool the model wants called, with `name`, `arguments`, and a `call_id`.                              |

Read the answer by taking the `output_text` parts of the `message` item, rather than assuming the first item is the answer. A reasoning model puts its `reasoning` item first.

{% tabs %}
{% tab title="Python" %}

```python
answer = "".join(
    part["text"]
    for item in result["output"]
    if item["type"] == "message"
    for part in item.get("content", [])
    if part["type"] == "output_text"
)
```

{% endtab %}
{% endtabs %}

The top-level `status` field can be `completed`, `failed`, or `incomplete`. If a response is cut short by the `max_output_tokens` limit, the status will be `incomplete`. Always check this status before processing the output.

## Call a Tool

Tools are declared with the function definition at the top level of the tool object. This differs from standard chat completions, where the definition is nested under a `function` key.

```python
tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"]
    }
}]

body = {
    "model": MODEL_NAME,
    "input": "What is the weather in Berlin?",
    "tools": tools
}
```

When the model decides to call the tool, the output contains a `function_call` item:

```json
{
  "type": "function_call",
  "call_id": "call_abc123",
  "name": "get_weather",
  "arguments": "{\"city\": \"Berlin\"}"
}
```

Run the function yourself, then send a second request containing the whole conversation: your original input, the `function_call` item exactly as you received it, and a `function_call_output` item carrying the result. Match the two with `call_id`.

```python
body = {
    "model": MODEL_NAME,
    "input": [
        {"role": "user", "content": "What is the weather in Berlin?"},
        {"type": "function_call", "call_id": "call_abc123",
         "name": "get_weather", "arguments": "{\"city\": \"Berlin\"}"},
        {"type": "function_call_output", "call_id": "call_abc123",
         "output": "{\"temperature_c\": 18, \"conditions\": \"cloudy\"}"}
    ],
    "tools": tools
}
```

{% hint style="info" %}
**Note:** The service keeps no conversation state, so every request must carry the full conversation, including any earlier tool calls, and their results.
{% endhint %}

## Limitations

The following parts of the OpenAI Responses API are not available. Sending one of these fields returns a `400` error that names the field, so a request never appears to succeed while quietly ignoring what you asked for. For more information, see [<mark style="color:blue;">Error Codes</mark>](/cloud/ai/ai-model-hub/error-codes.md).

| Field                                                 | Instead                                                                                 |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `store`, `previous_response_id`, `conversation`       | Send the full conversation in the `input` field on each request and save the responses. |
| `background`                                          | Omit it to receive the response synchronously.                                          |
| `stream`                                              | Omit it to receive the complete response.                                               |
| Built-in tools such as `web_search` and `file_search` | Only `function` tools are available.                                                    |

`tool_choice` accepts `auto` and `none`. `required` and named tool choice are not supported: depending on the model, such a request either returns an error or is answered without the forced call. Use `auto` and treat a tool call as something the model may or may not decide to make.

Image input depends on the model: `input_image` parts are accepted by models whose model card advertises image input, and return an error for models that do not. Pass the image as a publicly reachable URL or a `base64` data URI:

```json
{
  "role": "user",
  "content": [
    { "type": "input_text", "text": "What does this diagram show?" },
    { "type": "input_image", "image_url": "data:image/webp;base64,[BASE64 IMAGE DATA]" }
  ]
}
```

For the accepted formats and the request size limits, see [<mark style="color:blue;">Image Input</mark>](/cloud/ai/ai-model-hub/how-tos/image-input.md).

{% hint style="warning" %}
**Important:** Fields not listed in this guide are silently ignored rather than refused. If you pass a field that the standard OpenAI Responses API defines but this API omits, such as `metadata` or `include`, the request is accepted, but the field has no effect. Always refer to the [<mark style="color:blue;">API Reference</mark>](https://api.ionos.com/docs/inference-openai/v1/) before relying on a specific parameter.
{% endhint %}

## What you learned

In this guide, you learned how to:

1. Send a request to the Responses API using a string or a conversation array.
2. Read the typed output items, including the reasoning trace.
3. Call a tool and return its result.
4. Recognize the unsupported fields and what to use instead.

For the equivalent workflow using the chat completions API, see [<mark style="color:blue;">Text Generation</mark>](/cloud/ai/ai-model-hub/how-tos/text-generation.md) and [<mark style="color:blue;">Tool Calling</mark>](/cloud/ai/ai-model-hub/how-tos/tool-calling.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ionos.com/cloud/ai/ai-model-hub/how-tos/responses.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
