Threads
Threads persist conversation state across requests. Thread management endpoints (list, update, delete) require a Bearer token from TIE Auth.
Creating Threads
Section titled “Creating Threads”Pass a thread_id in your /v1/chat/completions request to maintain conversation state. TIE uses it to persist message history so the LLM has context from previous turns.
- If omitted, TIE auto-generates a UUID for the thread. Each request starts a new conversation.
- If provided, TIE resumes the conversation from where it left off. Use any string (e.g. a UUID you generate client-side).
Per-App Thread Isolation
Section titled “Per-App Thread Isolation”Threads can be scoped to a specific application using the X-App-Id header. This allows multiple apps to share the same TIE backend while keeping their conversation threads separate.
X-App-Idprovided — the thread is scoped to that app. Only requests with the sameX-App-Idcan see, rename, or delete it.X-App-Idomitted — the thread is unscoped (shared). It is visible when listing threads withoutX-App-Id, but hidden from app-scoped lists.
# Create a thread scoped to "vibrantly"curl -X POST https://your-tie-host/v1/chat/completions \ -H "Authorization: Bearer $TOKEN" \ -H "X-App-Id: vibrantly" \ -H "X-Agent-Id: chatbot" \ -d '{"model": "anthropic/claude-sonnet-4-5", "messages": [{"role": "user", "content": "Hello"}], "thread_id": "my-thread"}'Thread Metadata
Section titled “Thread Metadata”Each thread can carry an arbitrary JSON metadata object. Use it to store application-specific context that doesn't belong in the conversation itself — for example, where the thread originated, which page it's associated with, or whether it's pinned in a UI.
{ "source": "whatsapp", "pageType": "whatsapp-dm", "pageId": "550e8400-e29b-41d4-a716-446655440000", "isPinned": false}Metadata is set and updated via the Update Thread endpoint. It is returned in every thread summary (list and update responses). TIE stores metadata as-is and does not interpret it — your application defines the schema.
List Threads
Section titled “List Threads”Returns threads for the authenticated user. Supports cursor-based pagination, sorting, and date filtering.
GET https://your-tie-host/threadsAuthorization: Bearer $TOKENHeaders:
| Header | Type | Default | Description |
|---|---|---|---|
X-App-Id | string | null | Filter threads by app. When set, only threads matching that exact app ID are returned (unscoped threads are excluded). When omitted, all threads are returned (both scoped and unscoped). |
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
agent_id | string | null | Filter threads by agent |
cursor | string | null | Pagination token from a previous response (treat as opaque; do not parse or construct it) |
limit | integer | 20 | Results per page (1-100) |
order_by | string | created_at | Sort field: created_at or updated_at |
asc | boolean | false | Sort direction: true for ascending (oldest first), false for descending (newest first) |
created_after | ISO 8601 datetime | null | Only return threads created on or after this timestamp |
created_before | ISO 8601 datetime | null | Only return threads created on or before this timestamp |
Response:
{ "threads": [ { "thread_id": "847c6285-8fc9-4560-a83f-4e6285809254", "agent_id": "chatbot", "app_id": "vibrantly", "title": "What is the weather in Tokyo?", "metadata": { "source": "whatsapp", "isPinned": false }, "created_at": "2026-03-25T10:00:00+00:00", "updated_at": "2026-03-25T10:05:00+00:00" } ], "next_cursor": "MjAyNi0wMy0yNVQxMDowMDowMCswMDowMHw4NDdjNjI4NS04ZmM5LTQ1NjAtYTgzZi00ZTYyODU4MDkyNTQ="}Pass next_cursor as the cursor query parameter to fetch the next page. When next_cursor is null, there are no more results.
The app_id field is null for unscoped threads. The metadata field is null when no metadata has been set.
Get Thread History
Section titled “Get Thread History”Retrieve the full message history for a thread:
POST https://your-tie-host/historyAuthorization: Bearer $TOKENContent-Type: application/json
{ "thread_id": "<your-thread-id>" }Response:
{ "messages": [ { "type": "human", "content": "What is the weather in Tokyo?", "metadata": { "session_id": "8b94776f-31ae-49ac-9f06-3be137d69186", "platform": "ios", "app_version": "2.4.1" } }, { "type": "ai", "content": "The current weather in Tokyo is...", "metadata": null } ]}The metadata field on user messages contains the key-value pairs sent with the original request. AI messages have metadata: null since metadata is attached at request time, not per-response.
Update Thread
Section titled “Update Thread”Update a thread's title and/or metadata. The title is automatically set from the first user message, but you can override it. Metadata can be set at any time.
At least one of title or metadata must be provided in the request body.
PATCH https://your-tie-host/threads/<thread-id>Authorization: Bearer $TOKENContent-Type: application/json# Required only if the thread was created with X-App-IdX-App-Id: vibrantly
{ "title": "My weather conversation", "metadata": { "isPinned": true } }Request body:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | No | New title for the thread (1-500 characters, cannot be blank) |
metadata | object | null | No | Arbitrary metadata dict. Replaces existing metadata entirely. Pass null to clear. |
You can send either field alone or both together:
# Rename only{ "title": "New title" }
# Set metadata only{ "metadata": { "source": "telegram", "isPinned": false } }
# Clear metadata{ "metadata": null }Response:
{ "thread_id": "847c6285-8fc9-4560-a83f-4e6285809254", "agent_id": "chatbot", "app_id": "vibrantly", "title": "My weather conversation", "metadata": { "isPinned": true }, "created_at": "2026-03-25T10:00:00+00:00", "updated_at": "2026-03-25T10:10:00+00:00"}Delete Thread
Section titled “Delete Thread”Permanently delete a thread and all its data (title, metadata, timestamps, agent/app association):
DELETE https://your-tie-host/threads/<thread-id>Authorization: Bearer $TOKEN# Required only if the thread was created with X-App-IdX-App-Id: vibrantlyResponse:
{ "status": "deleted", "thread_id": "847c6285-8fc9-4560-a83f-4e6285809254" }Error Codes
Section titled “Error Codes”| Code | Status | When |
|---|---|---|
AUTH_TOKEN_MISSING | 401 | No Bearer token provided |
THREAD_NOT_FOUND | 404 | Thread does not exist or is not owned by the user |
VALIDATION_ERROR | 422 | Invalid cursor, empty title, title exceeds 500 characters, or empty update body |
THREADS_FETCH_FAILED | 500 | Unexpected server error while listing threads |
THREAD_UPDATE_FAILED | 500 | Unexpected server error while updating a thread |
THREAD_DELETE_FAILED | 500 | Unexpected server error while deleting a thread |
SERVICE_UNAVAILABLE | 501 | Thread management requires the PostgreSQL memory backend |