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.erebine.ai/proj_ABC123
Quick Start
Create a conversation, add a system prompt, then use it with the Responses API:
curl -X POST https://api.erebine.ai/proj_ABC123/v1/conversations \
-H "Authorization: Bearer ere_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", ...}
curl -X POST https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items \
-H "Authorization: Bearer ere_myproject_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "message",
"role": "user",
"content": "What is the weather in Paris?"
}'
# Responses API uses endpoint-scoped path
curl -X POST https://api.erebine.ai/proj_ABC123/my-endpoint/v1/responses \
-H "Authorization: Bearer ere_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 "https://api.erebine.ai/proj_ABC123/v1/conversations?limit=10" \
-H "Authorization: Bearer ere_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 https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123 \
-H "Authorization: Bearer ere_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 -X POST https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123 \
-H "Authorization: Bearer ere_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 -X DELETE https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123 \
-H "Authorization: Bearer ere_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 -X POST https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items \
-H "Authorization: Bearer ere_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 -X POST https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items \
-H "Authorization: Bearer ere_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 "https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items?limit=50" \
-H "Authorization: Bearer ere_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 https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items/item_xyz789 \
-H "Authorization: Bearer ere_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 -X DELETE https://api.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items/item_xyz789 \
-H "Authorization: Bearer ere_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 -X POST https://api.erebine.ai/proj_ABC123/my-endpoint/v1/responses \
-H "Authorization: Bearer ere_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
- The conversation's active items are loaded and prepended to the input as context, oldest-first, up to 2000 items per request.
- The model generates a response using that history plus the new input.
- The model's output items (messages, function calls) are automatically appended to the conversation.
- The conversation's
updated_attimestamp is refreshed.
The history is not trimmed to fit. If the loaded
conversation plus the new input exceeds the model's context window, the
request returns 400 context_length_exceeded under the default
truncation: "disabled". Erebine does not drop your oldest
turns and answer from a shortened conversation. The same applies to the
2000-item load bound: a conversation with more than 2000 items cannot be
replayed in one request, so under "disabled" it returns
400 context_length_exceeded rather than an answer built from
part of it. Send truncation: "auto" to have middle items
dropped to fit -- which also selects the most recent 2000 items -- or
branch the conversation. The context-window check applies only when the
model's context length is resolvable; the item bound always applies.
Use one prior-context source, not both.
conversation and previous_response_id are
mutually exclusive. A request carrying both returns
400 invalid_request_error (code invalid_request,
param conversation); neither source is applied. 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)
import requests
headers = {
"Authorization": "Bearer ere_myproject_your_api_key",
"Content-Type": "application/json"
}
base = "https://api.erebine.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)
const base = "https://api.erebine.ai/proj_ABC123/v1";
const headers = {
"Authorization": "Bearer ere_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.
# 1. Create conversation
curl -X POST https://api.erebine.ai/proj_ABC123/v1/conversations \
-H "Authorization: Bearer ere_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.erebine.ai/proj_ABC123/my-endpoint/v1/responses \
-H "Authorization: Bearer ere_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.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items?limit=100" \
-H "Authorization: Bearer ere_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.erebine.ai/proj_ABC123/v1/conversations/conv_abc123/items \
-H "Authorization: Bearer ere_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.erebine.ai/proj_ABC123/my-endpoint/v1/responses \
-H "Authorization: Bearer ere_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.