Skip to main content
A thread is created against a published agent and then accumulates messages and runs. It is the container everything else hangs off.

Ownership is fixed at creation

A thread binds to the subject that created it and to the agent named at creation. Neither changes afterwards. Because reads are scoped to (workspace, subject), asking for someone else’s thread returns 404 rather than 403 — from that subject’s point of view the thread does not exist.

Listing

GET /v1/loom/threads returns the subject’s recent active threads, most recently updated first. Each entry carries a title derived from the first user message, a message count, a preview of the last message, and — importantly — whichever pending_* field says what the thread is waiting for. That list endpoint is how a polling client discovers a paused run. See Runs and states.

A subject is required

Threads are partitioned by subject, so every call to them names one. In relay that means Patchwork-Subject on each request; with a session token the subject comes from the signed sub and there is nothing to send. Omitting it is a 400 subject_required, not a wider result set. There is no way to read across subjects: a request that does not say who it is for cannot be answered, because the honest answer would be somebody else’s conversations.

Continuity

The same subject talking to the same agent should reuse its thread. That is what gives a returning user their history. Create a new thread when the conversation should start clean — a new support ticket, a new session, a new task. Threads are soft-deleted, so a removed thread stops appearing in listings without destroying the runs and traces underneath it.