// API Reference

Conversations

Server-side conversation state for the Responses API. Create a conversation, append items, reference it by id. The model loads the history; you never resend it.

Endpoints

Method Path Description
POST /:project_id/v1/conversations Create a conversation
GET /:project_id/v1/conversations List conversations
GET /:project_id/v1/conversations/{id} Get a conversation
POST /:project_id/v1/conversations/{id} Update a conversation
DELETE /:project_id/v1/conversations/{id} Delete a conversation
POST /:project_id/v1/conversations/{id}/items Add an item
GET /:project_id/v1/conversations/{id}/items List items
GET /:project_id/v1/conversations/{id}/items/{item_id} Get an item
DELETE /:project_id/v1/conversations/{id}/items/{item_id} Delete an item

Conversations are project-scoped. All paths are relative to your project base URL: https://api.xerotier.ai/proj_ABC123

Quick Start

Create a conversation, add a system prompt, then use it with the Responses API:

Step 1: Create a conversation
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "metadata": {"title": "Weather assistant"}, "items": [ { "type": "message", "role": "system", "content": "You are a helpful weather assistant." } ] }' # Returns: {"id": "conv_abc123", ...}
Step 2: Add a user message
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "type": "message", "role": "user", "content": "What is the weather in Paris?" }'
Step 3: Generate a response
# Responses API uses endpoint-scoped path curl -X POST https://api.xerotier.ai/proj_ABC123/my-endpoint/v1/responses \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "model": "llama-3.1-8b", "input": "What is the weather in Paris?", "conversation": {"id": "conv_abc123"} }'

The Responses API automatically loads all conversation items as context and appends the model's response to the conversation.

Lifecycle

The two surfaces meet at the conversation id; the model writes back into the same store you read from.

flowchart LR
    Create["POST /v1/conversations
conv_abc123"] AddUser["POST .../items
user message"] Respond["POST /v1/responses
conversation: {id: ...}"] LoadCtx["Server loads items
as prior context"] Generate["Model generates"] AutoAppend["Server appends
assistant + function_call items"] Harvest["Client reads new items
for call_id, content, ..."] Create --> AddUser AddUser --> Respond Respond --> LoadCtx LoadCtx --> Generate Generate --> AutoAppend AutoAppend --> Harvest Harvest -.-> AddUser

Manage Conversations

Create Conversation

POST /:project_id/v1/conversations

Parameter Type Description
metadataoptional object Up to 16 key-value pairs. Keys max 64 characters, values max 512 characters.
itemsoptional array Initial items to add (max 20). Useful for seeding system prompts or conversation history.

Response

{ "id": "conv_abc123def456", "object": "conversation", "created_at": 1709000000, "updated_at": 1709000000, "metadata": {"title": "Weather assistant"} }

List Conversations

GET /:project_id/v1/conversations

Returns a paginated list of conversations. Use cursor-based pagination with after and limit parameters.

Query Parameters

Parameter Type Description
limitoptional integer Maximum conversations to return (1-100, default 20).
afteroptional string Cursor for pagination. Pass the last_id from the previous page to get the next page.
curl
curl "https://api.xerotier.ai/proj_ABC123/v1/conversations?limit=10" \ -H "Authorization: Bearer xero_myproject_your_api_key"

Response

{ "object": "list", "data": [ { "id": "conv_abc123def456", "object": "conversation", "created_at": 1709000000, "updated_at": 1709000100, "metadata": {"title": "Weather assistant"} } ], "first_id": "conv_abc123def456", "last_id": "conv_abc123def456", "has_more": false }

Get Conversation

GET /:project_id/v1/conversations/{conversation_id}

curl
curl https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123 \ -H "Authorization: Bearer xero_myproject_your_api_key"

Update Conversation

POST /:project_id/v1/conversations/{conversation_id}

Updates the conversation metadata. The new metadata replaces the existing metadata entirely.

curl
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123 \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "metadata": {"title": "Updated title", "category": "support"} }'

Delete Conversation

DELETE /:project_id/v1/conversations/{conversation_id}

Soft-deletes the conversation. It is excluded from list queries but retained for auditing.

curl
curl -X DELETE https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123 \ -H "Authorization: Bearer xero_myproject_your_api_key"

Response

{ "id": "conv_abc123def456", "object": "conversation", "deleted": true }

Manage Items

Add Item

POST /:project_id/v1/conversations/{conversation_id}/items

Parameter Type Description
typerequired string Item type: "message", "function_call", or "function_call_output".
roleconditional string Required (non-null) for message type. By convention one of "user", "assistant", "system", or "tool"; the server stores the value as-is and does not currently reject other strings, but downstream consumers (including the Responses API) expect the conventional values.
contentrequired string Text content of the item. Required at decode time for every item type. For function_call items the call's semantic payload is in arguments; supply an empty string or a short label for content.
call_idrecommended string Recommended for function_call and function_call_output items. Links a function call to its output so the Responses API can pair them in subsequent turns. Not enforced by the server today, but omitting it will break tool-result correlation.
namerecommended string Function name. Recommended for function_call items. Not enforced by the server today, but the model will not be able to resolve the tool without it.
argumentsrecommended string Serialized JSON arguments. Recommended for function_call items. Not enforced by the server today.

For function_call_output items, the call_id must match the one the model chose; harvest it from the conversation rather than inventing it. See Multi-Turn with Function Calling below for the harvest pattern.

Message Item

curl
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "type": "message", "role": "user", "content": "Hello, how are you?" }'

Response

{ "id": "item_xyz789abcdef", "object": "conversation.item", "type": "message", "role": "user", "content": "Hello, how are you?", "call_id": null, "name": null, "arguments": null, "sequence_number": 1, "created_at": 1709000100 }

Function Call Output Item

curl
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "type": "function_call_output", "call_id": "call_abc123", "content": "{\"temperature\": 18, \"condition\": \"sunny\"}" }'

List Items

GET /:project_id/v1/conversations/{conversation_id}/items

Returns items ordered by sequence number (ascending). Supports cursor-based pagination with after and limit parameters.

Query Parameters

Parameter Type Description
limitoptional integer Maximum items to return (1-100, default 20).
afteroptional string Cursor for pagination. Pass the last_id from the previous page.
curl
curl "https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items?limit=50" \ -H "Authorization: Bearer xero_myproject_your_api_key"

Response

{ "object": "list", "data": [ { "id": "item_xyz789abcdef", "object": "conversation.item", "type": "message", "role": "user", "content": null, "call_id": null, "name": null, "arguments": null, "sequence_number": 0, "created_at": 1709000100 } ], "first_id": "item_xyz789abcdef", "last_id": "item_xyz789abcdef", "has_more": false }

Note: The content field is null in list responses for efficiency. Use the Get Item endpoint to retrieve full content for a specific item.

Get Item

GET /:project_id/v1/conversations/{conversation_id}/items/{item_id}

Returns the item with full content loaded from tiered storage.

curl
curl https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items/item_xyz789 \ -H "Authorization: Bearer xero_myproject_your_api_key"

Delete Item

DELETE /:project_id/v1/conversations/{conversation_id}/items/{item_id}

Soft-deletes the item. It is excluded from future conversation context but the sequence number gap is preserved.

curl
curl -X DELETE https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items/item_xyz789 \ -H "Authorization: Bearer xero_myproject_your_api_key"

Response

{ "id": "item_xyz789abcdef", "object": "conversation.item", "deleted": true }

Delete response shape. Both delete endpoints return the resource type in object ("conversation" or "conversation.item"), not a synthetic ".deleted" suffix. Match on the deleted: true flag, not on the object string.

Responses API Integration

Pass a conversation parameter when creating a response on the Responses API to use the conversation's items as context. The model's output is automatically appended to the conversation.

curl
curl -X POST https://api.xerotier.ai/proj_ABC123/my-endpoint/v1/responses \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "model": "llama-3.1-8b", "input": "What is the weather in Paris?", "conversation": {"id": "conv_abc123"} }'

Note that conversations are project-scoped (at /:project_id/v1/conversations) while the Responses API is endpoint-scoped (at /:project_id/:endpoint_slug/v1/responses).

How It Works

  • All active items in the conversation are loaded and prepended to the input as context.
  • The model generates a response using the full conversation history plus the new input.
  • The model's output items (messages, function calls) are automatically appended to the conversation.
  • The conversation's updated_at timestamp is refreshed.

Precedence when both are supplied. If a request includes both conversation and previous_response_id, the conversation parameter wins: the server loads the conversation's items and uses them as the chain context, ignoring the response chain that previous_response_id would otherwise have selected. The request is not rejected. Send only one of the two unless you specifically intend this override behavior. Use conversation for explicit state management and previous_response_id for simple response chaining.

Storage Tiers

Conversation content is stored using the platform's standard two-tier storage architecture. For details on storage tiers, encryption, retention, and billing, see Storage.

Conversation Storage Limits

Limit Value
Max items per conversation 100
Max individual item size 1 MB
Max metadata keys per conversation 16
Max metadata key length 64 characters
Max metadata value length 512 characters
Max total metadata size 16 KB

Error Handling

HTTP Status Error Code Description
400 invalid_request Missing or invalid parameters (e.g., missing role for message items).
400 invalid_request Initial items array exceeds 20 items.
401 authentication_error Invalid or missing API key.
404 not_found Conversation or item not found.
429 rate_limit_exceeded Too many requests. Check the Retry-After header.

Examples

Python (requests)

Python
import requests headers = { "Authorization": "Bearer xero_myproject_your_api_key", "Content-Type": "application/json" } base = "https://api.xerotier.ai/proj_ABC123/v1" # Create a conversation with a system prompt conv = requests.post(f"{base}/conversations", headers=headers, json={ "metadata": {"title": "Demo chat"}, "items": [{ "type": "message", "role": "system", "content": "You are a helpful assistant." }] }).json() print(f"Created conversation: {conv['id']}") # Add a user message requests.post( f"{base}/conversations/{conv['id']}/items", headers=headers, json={ "type": "message", "role": "user", "content": "What is the capital of France?" } ) # List conversations convs = requests.get(f"{base}/conversations?limit=10", headers=headers).json() for c in convs["data"]: print(f"Conversation: {c['id']}") # List items in a conversation items = requests.get( f"{base}/conversations/{conv['id']}/items?limit=50", headers=headers ).json() for item in items["data"]: print(f"[{item['role']}] {item['content']}") # Delete a conversation requests.delete(f"{base}/conversations/{conv['id']}", headers=headers)

Node.js (fetch)

JavaScript
const base = "https://api.xerotier.ai/proj_ABC123/v1"; const headers = { "Authorization": "Bearer xero_myproject_your_api_key", "Content-Type": "application/json" }; // Create a conversation with a system prompt const convRes = await fetch(`${base}/conversations`, { method: "POST", headers, body: JSON.stringify({ metadata: { title: "Demo chat" }, items: [{ type: "message", role: "system", content: "You are a helpful assistant." }] }) }); const conv = await convRes.json(); console.log(`Created conversation: ${conv.id}`); // Add a user message await fetch(`${base}/conversations/${conv.id}/items`, { method: "POST", headers, body: JSON.stringify({ type: "message", role: "user", content: "What is the capital of France?" }) }); // List conversations const listRes = await fetch(`${base}/conversations?limit=10`, { headers }); const list = await listRes.json(); list.data.forEach(c => console.log(`Conversation: ${c.id}`)); // List items in a conversation const itemsRes = await fetch( `${base}/conversations/${conv.id}/items?limit=50`, { headers } ); const items = await itemsRes.json(); items.data.forEach(item => console.log(`[${item.role}] ${item.content}`)); // Delete a conversation await fetch(`${base}/conversations/${conv.id}`, { method: "DELETE", headers });

Multi-Turn with Function Calling (curl)

When the Responses API decides to call a tool, it auto-appends a function_call item to the conversation. That appended item carries the call_id the model chose; you must read it from the conversation before posting the matching function_call_output. Do not invent or hardcode call_id values.

curl
# 1. Create conversation curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{"metadata": {"title": "Tool demo"}}' # Returns: {"id": "conv_abc123", ...} # 2. Generate response with tools (auto-appends a function_call item to the conversation) curl -X POST https://api.xerotier.ai/proj_ABC123/my-endpoint/v1/responses \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "model": "llama-3.1-8b", "input": "What is the weather in Paris?", "conversation": {"id": "conv_abc123"}, "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Get weather for a city", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]} } }] }' # 3. Harvest the assistant's call_id from the conversation. # The Responses API auto-appended a function_call item; list the conversation # items and pick the most recent function_call entry. Its call_id is the value # the model chose and is the only value that will correlate with the output. ASSISTANT_CALL_ID=$(curl -s \ "https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items?limit=100" \ -H "Authorization: Bearer xero_myproject_your_api_key" \ | jq -r '[.data[] | select(.type == "function_call")] | last | .call_id') echo "captured call_id: $ASSISTANT_CALL_ID" # 4. Post the function output using the captured call_id (NOT a hardcoded one) curl -X POST https://api.xerotier.ai/proj_ABC123/v1/conversations/conv_abc123/items \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d "{ \"type\": \"function_call_output\", \"call_id\": \"$ASSISTANT_CALL_ID\", \"content\": \"{\\\"temperature\\\": 18, \\\"condition\\\": \\\"sunny\\\"}\" }" # 5. Continue with the function result in context curl -X POST https://api.xerotier.ai/proj_ABC123/my-endpoint/v1/responses \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "model": "llama-3.1-8b", "input": "Great, now summarize the weather.", "conversation": {"id": "conv_abc123"} }'

Note on the list response. List Items returns content: null for efficiency. call_id, name, type, and sequence_number are populated in the list response, so harvesting the call_id does not require a follow-up Get Item call. If you also need the function arguments payload, fetch the specific item by id.