Skip to main content

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.
MethodPathPurpose
GET/v1/threadsList 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

ParamTypeNotes
identity_idUUIDFilter to threads on a single identity
statusstringopen | waiting | draft_pending | closed
needs_reviewboolThreads flagged for human attention (new inbound on a closed thread, etc.)
qstringFull-text search across thread subject and message bodies
contactstringFilter by sender email or contact name
from_dateISO dateThreads with last_message_at >= this date
to_dateISO dateThreads with last_message_at <= this date
limitint1–100, default 20
offsetintdefault 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

StatusWhen
openDefault. New thread with no draft pending.
waitingOutbound was sent; waiting on a reply.
draft_pendingA draft was submitted and is awaiting human approval.
closedThread 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

HTTPerrorMeaning
404not_foundThread does not exist or belongs to another workspace