Skip to main content

Overview

Threads represent conversation sessions between users and the Loom AI agent. Each thread contains a sequence of messages, tool calls, and execution state. Ownership: Users can only access threads they own. System administrators can access all threads.

Create or Update Thread

PUT /api/threads/{id}
Creates a new thread or updates an existing one. Supports optimistic concurrency control via the If-Match header.

Path Parameters

id
string
required
Thread ID (must match ID in request body)

Headers

If-Match
integer
Expected thread version for optimistic locking

Request Body

Send the full Thread object (see loom-common-thread schema):
id
string
required
Thread ID (must match path parameter)
title
string
Thread title
workspace
string
Workspace root path
visibility
string
required
Visibility level: "private", "shared", or "public"
messages
array
required
Array of message objects
version
integer
required
Thread version (increment on each update)
updated_at
string
required
ISO 8601 timestamp (server will overwrite)

Response

id
string
Thread ID
version
integer
New version number after upsert
updated_at
string
ISO 8601 timestamp of last update

Example

curl -X PUT https://loom.ghuntley.com/api/threads/thread_abc123 \
  -H "Authorization: Bearer loom_sk_..." \
  -H "Content-Type: application/json" \
  -H "If-Match: 5" \
  -d '{
    "id": "thread_abc123",
    "title": "Fix login bug",
    "workspace": "/home/user/project",
    "visibility": "private",
    "messages": [...],
    "version": 5,
    "updated_at": "2026-03-03T12:00:00Z"
  }'
Response (200 OK):
{
  "id": "thread_abc123",
  "title": "Fix login bug",
  "workspace": "/home/user/project",
  "visibility": "private",
  "messages": [...],
  "version": 6,
  "updated_at": "2026-03-03T12:05:30Z"
}
Error (409 Conflict) if version mismatch:
{
  "error": "version_conflict",
  "message": "Expected version 5, but current version is 7"
}

Get Thread

GET /api/threads/{id}
Retrieves a single thread by ID. Only the thread owner (or system admin) can access.

Path Parameters

id
string
required
Thread ID

Response

Returns the full Thread object.

Example

curl -H "Authorization: Bearer loom_sk_..." \
  https://loom.ghuntley.com/api/threads/thread_abc123
{
  "id": "thread_abc123",
  "title": "Fix login bug",
  "workspace": "/home/user/project",
  "visibility": "private",
  "messages": [
    {
      "role": "user",
      "content": "Help me fix the login bug",
      "timestamp": "2026-03-03T12:00:00Z"
    },
    {
      "role": "assistant",
      "content": "I'll help you investigate the login bug.",
      "timestamp": "2026-03-03T12:00:15Z"
    }
  ],
  "version": 6,
  "updated_at": "2026-03-03T12:05:30Z",
  "created_at": "2026-03-01T10:00:00Z"
}
Error (404 Not Found) if thread doesn’t exist or user doesn’t own it:
{
  "error": "not_found",
  "message": "Thread not found"
}

List Threads

GET /api/threads
Lists threads owned by the authenticated user. Supports filtering by workspace and pagination.

Query Parameters

workspace
string
Filter by workspace root path
limit
integer
default:"50"
Maximum number of results (1-100)
offset
integer
default:"0"
Number of results to skip for pagination

Response

threads
array
Array of ThreadSummary objects (lightweight version without full message history)
total
integer
Total number of threads matching the filter
limit
integer
Limit from request
offset
integer
Offset from request

Example

curl "https://loom.ghuntley.com/api/threads?workspace=/home/user/project&limit=20&offset=0" \
  -H "Authorization: Bearer loom_sk_..."
{
  "threads": [
    {
      "id": "thread_abc123",
      "title": "Fix login bug",
      "workspace": "/home/user/project",
      "visibility": "private",
      "message_count": 12,
      "updated_at": "2026-03-03T12:05:30Z",
      "created_at": "2026-03-01T10:00:00Z"
    },
    {
      "id": "thread_def456",
      "title": "Add user settings page",
      "workspace": "/home/user/project",
      "visibility": "private",
      "message_count": 8,
      "updated_at": "2026-03-02T15:30:00Z",
      "created_at": "2026-03-02T14:00:00Z"
    }
  ],
  "total": 47,
  "limit": 20,
  "offset": 0
}

Delete Thread

DELETE /api/threads/{id}
Soft-deletes a thread. Only the thread owner (or system admin) can delete.

Path Parameters

id
string
required
Thread ID

Response

Returns 204 No Content on success.

Example

curl -X DELETE https://loom.ghuntley.com/api/threads/thread_abc123 \
  -H "Authorization: Bearer loom_sk_..."
Response: 204 No Content Error (404 Not Found) if thread doesn’t exist or user doesn’t own it.

Update Thread Visibility

POST /api/threads/{id}/visibility
Updates only the thread visibility without syncing the full thread content. Supports optimistic locking.

Path Parameters

id
string
required
Thread ID

Headers

If-Match
integer
Expected thread version

Request Body

visibility
string
required
New visibility: "private", "shared", or "public"

Response

Returns the updated Thread object with incremented version.

Example

curl -X POST https://loom.ghuntley.com/api/threads/thread_abc123/visibility \
  -H "Authorization: Bearer loom_sk_..." \
  -H "If-Match: 6" \
  -H "Content-Type: application/json" \
  -d '{"visibility": "shared"}'
{
  "id": "thread_abc123",
  "title": "Fix login bug",
  "visibility": "shared",
  "version": 7,
  "updated_at": "2026-03-03T13:00:00Z",
  ...
}

Search Threads

GET /api/threads/search
Full-text search across thread titles and messages. Searches only threads owned by the authenticated user.

Query Parameters

q
string
required
Search query
workspace
string
Filter by workspace root
limit
integer
default:"50"
Maximum number of results
offset
integer
default:"0"
Pagination offset

Response

hits
array
Array of search results with relevance scores
hits[].summary
object
ThreadSummary object
hits[].score
number
Relevance score (higher = more relevant)
limit
integer
Limit from request
offset
integer
Offset from request

Example

curl "https://loom.ghuntley.com/api/threads/search?q=login+bug&limit=10" \
  -H "Authorization: Bearer loom_sk_..."
{
  "hits": [
    {
      "summary": {
        "id": "thread_abc123",
        "title": "Fix login bug",
        "workspace": "/home/user/project",
        "message_count": 12,
        "updated_at": "2026-03-03T12:05:30Z"
      },
      "score": 0.92
    },
    {
      "summary": {
        "id": "thread_ghi789",
        "title": "Login form validation",
        "workspace": "/home/user/project",
        "message_count": 5,
        "updated_at": "2026-02-28T09:00:00Z"
      },
      "score": 0.67
    }
  ],
  "limit": 10,
  "offset": 0
}
Error (400 Bad Request) if search query is empty:
{
  "error": "bad_request",
  "message": "Empty search query"
}

Build docs developers (and LLMs) love