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

# Responses API

> An overview of Anannas's Responses API.

The Anannas Responses API provides a unified interface for building advanced AI agents capable of executing complex tasks autonomously. This API is compatible with OpenAI's Responses API format and supports multimodal inputs, reasoning capabilities, and seamless tool integration.

<Warning>
  **Stateless API Implementation**

  This API implements the **stateless version** of the Responses API. Unlike OpenAI's stateful Responses API, Anannas does not maintain conversation state between requests. Each request is completely independent, and you must include the full conversation history in every request.
</Warning>

<Note>
  **Beta API**

  This API is in **beta stage** and may have breaking changes. Use with caution in production environments.
</Note>

### Base URL

```
https://api.anannas.ai/api/v1/responses
```

### Authentication

All requests require authentication using your Anannas API key:

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.anannas.ai/api/v1/responses",
      headers={
          "Authorization": "Bearer <ANANNAS_API_KEY>",
          "Content-Type": "application/json",
      },
      json={
          "model": "openai/gpt-5-mini",
          "input": "Hello, world!",
      },
  )
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch('https://api.anannas.ai/api/v1/responses', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <ANANNAS_API_KEY>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'openai/gpt-5-mini',
      input: 'Hello, world!',
    }),
  });
  ```

  ```go Go theme={null}
  package main

  import (
  	"bytes"
  	"encoding/json"
  	"fmt"
  	"net/http"
  )

  func main() {
  	reqBody := map[string]interface{}{
  		"model": "openai/gpt-5-mini",
  		"input": "Hello, world!",
  	}

  	jsonData, _ := json.Marshal(reqBody)
  	req, _ := http.NewRequest("POST", "https://api.anannas.ai/api/v1/responses", bytes.NewBuffer(jsonData))
  	req.Header.Set("Authorization", "Bearer <ANANNAS_API_KEY>")
  	req.Header.Set("Content-Type", "application/json")

  	client := &http.Client{}
  	resp, err := client.Do(req)
  	if err != nil {
  		fmt.Println("Error:", err)
  		return
  	}
  	defer resp.Body.Close()
  }
  ```

  ```bash cURL theme={null}
  curl https://api.anannas.ai/api/v1/responses \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <ANANNAS_API_KEY>" \
    -d '{
      "model": "openai/gpt-5-mini",
      "input": "Hello, world!"
    }'
  ```
</CodeGroup>

### Core Features

* **Stateless Design**: Each request is independent - you manage conversation history client-side
* **Multimodal Support**: Handle various input types, including text, images, and audio
* **Reasoning Capabilities**: Access advanced reasoning with configurable effort levels
* **Tool Integration**: Utilize function calling with support for parallel execution
* **Streaming Support**: Receive responses in real-time as they're generated

<Info>
  **Managing Conversation History**

  Since this API is stateless, you must include the complete conversation history in each request. Include all previous user messages and assistant responses in the `input` array to maintain context.
</Info>

### Request Format

The Responses API uses a structured request format with an `input` array containing conversation messages:

<CodeGroup>
  ```typescript TypeScript theme={null}
  type ResponsesRequest = {
    // Required
    model: string;
    input: ResponsesMessage[];

    // Optional
    instructions?: string;
    response_format?: { type: 'json_object' };
    metadata?: { [key: string]: string };
    temperature?: number;
    max_output_tokens?: number;
    stream?: boolean;
    
    // Tool calling
    tools?: Tool[];
    tool_choice?: 'auto' | 'none' | { type: 'function'; name: string };
    parallel_tool_calls?: boolean;

    // Advanced parameters
    top_p?: number;
    top_k?: number;
    frequency_penalty?: number;
    presence_penalty?: number;
    stop?: string[];
    seed?: number;

    // Reasoning
    reasoning?: {
      effort?: 'minimal' | 'low' | 'medium' | 'high';
      max_tokens?: number;
      exclude?: boolean;
    };

    // Anannas-specific
    provider?: ProviderPreferences;
    modalities?: string[];
    audio?: AudioConfig;
    mcp?: MCPConfig;
    prompt_cache_key?: string;
  };
  ```
</CodeGroup>

### Response Format

The Responses API returns a structured response with an `output` array:

<CodeGroup>
  ```typescript TypeScript theme={null}
  type ResponsesResponse = {
    id: string;
    object: 'response';
    model: string;
    created: number;
    output: ResponsesOutputItem[];
    usage: {
      prompt_tokens: number;
      completion_tokens: number;
      total_tokens: number;
    };
    metadata?: { [key: string]: any };
  };
  ```
</CodeGroup>

**Example Response:**

```json theme={null}
{
  "id": "resp_abc123",
  "object": "response",
  "model": "openai/gpt-5-mini",
  "created": 1693350000,
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "status": "completed",
      "content": [
        {
          "type": "output_text",
          "text": "Hello! How can I help you today?"
        }
      ]
    }
  ],
  "usage": {
    "prompt_tokens": 10,
    "completion_tokens": 8,
    "total_tokens": 18
  }
}
```

### Input Format

The `input` field accepts either a simple string or an array of message objects:

**Simple String Input:**

```json theme={null}
{
  "model": "openai/gpt-5-mini",
  "input": "What is the capital of France?"
}
```

**Structured Message Input:**

```json theme={null}
{
  "model": "openai/gpt-5-mini",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "input_text",
          "text": "What is the capital of France?"
        }
      ]
    }
  ]
}
```

### Output Format

The `output` array contains one or more output items. Each item can be:

* **Message**: Text response from the model
* **Function Call**: Tool/function invocation
* **Error**: Error information

**Message Output:**

```json theme={null}
{
  "type": "message",
  "role": "assistant",
  "status": "completed",
  "content": [
    {
      "type": "output_text",
      "text": "The capital of France is Paris."
    }
  ]
}
```

**Function Call Output:**

```json theme={null}
{
  "type": "message",
  "role": "assistant",
  "status": "completed",
  "content": [
    {
      "type": "function_call",
      "function_call": {
        "id": "call_abc123",
        "name": "get_weather",
        "arguments": "{\"location\": \"Paris\"}"
      }
    }
  ]
}
```

### Prompt Caching

<Card title="Check Caching Support" icon="book">
  For models that support prompt caching and current pricing, visit [anannas.ai/models](https://anannas.ai/models).
</Card>

Prompt caching allows you to reduce costs and latency by reusing cached prompt prefixes. Anannas supports two caching methods depending on the provider:

#### OpenAI Models (`prompt_cache_key`)

For OpenAI models, use the `prompt_cache_key` parameter:

```json theme={null}
{
  "model": "openai/gpt-5-mini",
  "input": "Hello, world!",
  "prompt_cache_key": "my-cache-key-123"
}
```

**Pricing:**

* **Cache reads**: Cached input tokens are billed at **50%** of the original input token price
* **Cache writes**: No additional cost for creating the cache

**How it works:**

1. First request with a `prompt_cache_key` creates the cache
2. Subsequent requests with the same key reuse the cached prefix
3. Cache is automatically managed by the provider

#### Anthropic Models (`cache_control`)

For Anthropic Claude models, use the `cache_control` object in message content:

```json theme={null}
{
  "model": "anthropic/claude-sonnet-4",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Your system instructions here...",
          "cache_control": {
            "type": "ephemeral",
            "ttl": "5m"
          }
        }
      ]
    }
  ]
}
```

**Pricing:**

* **Cache creation**: Cache creation tokens are billed at **1.25x** (125%) of the original input token price
* **Cache reads**: Cached input tokens are billed at **0.1x** (10%) of the original input token price - a **90% discount**

**Anthropic-specific requirements:**

* Maximum of **4 content blocks** can have `cache_control` per request
* Cache expires after **5 minutes** (TTL: `"5m"`)
* `cache_control` must be added to individual content parts within messages
* Only `"ephemeral"` cache type is supported

**Example with system message:**

```json theme={null}
{
  "model": "anthropic/claude-sonnet-4",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "You are a helpful assistant. Always be concise.",
          "cache_control": {
            "type": "ephemeral",
            "ttl": "5m"
          }
        },
        {
          "type": "text",
          "text": "What is 2+2?"
        }
      ]
    }
  ]
}
```

#### Other Providers

<Card title="View Caching Support" icon="book">
  For complete caching support details by provider and model, check [anannas.ai/models](https://anannas.ai/models).
</Card>

* **Grok**: Supports caching similar to OpenAI with cached tokens at **10%** of input price (90% discount)
* **Nebius**: Supports caching with provider-specific pricing
* **TogetherAI**: Supports caching with provider-specific pricing

#### Monitoring Cache Usage

Cache usage is included in the response `usage` object:

```json theme={null}
{
  "usage": {
    "prompt_tokens": 1000,
    "completion_tokens": 500,
    "total_tokens": 1500,
    "cache_read_input_tokens": 800,
    "cache_creation_input_tokens": 200
  }
}
```

* `cache_read_input_tokens`: Number of tokens read from cache (discounted pricing)
* `cache_creation_input_tokens`: Number of tokens used to create the cache (Anthropic only, 1.25x pricing)

### Error Handling

The Anannas API returns standard HTTP status codes and error responses:

```json theme={null}
{
  "error": {
    "message": "Invalid request parameters",
    "type": "invalid_request_error",
    "code": "invalid_parameter"
  }
}
```

Common error codes:

* `400 Bad Request`: Invalid request parameters
* `401 Unauthorized`: Missing or invalid API key
* `429 Too Many Requests`: Rate limit exceeded
* `500 Internal Server Error`: Server error

### Rate Limits

Rate limits are applied per API key. See the [Limits documentation](/API/LIMITS) for details.

### Next Steps

* Learn [basic usage](/API/Responses/BasicUsage) with simple text requests
* Explore [streaming responses](/API/Responses/Streaming) for real-time interactions
* Integrate [tool calling](/API/Responses/ToolCalling) for function execution
* Configure [reasoning capabilities](/Features/reasoning) for advanced problem-solving

<div
  style={{ 
marginTop: '2rem',
display: 'flex',
alignItems: 'center',
gap: '0.75rem',
fontSize: '14px',
color: '#6b7280'
}}
>
  <span>Was this page helpful?</span>

  <button
    id="feedback-yes-btn"
    onClick={() => {
  console.log('Positive feedback');
  document.getElementById('feedback-yes-btn').style.background = 'rgba(156, 163, 175, 0.1)';
  document.getElementById('feedback-yes-btn').style.backdropFilter = 'blur(10px)';
  document.getElementById('feedback-yes-btn').style.border = '1px solid rgba(156, 163, 175, 0.2)';
  document.getElementById('feedback-no-btn').style.background = 'transparent';
  document.getElementById('feedback-no-btn').style.backdropFilter = 'none';
  document.getElementById('feedback-no-btn').style.border = 'none';
}}
    style={{
  background: 'transparent',
  border: 'none',
  cursor: 'pointer',
  padding: '6px 12px',
  fontSize: '14px',
  borderRadius: '8px',
  transition: 'all 0.2s ease',
  display: 'flex',
  alignItems: 'center',
  gap: '6px',
  color: '#6b7280'
}}
  >
    <span style={{ fontSize: '16px' }}>👍</span>
    Yes
  </button>

  <button
    id="feedback-no-btn"
    onClick={() => {
  console.log('Negative feedback');
  document.getElementById('feedback-no-btn').style.background = 'rgba(156, 163, 175, 0.1)';
  document.getElementById('feedback-no-btn').style.backdropFilter = 'blur(10px)';
  document.getElementById('feedback-no-btn').style.border = '1px solid rgba(156, 163, 175, 0.2)';
  document.getElementById('feedback-yes-btn').style.background = 'transparent';
  document.getElementById('feedback-yes-btn').style.backdropFilter = 'none';
  document.getElementById('feedback-yes-btn').style.border = 'none';
}}
    style={{
  background: 'transparent',
  border: 'none',
  cursor: 'pointer',
  padding: '6px 12px',
  fontSize: '14px',
  borderRadius: '8px',
  transition: 'all 0.2s ease',
  display: 'flex',
  alignItems: 'center',
  gap: '6px',
  color: '#6b7280'
}}
  >
    <span style={{ fontSize: '16px' }}>👎</span>
    No
  </button>
</div>
