Threa Developers

Reference

API reference.

Every endpoint, generated from the OpenAPI spec we ship. Set your workspace ID and key in the Credentials panel (top right) and the read-only examples run against your own workspace as you read.

The base is https://app.threa.io, under the stable /api/v1 prefix and scoped to a workspace: /api/v1/workspaces/{workspaceId}/…. The v1 segment does not move as the API evolves; versions are dated and selected with the Threa-Version header, described in Versioning. Every request authenticates with Authorization: Bearer <key>. Error shapes, paging, idempotency, and rate limits live in Operations.

Identity

Confirm who a key belongs to and list the bots you own.

GET /api/v1/workspaces/{workspaceId}/me

Get the authenticated principal

Returns a discriminated union describing the authenticated principal: the API-key owner (`kind: "user"`) or the bot whose key is in use (`kind: "bot"`). Also reports the key's API version pin, the version this request resolved to, and the supported versions. Used by clients (e.g. the OpenClaw channel plugin) to verify their key and discover their identity after pairing.

Scope none — any valid key

Response 200

dataobjectrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/me/bots

List my personal bots

For user-scoped keys: lists the authenticated user's personal bots, optionally filtered by trait. Used by the frontend to enumerate quick-switcher commands. Bot-scoped keys receive 403.

Scope none — any valid key

Query parameters

traitsstring
one of: mentionable, active-scratchpad

Response 200

dataobject[]required
idstringrequired
workspaceIdstringrequired
traitsstring[]required
slugstring | nullrequired
namestringrequired
descriptionstring | nullrequired
avatarEmojistring | nullrequired
avatarUrlstring | nullrequired
archivedAtstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
typestringrequired
ownerUserIdstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource

Streams

List and inspect streams (channels, scratchpads, threads)

Recipes Notify a stream from CI →

GET /api/v1/workspaces/{workspaceId}/streams

List streams

List streams accessible to this API key, with optional type and text filters.

Scope streams:read

Query parameters

typeanyrequired
querystring
afterstring
limitinteger
1–200 · default 50
includeArchivedstring
one of: true, false

Response 200

dataobject[]required
idstringrequired
typestringrequired
one of: scratchpad, channel, dm, thread, system
displayNamestringrequired
slugstring
descriptionstring
visibilitystringrequired
memoryModestringrequired
one of: auto, off

GAM memory automation gate: 'auto' extracts memos, 'off' disables it

parentStreamIdstring
rootStreamIdstring
anchorIdstring

Canonical id of the timeline item a thread anchors on. The prefix is the kind: 'msg_…' for a message, 'event_…' for a card. Present on threads only.

createdAtstringrequired
date-time
archivedAtstring
date-time
hasMorebooleanrequired
cursorstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/streams/{streamId}

Get a stream

Scope streams:read

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Response 200

dataobjectrequired
idstringrequired
typestringrequired
one of: scratchpad, channel, dm, thread, system
displayNamestringrequired
slugstring
descriptionstring
visibilitystringrequired
memoryModestringrequired
one of: auto, off

GAM memory automation gate: 'auto' extracts memos, 'off' disables it

parentStreamIdstring
rootStreamIdstring
anchorIdstring

Canonical id of the timeline item a thread anchors on. The prefix is the kind: 'msg_…' for a message, 'event_…' for a card. Present on threads only.

createdAtstringrequired
date-time
archivedAtstring
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
PATCH /api/v1/workspaces/{workspaceId}/streams/{streamId}

Set a stream's description

Set the stream's description from markdown (parsed to rich text, same as message content). Send an empty string to clear it. User-scoped keys attribute the change to the key owner; workspace-scoped keys to the bot.

Scope streams:write

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Request body

descriptionstringrequired
max length 10000

Response 200

dataobjectrequired
idstringrequired
typestringrequired
one of: scratchpad, channel, dm, thread, system
displayNamestringrequired
slugstring
descriptionstring
visibilitystringrequired
memoryModestringrequired
one of: auto, off

GAM memory automation gate: 'auto' extracts memos, 'off' disables it

parentStreamIdstring
rootStreamIdstring
anchorIdstring

Canonical id of the timeline item a thread anchors on. The prefix is the kind: 'msg_…' for a message, 'event_…' for a card. Present on threads only.

createdAtstringrequired
date-time
archivedAtstring
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
GET /api/v1/workspaces/{workspaceId}/streams/{streamId}/members

List stream members

Scope streams:read

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Query parameters

afterstring
limitinteger
1–200 · default 50

Response 200

dataobject[]required
userIdstringrequired
namestringrequired
slugstringrequired
avatarUrlstring
joinedAtstringrequired
date-time
hasMorebooleanrequired
cursorstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource

Messages

Read, send, update, and delete messages

Recipes Notify a stream from CI →Mirror a search into your own tool →

POST /api/v1/workspaces/{workspaceId}/messages/search

Search messages

Full-text and optional semantic search across accessible streams.

Scope messages:search

Request body

querystringrequired
min length 1
semanticbooleanrequired
default false
exactbooleanrequired
default false
streamsstring[]
fromstring
typestring[]
beforestring
date-time
afterstring
date-time
limitintegerrequired
1–50 · default 20

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

contentstringrequired
authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
replyCountintegerrequired
-9007199254740991–9007199254740991
metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

editedAtstring
date-time
createdAtstringrequired
date-time
ranknumberrequired
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/streams/{streamId}/messages

List messages in a stream

Cursor-paginated message list. Use `before` or `after` sequence numbers.

Scope messages:read

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Query parameters

beforestring
afterstring
limitinteger
1–100 · default 50

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
contentstringrequired
replyCountintegerrequired
-9007199254740991–9007199254740991
threadStreamIdstring
clientMessageIdstring
sentViastring

Present when message was sent via API on behalf of a user

metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

attachmentsobject[]
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstring
one of: pending, processing, completed, failed, skipped
widthinteger
-9007199254740991–9007199254740991
heightinteger
-9007199254740991–9007199254740991
editedAtstring
date-time
createdAtstringrequired
date-time
hasMorebooleanrequired
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/streams/{streamId}/messages

Send a message

Send a message. Workspace-scoped keys send as a bot; user-scoped keys send on behalf of the key owner. Optionally declare the message's conversation via `conversation`: `{intent: "new"}` starts a fresh conversation, `{intent: "existing", conversationId}` posts into one under the same root stream.

Scope messages:write

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Request body

contentstringrequired
min length 1
clientMessageIdstring
max length 128
metadataobject
conversationobject

Response 201

dataobjectrequired
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
contentstringrequired
replyCountintegerrequired
-9007199254740991–9007199254740991
threadStreamIdstring
clientMessageIdstring
sentViastring

Present when message was sent via API on behalf of a user

metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

attachmentsobject[]
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstring
one of: pending, processing, completed, failed, skipped
widthinteger
-9007199254740991–9007199254740991
heightinteger
-9007199254740991–9007199254740991
editedAtstring
date-time
createdAtstringrequired
date-time
conversationIdstring

The conversation the message was assigned to; present when the request declared a `conversation`.

slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 201 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/messages/find-by-metadata

Find messages by metadata

Find non-deleted messages whose `metadata` contains all the given key/value pairs (AND-containment). Useful for dedup flows, e.g. 'has a message already been posted for this GitHub PR event?'.

Scope messages:read

Request body

metadataobjectrequired
streamIdstring
min length 1
limitintegerrequired
1–100 · default 20

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
contentstringrequired
replyCountintegerrequired
-9007199254740991–9007199254740991
threadStreamIdstring
clientMessageIdstring
sentViastring

Present when message was sent via API on behalf of a user

metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

attachmentsobject[]
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstring
one of: pending, processing, completed, failed, skipped
widthinteger
-9007199254740991–9007199254740991
heightinteger
-9007199254740991–9007199254740991
editedAtstring
date-time
createdAtstringrequired
date-time
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
PATCH /api/v1/workspaces/{workspaceId}/messages/{messageId}

Update a message

Update a message you previously sent via API.

Scope messages:write

Path parameters

messageIdstringrequired

Message ID (prefixed ULID)

Request body

contentstringrequired
min length 1

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
contentstringrequired
replyCountintegerrequired
-9007199254740991–9007199254740991
threadStreamIdstring
clientMessageIdstring
sentViastring

Present when message was sent via API on behalf of a user

metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

attachmentsobject[]
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstring
one of: pending, processing, completed, failed, skipped
widthinteger
-9007199254740991–9007199254740991
heightinteger
-9007199254740991–9007199254740991
editedAtstring
date-time
createdAtstringrequired
date-time
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
DELETE /api/v1/workspaces/{workspaceId}/messages/{messageId}

Delete a message

Delete a message you previously sent via API.

Scope messages:write

Path parameters

messageIdstringrequired

Message ID (prefixed ULID)

Status codes

  • 204 No content
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Conversations

Browse first-class conversations — topic-level groupings of messages under a root stream and its threads

GET /api/v1/workspaces/{workspaceId}/conversations

List conversations

Cursor-paginated conversation feed across accessible streams, newest activity first. Filter with `streamId` (scopes to that stream's root and its threads) and `status`.

Scope messages:read

Query parameters

streamIdstring
statusstring
one of: active, stalled, resolved
afterstring
limitinteger
1–100 · default 50

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired

Anchor stream the conversation lives in (may be a thread)

rootStreamIdstringrequired

Effective root of the anchor — the stream whose access governs the conversation

topicSummarystring | nullrequired
summarystring | nullrequired
statusstringrequired
one of: active, stalled, resolved
messageCountintegerrequired
-9007199254740991–9007199254740991

Number of primary member messages

participantIdsstring[]required

Distinct author ids of the member messages

lastActivityAtstringrequired
date-time
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
hasMorebooleanrequired
cursorstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
GET /api/v1/workspaces/{workspaceId}/conversations/{conversationId}

Get a conversation

Scope messages:read

Path parameters

conversationIdstringrequired

Conversation ID (prefixed ULID)

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired

Anchor stream the conversation lives in (may be a thread)

rootStreamIdstringrequired

Effective root of the anchor — the stream whose access governs the conversation

topicSummarystring | nullrequired
summarystring | nullrequired
statusstringrequired
one of: active, stalled, resolved
messageCountintegerrequired
-9007199254740991–9007199254740991

Number of primary member messages

participantIdsstring[]required

Distinct author ids of the member messages

lastActivityAtstringrequired
date-time
createdAtstringrequired
date-time
updatedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
GET /api/v1/workspaces/{workspaceId}/conversations/{conversationId}/messages

List a conversation's messages

The conversation's member messages in chronological order, cursor-paginated. Messages can span the conversation's root stream and its threads; each message carries its own `streamId`.

Scope messages:read

Path parameters

conversationIdstringrequired

Conversation ID (prefixed ULID)

Query parameters

afterstring
limitinteger
1–100 · default 50

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired
sequencestringrequired

Numeric sequence as string

authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorDisplayNamestring
contentstringrequired
replyCountintegerrequired
-9007199254740991–9007199254740991
threadStreamIdstring
clientMessageIdstring
sentViastring

Present when message was sent via API on behalf of a user

metadataobjectrequired

External references attached by the sender. Always present; empty when unset.

attachmentsobject[]
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstring
one of: pending, processing, completed, failed, skipped
widthinteger
-9007199254740991–9007199254740991
heightinteger
-9007199254740991–9007199254740991
editedAtstring
date-time
createdAtstringrequired
date-time
hasMorebooleanrequired
cursorstring | nullrequired
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Memos

Search preserved workspace knowledge and inspect memo provenance

Recipes Find out what was decided, and why →

POST /api/v1/workspaces/{workspaceId}/memos/search

Search memos

Search preserved workspace memos with semantic, exact, or recent-first retrieval.

Scope memos:read

Request body

querystringrequired
default ""
exactboolean
streamsstring[]
memoTypestring[]
knowledgeTypestring[]
tagsstring[]
scopestring
one of: user, stream, workspace
beforestring
date-time
afterstring
date-time
limitintegerrequired
1–100 · default 20

Response 200

dataobject[]required
memoobjectrequired
idstringrequired
workspaceIdstringrequired
memoTypestringrequired
one of: message, conversation
sourceMessageIdstring | nullrequired
sourceConversationIdstring | nullrequired
titlestringrequired
abstractstringrequired
keyPointsstring[]required
sourceMessageIdsstring[]required
participantIdsstring[]required
knowledgeTypestringrequired
one of: decision, learning, procedure, context, reference
tagsstring[]required
parentMemoIdstring | nullrequired
statusstringrequired
versionintegerrequired
-9007199254740991–9007199254740991
revisionReasonstring | nullrequired
authoredByKindstringrequired
one of: pipeline, agent
sourceSessionIdstring | nullrequired
scopestringrequired
one of: user, stream, workspace
scopeUserIdstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired
distancenumberrequired
sourceStreamobject | nullrequired
rootStreamobject | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/memos/{memoId}

Get a memo

Retrieve a memo together with source stream and source message provenance.

Scope memos:read

Path parameters

memoIdstringrequired

Memo ID (prefixed ULID)

Response 200

dataobjectrequired
memoobjectrequired
idstringrequired
workspaceIdstringrequired
memoTypestringrequired
one of: message, conversation
sourceMessageIdstring | nullrequired
sourceConversationIdstring | nullrequired
titlestringrequired
abstractstringrequired
keyPointsstring[]required
sourceMessageIdsstring[]required
participantIdsstring[]required
knowledgeTypestringrequired
one of: decision, learning, procedure, context, reference
tagsstring[]required
parentMemoIdstring | nullrequired
statusstringrequired
versionintegerrequired
-9007199254740991–9007199254740991
revisionReasonstring | nullrequired
authoredByKindstringrequired
one of: pipeline, agent
sourceSessionIdstring | nullrequired
scopestringrequired
one of: user, stream, workspace
scopeUserIdstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired
distancenumberrequired
sourceStreamobject | nullrequired
rootStreamobject | nullrequired
sourceMessagesobject[]required
idstringrequired
streamIdstringrequired
streamNamestringrequired
authorIdstringrequired
authorTypestringrequired
one of: user, persona, system, bot
authorNamestringrequired
contentstringrequired
createdAtstringrequired
date-time
successorMemoIdstring | nullrequired
capturedByPersonaNamestring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Attachments

Search attachments, inspect extracted content, and fetch download URLs

POST /api/v1/workspaces/{workspaceId}/attachments

Upload an attachment

Upload a file as multipart/form-data using field `file`. Include the returned attachment id in message markdown as `attachment:<id>` to attach it to a message.

Scope attachments:write

Response 201

dataobjectrequired
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstringrequired
one of: pending, processing, completed, failed, skipped
createdAtstringrequired
date-time

Status codes

  • 201 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/attachments/search

Search attachments

Search accessible attachments by filename or extracted content. Omit query to browse the most recent attachments.

Scope attachments:read

Request body

querystring
min length 1
streamsstring[]
contentTypesstring[]
limitintegerrequired
1–50 · default 20

Response 200

dataobject[]required
idstringrequired
filenamestringrequired
mimeTypestringrequired
contentTypestring | nullrequired
summarystring | nullrequired
streamIdstring
messageIdstring
createdAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/attachments/{attachmentId}

Get an attachment

Retrieve attachment metadata and extracted content for an accessible attachment.

Scope attachments:read

Path parameters

attachmentIdstringrequired

Attachment ID (prefixed ULID)

Response 200

dataobjectrequired
idstringrequired
filenamestringrequired
mimeTypestringrequired
sizeBytesintegerrequired
-9007199254740991–9007199254740991
processingStatusstringrequired
one of: pending, processing, completed, failed, skipped
createdAtstringrequired
date-time
extractionobject | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
GET /api/v1/workspaces/{workspaceId}/attachments/{attachmentId}/url

Get an attachment download URL

Create a short-lived signed URL for an accessible attachment.

Scope attachments:read

Path parameters

attachmentIdstringrequired

Attachment ID (prefixed ULID)

Response 200

dataobjectrequired
urlstringrequired
uri
expiresInintegerrequired
-9007199254740991–9007199254740991

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Users

List workspace users

GET /api/v1/workspaces/{workspaceId}/users

List workspace users

List users in the workspace with optional text search and cursor pagination.

Scope users:read

Query parameters

querystring
afterstring
limitinteger
1–200 · default 50

Response 200

dataobject[]required
idstringrequired
namestringrequired
slugstringrequired
emailstringrequired
avatarUrlstring
rolestringrequired
hasMorebooleanrequired
cursorstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource

Labels

List, create, edit, archive, join, and apply workspace labels

GET /api/v1/workspaces/{workspaceId}/labels

List labels

The key actor's labels (every label is private to its owner) and their resource assignments.

Scope labels:read

Response 200

dataobjectrequired
labelsobject[]required
idstringrequired
workspaceIdstringrequired
creatorActorTypestringrequired
one of: user, bot
creatorActorIdstringrequired
namestringrequired
slugstringrequired
colorstringrequired
emojistring | nullrequired
descriptionstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired
assignmentsobject[]required
labelIdstringrequired
resourceTypestringrequired
one of: stream, message
resourceIdstringrequired
actorTypestringrequired
one of: user, bot
actorIdstringrequired
workspaceIdstringrequired
assignedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/labels

Create or update a label by name

Find-or-create a label owned by the key actor (a user or a bot), keyed by its name. Posting an existing name returns that label and applies any appearance fields supplied; labels are identified by their text, so this is idempotent.

Scope labels:write

Request body

namestringrequired
min length 1 · max length 100
colorstring
emojistring | null
descriptionstring | null

Response 201

dataobjectrequired
idstringrequired
workspaceIdstringrequired
creatorActorTypestringrequired
one of: user, bot
creatorActorIdstringrequired
namestringrequired
slugstringrequired
colorstringrequired
emojistring | nullrequired
descriptionstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired

Status codes

  • 201 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/labels/assignments

Apply a label to a resource by name

Attach a label to a resource the key actor can reach, identifying the label by its text: the label is found-or-created for the actor, then assigned. `resourceType` is the polymorphic target (`stream` today) so the same endpoint labels any future resource without a wire change.

Scope labels:write

Request body

namestringrequired
min length 1 · max length 100
colorstring
emojistring | null
descriptionstring | null
resourceTypestringrequired
one of: stream, message
resourceIdstringrequired
min length 1 · max length 64

Response 201

dataobjectrequired
labelobjectrequired
idstringrequired
workspaceIdstringrequired
creatorActorTypestringrequired
one of: user, bot
creatorActorIdstringrequired
namestringrequired
slugstringrequired
colorstringrequired
emojistring | nullrequired
descriptionstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired
assignmentobjectrequired
labelIdstringrequired
resourceTypestringrequired
one of: stream, message
resourceIdstringrequired
actorTypestringrequired
one of: user, bot
actorIdstringrequired
workspaceIdstringrequired
assignedAtstringrequired
date-time

Status codes

  • 201 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
DELETE /api/v1/workspaces/{workspaceId}/labels/assignments

Remove a label from a resource by name

Remove the key actor's assignment of a label (identified by its text) from a resource.

Scope labels:write

Query parameters

namestringrequired
min length 1 · max length 100
resourceTypestringrequired
one of: stream, message
resourceIdstringrequired
min length 1 · max length 64

Status codes

  • 204 No content
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
PATCH /api/v1/workspaces/{workspaceId}/labels/{labelId}

Update a label

Update a label the key actor created.

Scope labels:write

Path parameters

labelIdstringrequired

Label ID (prefixed ULID)

Request body

namestring
min length 1 · max length 100
colorstring
emojistring | null
descriptionstring | null

Response 200

dataobjectrequired
idstringrequired
workspaceIdstringrequired
creatorActorTypestringrequired
one of: user, bot
creatorActorIdstringrequired
namestringrequired
slugstringrequired
colorstringrequired
emojistring | nullrequired
descriptionstring | nullrequired
createdAtstringrequired
date-time
updatedAtstringrequired
date-time
archivedAtstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
DELETE /api/v1/workspaces/{workspaceId}/labels/{labelId}

Delete a label

Archive a label the key actor created and remove its assignments.

Scope labels:write

Path parameters

labelIdstringrequired

Label ID (prefixed ULID)

Status codes

  • 204 No content
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Bot runtimes

Register a runtime and keep its presence alive so it can be assigned work.

Recipes Connect your local agent →

POST /api/v1/workspaces/{workspaceId}/bot-runtime/presence

Heartbeat bot runtime presence

Scope bot-runtime:write

Request body

runtimeKindstringrequired
one of: pi-local, hermes, openclaw, claude-code-channel, custom
instanceIdstringrequired
min length 1 · max length 128
runtimeSessionIdstring
min length 1 · max length 256
displayNamestring
max length 100
statusstringrequired
one of: available, busy, offline, error
acceptingInvocationsbooleanrequired
capabilitiesobjectrequired
default {}
statusTextstring
max length 200
publicKeystring
min length 44 · max length 44
publicKeyIdstring
min length 1 · max length 128

Response 200

dataobjectrequired
idstringrequired
workspaceIdstringrequired
botIdstringrequired
runtimeKindstringrequired
one of: pi-local, hermes, openclaw, claude-code-channel, custom
instanceIdstringrequired
displayNamestring | nullrequired
statusstringrequired
one of: available, busy, offline, error
acceptingInvocationsbooleanrequired
capabilitiesobjectrequired
statusTextstring | nullrequired
lastSeenAtstringrequired
date-time
createdAtstringrequired
date-time
updatedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/bot-runtime/sessions

Create or link a bot runtime session

Scope bot-runtime:write

Request body

runtimeKindstringrequired
one of: pi-local, claude-code-channel
instanceIdstringrequired
min length 1 · max length 128
runtimeSessionIdstringrequired
min length 1 · max length 256
displayNamestringrequired
min length 1 · max length 100
localCwdstring
max length 1000
memoryModestring
one of: auto, off
labelNamestring
min length 1 · max length 100
descriptionstring
max length 10000
e2eobject
ownerKeyIdstringrequired
min length 1 · max length 128
ifArchivedstring
one of: wait, replace
ifMissingstring
one of: create, error

Response 200

dataobjectrequired
linkIdstringrequired
rootStreamIdstringrequired
activeStreamIdstringrequired
runtimeSessionIdstringrequired
streamUrlPathstringrequired
e2eEnabledboolean

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
GET /api/v1/workspaces/{workspaceId}/bot-runtime/owner-e2e-key

Get the bot owner's active encryption public key

The bot owner's active UIK (key id + base64 X25519 public key). A sealed harness fetches this before creating an end-to-end-encrypted session so it can wrap the generation-0 stream key to the owner. 404 when the owner has not set up encryption.

Scope bot-runtime:write

Response 200

dataobjectrequired
keyIdstringrequired
publicKeystringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/streams/{streamId}/e2e/key-wraps

Provision the generation-0 key wraps for a harness-created encrypted scratchpad

Phase two of harness-created E2E scratchpads: stores the stream-key wraps (owner UIK + the harness's own BIK) minted against the stream id returned by session create. Bot-actor-only, current generation only, and only while the generation has no wraps. Slots are immutable, so a replay cannot splice keys.

Scope bot-runtime:write

Path parameters

streamIdstringrequired

Stream ID

Request body

keyGenerationintegerrequired
0–9007199254740991
wrapsobject[]required
recipientKindstringrequired
one of: user, bot
recipientKeyIdstringrequired
min length 1 · max length 128
wrapEncstringrequired
base64 · min length 1
wrapCtstringrequired
base64 · min length 1

Response 200

dataobjectrequired
storedintegerrequired
-9007199254740991–9007199254740991

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-runtime/sessions/rename

Rename the scratchpad linked to a bot runtime session

Scope bot-runtime:write

Request body

instanceIdstringrequired
min length 1 · max length 128
runtimeSessionIdstringrequired
min length 1 · max length 256
displayNamestringrequired
min length 1 · max length 100

Response 200

dataobjectrequired
linkIdstringrequired
rootStreamIdstringrequired
activeStreamIdstringrequired
runtimeSessionIdstringrequired
streamUrlPathstringrequired
e2eEnabledboolean
displayNamestringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-runtime/sessions/rebind

Move an existing bot runtime session link to a new runtime instance id

Scope bot-runtime:write

Request body

linkIdstringrequired
min length 1 · max length 128
instanceIdstringrequired
min length 1 · max length 128
runtimeSessionIdstringrequired
min length 1 · max length 256
newInstanceIdstringrequired
min length 1 · max length 128

Response 200

dataobjectrequired
linkIdstringrequired
rootStreamIdstringrequired
activeStreamIdstringrequired
runtimeSessionIdstringrequired
streamUrlPathstringrequired
e2eEnabledboolean

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Bot invocations

Claim, renew, step through, complete, or fail the work a bot is summoned to do.

Recipes Connect your local agent →

POST /api/v1/workspaces/{workspaceId}/bot-invocations/claim

Claim one pending bot invocation

Scope bot-invocations:write

Request body

runtimeKindstringrequired
one of: pi-local, hermes, openclaw, claude-code-channel, custom
instanceIdstringrequired
min length 1 · max length 128
runtimeSessionIdstring
min length 1 · max length 256
supportedCapabilitiesstring[]required
claimTtlSecondsintegerrequired
15–300 · default 60
responseStreamIdstring
min length 1 · max length 64

Response 200

dataobject | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/renew

Renew a claimed bot invocation

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

instanceIdstringrequired
min length 1 · max length 128
claimTokenstringrequired
min length 1 · max length 256
claimTtlSecondsintegerrequired
15–300 · default 60

Response 200

dataobjectrequired
invocationIdstringrequired
statusstringrequired
claimExpiresAtstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/steps

Record a bot invocation trace step

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

instanceIdstringrequired
min length 1 · max length 128
claimTokenstringrequired
min length 1 · max length 256
stepTypestringrequired
one of: context_received, thinking, reconsidering, steer, web_search, visit_page, workspace_search, research, github_access, linear_access, message_sent, message_edited, response, tool_call, tool_error, rate_limited, rate_limit_retry, turn_digest, model_escalated
contentstringrequired
min length 1 · max length 10000
statusTextstring
max length 200
clientStepIdstring
min length 1 · max length 128

Response 200

dataobjectrequired
invocationIdstringrequired
sessionIdstringrequired
stepIdstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/sealed-steps/started

Open an in-flight sealed bot invocation trace step

Sealed variant of the trace-step start, for an owner-granted E2E bot harness: the content is ciphertext the server never decrypts. Authenticated with the per-claim callback token in the X-Threa-Callback-Token header.

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

stepIdstringrequired
min length 1 · max length 128
stepTypestringrequired
one of: context_received, thinking, reconsidering, steer, web_search, visit_page, workspace_search, research, github_access, linear_access, message_sent, message_edited, response, tool_call, tool_error, rate_limited, rate_limit_retry, turn_digest, model_escalated
messageIdstring
min length 1 · max length 128
ciphertextstring
base64 · min length 1
envelopeobject
vnumberrequired
keyGenerationintegerrequired
0–9007199254740991
ivstringrequired
base64 · min length 1
aadstringrequired
base64 · min length 1

Response 200

dataobjectrequired
invocationIdstringrequired
sessionIdstringrequired
stepIdstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/sealed-steps

Finalize a sealed bot invocation trace step

Sealed variant of the trace-step finalize, for an owner-granted E2E bot harness: sets the sealed content + completion on the step opened at sealed-steps/started (or inserts a completed row if the start was dropped). Authenticated with the per-claim callback token in the X-Threa-Callback-Token header.

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

stepIdstringrequired
min length 1 · max length 128
stepTypestringrequired
one of: context_received, thinking, reconsidering, steer, web_search, visit_page, workspace_search, research, github_access, linear_access, message_sent, message_edited, response, tool_call, tool_error, rate_limited, rate_limit_retry, turn_digest, model_escalated
messageIdstring
min length 1 · max length 128
ciphertextstringrequired
base64 · min length 1
envelopeobjectrequired
vnumberrequired
keyGenerationintegerrequired
0–9007199254740991
ivstringrequired
base64 · min length 1
aadstringrequired
base64 · min length 1
durationMsinteger
0–9007199254740991

Response 200

dataobjectrequired
invocationIdstringrequired
sessionIdstringrequired
stepIdstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/sealed-messages

Post a sealed interim message from an in-flight sealed bot invocation

Sealed variant of a mid-turn bot message, for an owner-granted E2E bot harness: posts one sealed interim message (ciphertext the server never decrypts) into the claim's stream before the turn completes: progress notes, permission prompts, early acks. The client-minted messageId binds the seal AAD and dedupes retries. Authenticated with the per-claim callback token in the X-Threa-Callback-Token header.

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

messageIdstringrequired
min length 1 · max length 128
ciphertextstringrequired
base64 · min length 1
envelopeobjectrequired
vnumberrequired
keyGenerationintegerrequired
0–9007199254740991
ivstringrequired
base64 · min length 1
aadstringrequired
base64 · min length 1
attachmentIdsstring[]

Response 200

dataobjectrequired
messageIdstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/sealed-complete

Complete a sealed bot invocation

Sealed variant of the completion, for an owner-granted E2E bot harness: persists the turn's final sealed reply (ciphertext the server never decrypts) or noResponse, flips the claim, and finalizes the agent session. Authenticated with the per-claim callback token in the X-Threa-Callback-Token header.

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

replyobject
messageIdstringrequired
min length 1 · max length 128
ciphertextstringrequired
base64 · min length 1
envelopeobjectrequired
vnumberrequired
keyGenerationintegerrequired
0–9007199254740991
ivstringrequired
base64 · min length 1
aadstringrequired
base64 · min length 1
attachmentIdsstring[]
noResponseboolean

Response 200

dataobjectrequired
invocationIdstringrequired
sessionIdstringrequired
messageIdstring | nullrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/complete

Complete a claimed bot invocation

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

instanceIdstringrequired
min length 1 · max length 128
claimTokenstringrequired
min length 1 · max length 256
finalMessageMarkdownstring
min length 1 · max length 50000
noResponseboolean
sourcesobject[]
typestring
one of: web, workspace, github
titlestringrequired
min length 1 · max length 500
urlstringrequired
min length 1 · max length 2000
snippetstring
max length 2000
metadataobject
sealedReplyobject
messageIdstringrequired
min length 1 · max length 128
ciphertextstringrequired
base64 · min length 1
envelopeobjectrequired
vnumberrequired
keyGenerationintegerrequired
0–9007199254740991
ivstringrequired
base64 · min length 1
aadstringrequired
base64 · min length 1

Response 200

dataobjectrequired
invocationIdstringrequired
messageobject | nullrequired
slotsobjectrequired

Hydration for cross-stream shared-message pointers in the returned messages, keyed by `shared:<messageId>`. Always present; empty when no message references a shared source.

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/bot-invocations/{invocationId}/fail

Fail a claimed bot invocation

Scope bot-invocations:write

Path parameters

invocationIdstringrequired

Invocation ID

Request body

instanceIdstringrequired
min length 1 · max length 128
claimTokenstringrequired
min length 1 · max length 256
errorMessagestringrequired
min length 1 · max length 1000

Response 200

dataobjectrequired
invocationIdstringrequired
statusstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found

Delegations

Close the loop on delegated tasks: your local agent lists the open queue, claims a task, reports progress, and completes it with a result posted back to the stream.

GET /api/v1/workspaces/{workspaceId}/delegations

List open delegations

List delegated tasks that are open to claim, filtered to what the key can access: a user-scoped key sees streams its user can access, a workspace key sees the bot's channel grants.

Scope delegations:read

Query parameters

statusstring
default "open"
sincestring
date-time

Response 200

dataobject[]required
idstringrequired
streamIdstringrequired
titlestringrequired
statusstringrequired
one of: open, claimed, running, completed, failed, cancelled, expired
claimedByLabelstring
statusNotestring
resultMessageIdstring
sourceConversationIdstring
createdAtstringrequired
date-time
statusChangedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/claim

Claim an open delegation

Atomically claim an open delegation. Returns the brief, context refs, and the claim token (cleartext, exactly once; send it as X-Threa-Callback-Token on every later lifecycle call). A delegation that is no longer open returns 409.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Request body

claimedByLabelstringrequired
min length 1 · max length 200
idempotencyKeystring
min length 8 · max length 128

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired
titlestringrequired
statusstringrequired
one of: open, claimed, running, completed, failed, cancelled, expired
claimedByLabelstring
statusNotestring
resultMessageIdstring
sourceConversationIdstring
createdAtstringrequired
date-time
statusChangedAtstringrequired
date-time
briefstringrequired
contextRefsstring[]required
claimTokenstringrequired
claimExpiresAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
  • 409 Conflict: the resource is not in the state the operation requires
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/heartbeat

Renew a delegation claim

Push the claim's expiry forward while the local agent is still working. Liveness only; no status change on the card. Authenticated with the per-claim token in the X-Threa-Callback-Token header.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Response 200

dataobjectrequired
claimExpiresAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/status

Report delegation progress

Mark the delegation running and put a free-text progress note on its card (each report replaces the previous note; the claim TTL renews). Authenticated with the per-claim token in the X-Threa-Callback-Token header.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Request body

statusNotestring
min length 1 · max length 2000

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired
titlestringrequired
statusstringrequired
one of: open, claimed, running, completed, failed, cancelled, expired
claimedByLabelstring
statusNotestring
resultMessageIdstring
sourceConversationIdstring
createdAtstringrequired
date-time
statusChangedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/complete

Complete a delegation

Complete the claimed delegation. When resultMarkdown is given, the result is posted in a thread anchored on the delegation card in the same transaction as the completion, authored as the key's user (with via-API provenance) for a user-scoped key, or as the bot for a workspace key. The response includes resultMessageId and resultThreadId. It enters the normal message pipeline, so workspace memory captures the outcome. Authenticated with the per-claim token in the X-Threa-Callback-Token header.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Request body

resultMarkdownstring
min length 1 · max length 50000
metadataobject

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired
titlestringrequired
statusstringrequired
one of: open, claimed, running, completed, failed, cancelled, expired
claimedByLabelstring
statusNotestring
resultMessageIdstring
sourceConversationIdstring
createdAtstringrequired
date-time
statusChangedAtstringrequired
date-time
resultThreadIdstring

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/fail

Fail a delegation

Mark the claimed delegation failed, recording why on its card. Authenticated with the per-claim token in the X-Threa-Callback-Token header.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Request body

errorMessagestringrequired
min length 1 · max length 2000

Response 200

dataobjectrequired
idstringrequired
streamIdstringrequired
titlestringrequired
statusstringrequired
one of: open, claimed, running, completed, failed, cancelled, expired
claimedByLabelstring
statusNotestring
resultMessageIdstring
sourceConversationIdstring
createdAtstringrequired
date-time
statusChangedAtstringrequired
date-time

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found
POST /api/v1/workspaces/{workspaceId}/delegations/{delegationId}/request-access

Request access to a delegation's stream

For a workspace (bot) key that received the delegation:available nudge but cannot claim it (no channel grant): file an access request that renders as a card in the delegation's stream for a member to approve or deny. Returns already_granted (no card) when the bot already has access; otherwise the request is idempotent per (bot, stream). 404 for an unknown delegation id — the existence-hiding carve-out is scoped to ids the workspace bot plane already saw on the nudge. A user-scoped key gets 400 (USER_KEY_CANNOT_REQUEST_ACCESS): a user key's access follows its user, who should join the stream directly.

Scope delegations:write

Path parameters

delegationIdstringrequired

Delegation ID (prefixed ULID)

Request body

requestedByLabelstring
max length 200

Response 200

dataobjectrequired
requestIdstring
statusstringrequired

Status codes

  • 200 Successful response
  • 400 Validation error
  • 401 Missing or invalid API key
  • 403 Insufficient permissions or inaccessible resource
  • 404 Resource not found