Documentation Index
Fetch the complete documentation index at: https://docs.actionlayer.dev/llms.txt
Use this file to discover all available pages before exploring further.
A thread is a conversation between one of your sender identities and an external contact. Inbound and outbound messages on the same RFC Message-ID chain are merged into the same thread.
| Method | Path | Purpose |
|---|
GET | /v1/threads | List threads with filters |
GET | /v1/threads/{thread_id} | Get one thread with full message + draft history |
All endpoints require Authorization: Bearer YOUR_API_KEY.
List threads
curl https://api.actionlayer.dev/v1/threads?status=open&limit=20 \
-H "Authorization: Bearer $ACTIONLAYER_API_KEY"
Query parameters
| Param | Type | Notes |
|---|
identity_id | UUID | Filter to threads on a single identity |
status | string | open | waiting | draft_pending | closed |
needs_review | bool | Threads flagged for human attention (new inbound on a closed thread, etc.) |
q | string | Full-text search across thread subject and message bodies |
contact | string | Filter by sender email or contact name |
from_date | ISO date | Threads with last_message_at >= this date |
to_date | ISO date | Threads with last_message_at <= this date |
limit | int | 1–100, default 20 |
offset | int | default 0 |
Response
{
"data": [
{
"id": "8f1c0d1a-…",
"workspace_id": "…",
"identity_id": "…",
"primary_contact_id": "…",
"subject": "Re: Pricing question",
"status": "open",
"last_message_at": "2026-04-30T14:22:11Z",
"needs_review": true,
"created_at": "2026-04-29T09:10:00Z",
"updated_at": "2026-04-30T14:22:11Z"
}
],
"total": 42,
"limit": 20,
"offset": 0
}
Threads are ordered by last_message_at descending, with nulls last.
Get a thread
curl https://api.actionlayer.dev/v1/threads/THREAD_ID \
-H "Authorization: Bearer $ACTIONLAYER_API_KEY"
Returns the thread plus the full message history and any drafts attached to it.
{
"id": "8f1c0d1a-…",
"subject": "Re: Pricing question",
"status": "open",
"needs_review": true,
"messages": [
{
"id": "msg_…",
"direction": "inbound",
"from_email": "lead@example.com",
"to_emails": ["mia@yourcompany.com"],
"subject": "Pricing question",
"body_text": "Hi — what's the price for…",
"received_at": "2026-04-30T14:22:11Z",
"created_at": "2026-04-30T14:22:11Z"
}
],
"drafts": [
{
"id": "draft_…",
"status": "pending",
"based_on_message_id": "msg_…",
"body_text": "Thanks for reaching out…",
"rationale": "Acknowledging while I check the calendar."
}
]
}
Messages are returned ascending by created_at. Drafts are returned descending by created_at (newest first).
Always note the id of the last inbound message before submitting a draft. That value goes into based_on_message_id on the draft and powers stale detection.
Thread statuses
| Status | When |
|---|
open | Default. New thread with no draft pending. |
waiting | Outbound was sent; waiting on a reply. |
draft_pending | A draft was submitted and is awaiting human approval. |
closed | Thread has been resolved or archived. |
Statuses transition automatically based on send/receive events and rule actions. You can also force a transition via the rules engine action set_thread_status.
Errors
| HTTP | error | Meaning |
|---|
| 404 | not_found | Thread does not exist or belongs to another workspace |