Threads API
Threads are conversation containers backed by Temporal workflows.
Create Thread
POST /threads
Request Body
{
"thread_id": "thread-abc123",
"metadata": {
"user": "alice",
"project": "demo"
}
}
| Field | Description |
|---|---|
thread_id | Optional. Custom thread ID. Auto-generated if not provided. |
metadata | Optional. Arbitrary key/value metadata. Values are stored as strings — non-string values are converted via string formatting. |
Response
Returns 201 Created:
{
"thread_id": "thread-abc123",
"status": "idle",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"metadata": {
"user": "alice",
"project": "demo"
}
}
Example
curl -X POST http://localhost:8090/threads \
-H "Content-Type: application/json" \
-d '{"metadata": {"user": "alice"}}'
Get Thread
GET /threads/{thread_id}
Response
{
"thread_id": "thread-abc123",
"status": "idle",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:35:00Z",
"metadata": {
"user": "alice"
},
"values": {
"messages": [...],
"step_count": 5
}
}
Thread Status
| Status | Description |
|---|---|
idle | No active run |
busy | Run in progress |
interrupted | Waiting for human input |
error | Last run failed |
Example
curl http://localhost:8090/threads/thread-abc123
Update Thread
PATCH /threads/{thread_id}
Request Body
{
"metadata": {
"priority": "high"
}
}
metadata is required and non-empty. As with Create Thread, values
are stored as strings.
Response
{
"thread_id": "thread-abc123",
"status": "idle",
"updated_at": "2024-01-15T10:35:00Z",
"metadata": {
"user": "alice",
"priority": "high"
}
}
The current implementation does not repopulate created_at on this response — it
serializes as the Go zero value "0001-01-01T00:00:00Z" rather than the thread's actual
creation time. Use Get Thread if you need the real created_at.
Example
curl -X PATCH http://localhost:8090/threads/thread-abc123 \
-H "Content-Type: application/json" \
-d '{"metadata": {"priority": "high"}}'
Delete Thread
DELETE /threads/{thread_id}
Cancels the Temporal workflow and cleans up resources.
Response
Returns 204 No Content with an empty body.
Example
curl -X DELETE http://localhost:8090/threads/thread-abc123
Copy Thread
POST /threads/{thread_id}/copy
Creates a new thread populated with the source thread's state (messages, values, metadata). Useful for branching a conversation, creating backups, or template-based thread setup.
Request Body
The body is optional — sending an empty POST uses an auto-generated thread ID.
{
"thread_id": "thread-backup"
}
| Field | Description |
|---|---|
thread_id | Optional. ID for the new (destination) thread. Auto-generated if not provided. |
Response
Returns 201 Created with the new thread:
{
"thread_id": "thread-backup",
"status": "idle",
"created_at": "2024-01-15T10:35:00Z",
"updated_at": "2024-01-15T10:35:00Z",
"metadata": {"user": "alice"}
}
There is no values field on this response (it's omitted, not an empty object) —
fetch the copied state separately with Get State.
Only the source thread's root namespace checkpoint is copied. If the
source thread has in-flight subgraph state (a non-empty checkpoint_ns),
that subgraph state is not carried over to the new thread — see
Subgraphs and Namespace Growth
for how AgentVisor partitions checkpoint state by namespace.
Example
# Auto-generated destination ID
curl -X POST http://localhost:8090/threads/thread-abc123/copy
# Explicit destination ID
curl -X POST http://localhost:8090/threads/thread-abc123/copy \
-H "Content-Type: application/json" \
-d '{"thread_id": "thread-backup"}'
Search Threads
POST /threads/search
Request Body
{
"status": "idle",
"metadata": {
"user": "alice"
},
"limit": 10,
"offset": 0
}
Response
[
{
"thread_id": "thread-abc123",
"status": "idle",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"metadata": {"user": "alice"}
},
{
"thread_id": "thread-def456",
"status": "idle",
"created_at": "2024-01-15T09:00:00Z",
"updated_at": "2024-01-15T09:00:00Z",
"metadata": {"user": "alice"}
}
]
updated_at here reflects the Temporal workflow start time, the same as created_at —
it is not the time of the thread's last state change.
Example
curl -X POST http://localhost:8090/threads/search \
-H "Content-Type: application/json" \
-d '{"status": "interrupted"}'
Thread History
GET /threads/{thread_id}/history
POST /threads/{thread_id}/history
Returns checkpoint history for the thread as a plain array, most recent first. The POST
form accepts the same filters as a JSON body instead of query parameters (the form used by
the reference langgraph_sdk client), and additionally accepts checkpoint.checkpoint_ns to
target a specific namespace (LangGraph subgraph). Both forms are supported; the GET form is
not being removed.
Query Parameters (GET)
| Parameter | Default | Description |
|---|---|---|
limit | 100 | Max number of history entries to return (max 1000) |
Request Body (POST)
{
"limit": 100,
"before": "cp-002",
"checkpoint": {"checkpoint_ns": ""}
}
| Field | Description |
|---|---|
limit | Max number of history entries to return |
before | Optional. Return entries strictly older than this checkpoint ID (cursor-based pagination) |
metadata | Accepted for Agent Protocol parity; not used for filtering |
checkpoint.checkpoint_ns | Optional. Filters to a specific namespace (empty string is the root graph) |
Response
[
{
"checkpoint": {"thread_id": "thread-abc123", "checkpoint_ns": "", "checkpoint_id": "cp-002"},
"values": {"step_count": 2},
"metadata": {"source": "loop"},
"created_at": "2024-01-15T10:31:00Z",
"parent_checkpoint": {"thread_id": "thread-abc123", "checkpoint_ns": "", "checkpoint_id": "cp-001"}
},
{
"checkpoint": {"thread_id": "thread-abc123", "checkpoint_ns": "", "checkpoint_id": "cp-001"},
"values": {"step_count": 1},
"created_at": "2024-01-15T10:30:00Z"
}
]
| Field | Description |
|---|---|
checkpoint | Identifies this entry's own checkpoint (thread_id/checkpoint_ns/checkpoint_id) |
values | State values at this checkpoint |
metadata | Optional checkpoint metadata |
created_at | When this checkpoint was created |
parent_checkpoint | Optional. Identifies the parent checkpoint (for branching), same shape as checkpoint |
Example
curl http://localhost:8090/threads/thread-abc123/history
curl -X POST http://localhost:8090/threads/thread-abc123/history \
-H "Content-Type: application/json" \
-d '{"limit": 10}'