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, versioned under /api/v1 and scoped to a workspace: /api/v1/workspaces/{workspaceId}/…. 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 — either the API-key owner (`kind: "user"`) or the bot whose key is in use (`kind: "bot"`). Used by clients (e.g. the OpenClaw channel plugin) to verify their key and discover their identity after pairing.

Scope none — any valid key

Example

GET /me
curl "/api/v1/workspaces/{workspaceId}/me" \
  -H "Authorization: Bearer "

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

Example

GET /me/bots
curl "/api/v1/workspaces/{workspaceId}/me/bots" \
  -H "Authorization: Bearer "

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)

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
limitintegerrequired
1–200 · default 50

Example

GET /streams
curl "/api/v1/workspaces/{workspaceId}/streams?type=channel&limit=20" \
  -H "Authorization: Bearer "

Response 200

dataobject[]required
idstringrequired
typestringrequired
one of: scratchpad, channel, dm, thread, system
displayNamestringrequired
slugstring
descriptionstring
visibilitystringrequired
parentStreamIdstring
rootStreamIdstring
parentMessageIdstring
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)

Example

GET /streams/{streamId}
curl "/api/v1/workspaces//streams/STREAM_ID" \
  -H "Authorization: Bearer "

Response 200

dataobjectrequired
idstringrequired
typestringrequired
one of: scratchpad, channel, dm, thread, system
displayNamestringrequired
slugstring
descriptionstring
visibilitystringrequired
parentStreamIdstring
rootStreamIdstring
parentMessageIdstring
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
limitintegerrequired
1–200 · default 50

Example

GET /streams/{streamId}/members
curl "/api/v1/workspaces//streams/STREAM_ID/members?limit=50" \
  -H "Authorization: Bearer "

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

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

Example

POST /messages/search
curl -X POST /api/v1/workspaces/{workspaceId}/messages/search \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "query": "auth",
  "semantic": true,
  "exact": false,
  "limit": 5
}'

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

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
limitintegerrequired
1–100 · default 50

Example

GET /streams/{streamId}/messages
curl "/api/v1/workspaces//streams/STREAM_ID/messages?limit=50" \
  -H "Authorization: Bearer "

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

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.

Scope messages:write

Path parameters

streamIdstringrequired

Stream ID (prefixed ULID)

Request body

contentstringrequired
min length 1
clientMessageIdstring
max length 128
metadataobject

Example

POST /streams/{streamId}/messages
curl -X POST /api/v1/workspaces//streams/STREAM_ID/messages \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "content": "string"
}'

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

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

Example

POST /messages/find-by-metadata
curl -X POST /api/v1/workspaces//messages/find-by-metadata \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "metadata": {},
  "limit": 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

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

Example

PATCH /messages/{messageId}
curl -X PATCH /api/v1/workspaces//messages/MESSAGE_ID \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "content": "string"
}'

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

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)

Example

DELETE /messages/{messageId}
curl -X DELETE /api/v1/workspaces//messages/MESSAGE_ID \
  -H "Authorization: Bearer "

Status codes

  • 204 No content
  • 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

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[]
beforestring
date-time
afterstring
date-time
limitintegerrequired
1–100 · default 20

Example

POST /memos/search
curl -X POST /api/v1/workspaces/{workspaceId}/memos/search \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "query": "auth",
  "limit": 5
}'

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
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)

Example

GET /memos/{memoId}
curl "/api/v1/workspaces//memos/MEMO_ID" \
  -H "Authorization: Bearer "

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
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

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

Example

POST /attachments
curl -X POST /api/v1/workspaces//attachments \
  -H "Authorization: Bearer "

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.

Scope attachments:read

Request body

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

Example

POST /attachments/search
curl -X POST /api/v1/workspaces/{workspaceId}/attachments/search \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "query": "auth",
  "limit": 5
}'

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)

Example

GET /attachments/{attachmentId}
curl "/api/v1/workspaces//attachments/ATTACHMENT_ID" \
  -H "Authorization: Bearer "

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)

Example

GET /attachments/{attachmentId}/url
curl "/api/v1/workspaces//attachments/ATTACHMENT_ID/url" \
  -H "Authorization: Bearer "

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
limitintegerrequired
1–200 · default 50

Example

GET /users
curl "/api/v1/workspaces/{workspaceId}/users?limit=20" \
  -H "Authorization: Bearer "

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

Bot runtimes

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

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

Example

POST /bot-runtime/presence
curl -X POST /api/v1/workspaces//bot-runtime/presence \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "runtimeKind": "pi-local",
  "instanceId": "string",
  "status": "available",
  "acceptingInvocations": false,
  "capabilities": {}
}'

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
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

Example

POST /bot-runtime/sessions
curl -X POST /api/v1/workspaces//bot-runtime/sessions \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "runtimeKind": "string",
  "instanceId": "string",
  "runtimeSessionId": "string",
  "displayName": "string"
}'

Response 200

dataobjectrequired
linkIdstringrequired
rootStreamIdstringrequired
activeStreamIdstringrequired
runtimeSessionIdstringrequired
streamUrlPathstringrequired

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/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

Example

POST /bot-runtime/sessions/rename
curl -X POST /api/v1/workspaces//bot-runtime/sessions/rename \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "instanceId": "string",
  "runtimeSessionId": "string",
  "displayName": "string"
}'

Response 200

dataobjectrequired
linkIdstringrequired
rootStreamIdstringrequired
activeStreamIdstringrequired
runtimeSessionIdstringrequired
streamUrlPathstringrequired
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

Bot invocations

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

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

Example

POST /bot-invocations/claim
curl -X POST /api/v1/workspaces//bot-invocations/claim \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "runtimeKind": "pi-local",
  "instanceId": "string",
  "supportedCapabilities": [
    "mentionable"
  ],
  "claimTtlSeconds": 60
}'

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

Example

POST /bot-invocations/{invocationId}/renew
curl -X POST /api/v1/workspaces//bot-invocations/INVOCATION_ID/renew \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "instanceId": "string",
  "claimToken": "string",
  "claimTtlSeconds": 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, 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
contentstringrequired
min length 1 · max length 10000
statusTextstring
max length 200

Example

POST /bot-invocations/{invocationId}/steps
curl -X POST /api/v1/workspaces//bot-invocations/INVOCATION_ID/steps \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "instanceId": "string",
  "claimToken": "string",
  "stepType": "context_received",
  "content": "string"
}'

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}/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
metadataobject

Example

POST /bot-invocations/{invocationId}/complete
curl -X POST /api/v1/workspaces//bot-invocations/INVOCATION_ID/complete \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "instanceId": "string",
  "claimToken": "string"
}'

Response 200

dataobjectrequired
invocationIdstringrequired
messageobject | 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}/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

Example

POST /bot-invocations/{invocationId}/fail
curl -X POST /api/v1/workspaces//bot-invocations/INVOCATION_ID/fail \
  -H "Authorization: Bearer " \
  -H "Content-Type: application/json" \
  -d '{
  "instanceId": "string",
  "claimToken": "string",
  "errorMessage": "string"
}'

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