- Core Concepts
- Conversation threads
Core Concepts
Conversation threads
One thread is one ongoing chat—message history, tool calls, and context—stays together until you delete it.
What this is
A thread is a single conversation: the full back-and-forth between the user and the model (including tool messages). It has a thread_id. When you send another message with the same thread_id, the model sees prior turns—that is how chat feels continuous.
Threads are not the same as assistants. Think:
- Assistant = the AI profile (memory scope, docs, defaults).
- Thread = one chat session under that profile.
Each thread belongs to exactly one assistant. You can open many threads per assistant (for example one thread per end user).
When you create or reuse a thread
| Situation | What happens |
|---|---|
First send_message with no thread_id | The API creates a new thread (and ties it to an assistant). Save thread_id from the response to continue. |
Next message with thread_id | Appends to that thread—history is preserved. |
| New thread under the same assistant | Omit thread_id but pass the same assistant_id—memory and docs from that assistant still apply. |
Key properties
| Property | Type | Description |
|---|---|---|
thread_id | uuid | Unique identifier |
assistant_id | uuid | The assistant this thread belongs to |
messages | array | Messages in the conversation (included on GET) |
metadata_ | object | Optional metadata object |
created_at | datetime | Creation timestamp |
Important behavior
- Each thread is tied to one assistant.
- You can have many threads per assistant (e.g. one per end-user).
- Threads persist until you delete them.
- Fetching a thread (
GET /threads/{id}) returns messages for inspection or debugging.
Create a thread
import requests
headers = {"X-API-Key": "YOUR_API_KEY"}
assistant_id = "your-assistant-id"
thread = requests.post(
f"https://app.backboard.io/api/assistants/{assistant_id}/threads",
headers=headers,
json={}
).json()
print(thread["thread_id"])
Get a thread (with messages)
thread = requests.get(
f"https://app.backboard.io/api/threads/{thread_id}",
headers=headers
).json()
for msg in thread["messages"]:
print(f"{msg['role']}: {msg.get('content', '')}")
List threads
Both GET /threads (all threads) and GET /assistants/{id}/threads (scoped) support skip and limit pagination.
| Parameter | Type | Default | Range | Description |
|---|---|---|---|---|
skip | integer | 0 | 0–10 000 | Number of records to skip |
limit | integer | 100 | 1–200 | Maximum number of records to return |
# All threads
all_threads = requests.get(
"https://app.backboard.io/api/threads",
headers=headers,
params={"skip": 0, "limit": 50}
).json()
# Threads for a specific assistant
asst_threads = requests.get(
f"https://app.backboard.io/api/assistants/{assistant_id}/threads",
headers=headers,
params={"skip": 0, "limit": 50}
).json()
Delete a thread
Permanently removes the thread and all its messages.
Threads do not expire automatically. Delete threads you no longer need to keep your data clean.
requests.delete(
f"https://app.backboard.io/api/threads/{thread_id}",
headers=headers
)
Cancel a run
If a streaming response is no longer needed (e.g. user presses Ctrl+C), you can cancel the in-progress run. The server stops the LLM call on the next yield. Idempotent — cancelling a finished or already-cancelled run returns 200.
result = await client.cancel_run(thread_id, run_id)
print(result) # {"thread_id": "...", "run_id": "...", "cancelled": true}
Related
- Assistant profiles — what owns threads and memory
- First Message — simplest way to get a
thread_id - Continuing conversations — SDK patterns for
thread_id - Create Thread
- List Threads
- List Threads for Assistant
- Get Thread
- Delete Thread