Mosoo API for coding agents
Machine-oriented guide for calling published Mosoo Agents through the public API.
Mosoo API for coding agents
Use this document when integrating an existing, published Mosoo Agent into application code through the public API.
Integration scope
This document only covers API calls between application code and an existing Mosoo Agent: sending inputs, attaching files, reading outputs, and handling public API errors.
It does not cover:
- Creating, configuring, or publishing Agents.
- Managing Mosoo Apps.
- Managing Agent lifecycle, versions, readiness, runtime settings, model providers, tools, or channels.
- Any other Mosoo product surface outside the public API used to pass input to an Agent and read output from it.
This document is also not the source for secrets or live resource IDs. Do not invent API tokens, agentId, threadId, fileId, or runId values. Use values supplied by the user, environment variables, Mosoo UI, or Mosoo CLI when available.
This document is not a replacement for the raw OpenAPI document when generating clients or validating every schema detail. Use the raw OpenAPI for code generation and strict schema validation.
Integration model
Mosoo is the Agent runtime. The published Agent runs inside a Mosoo-managed sandbox, and your application backend and product code should call that sandboxed Agent through the public API.
Build the app-side integration layer around Mosoo Threads, events, files, and public error handling. Your application can still own backend APIs, jobs, business logic, user flows, and data storage around the sandboxed Agent. For a Mosoo Agent integration, do not implement a parallel Agent layer, sandbox, model loop, planner, tool runner, memory system, lifecycle manager, or provider integration in your application.
Primary contract:
- Human docs:
/docs,/docs/quickstart,/docs/auth-and-access,/docs/agent-api-endpoints,/docs/threads-and-runs,/docs/events-and-streaming,/docs/files,/docs/errors-and-limits - Raw OpenAPI:
/docs/openapi/mosoo-openapi.en.generated.json - API version:
v1 - Base URL used in examples:
https://try.mosoo.ai/api/v1
Do not infer request fields that are not listed here or in the raw OpenAPI. The public API rejects unsupported fields.
What Mosoo exposes
Mosoo exposes published Agents through Thread-based HTTP APIs. If required credentials or resource IDs are missing, get them from the environment, the user, Mosoo UI, or Mosoo CLI when it is available. Do not guess or synthesize Mosoo IDs.
| Concept | Meaning for callers |
|---|---|
| Agent | A configured Mosoo Agent. It must be published and have API access enabled before the API can call it. |
agentId | The published Agent ID shown in the Agent API Access panel |
| API token | Bearer credential used by your code. It authenticates the Mosoo account that owns the Agent API Endpoint App and public Thread resources. |
| Thread | The API conversation container. It records messages, files, run status, and public event history. |
| Run | One execution pass of the Agent on a Thread. A user message can create or resume a Run. |
| Event | A public timeline entry for Thread inputs, Agent output deltas, tool updates, file changes, status changes, and usage updates. |
| File | A Thread attachment uploaded by the caller or an Agent artifact produced during execution. |
Resource IDs in v1 are bare ULIDs, not prefixed IDs.
Authentication and access
All API requests require an API token:
Authorization: Bearer mst_...JSON requests also require:
Content-Type: application/jsonA valid request must pass all of these checks:
- The Agent exists.
- The Agent is published and has API access enabled.
- The API token is valid and not revoked.
- The Agent has a live API endpoint version.
- The API token owner owns the App that owns the Agent.
- The requested Thread or file is visible to the API token owner.
The API token does not switch users, create a multi-user access context, or let a request override model provider, channel, tool, or runtime settings. Configure and publish the Agent in Mosoo before calling the API.
Responsibility boundary
| Your application owns | Mosoo owns |
|---|---|
App UI, app routing, app backend APIs, jobs, app-side users, business logic, data storage, thread.id persistence, and caller-owned correlation IDs such as client_external_ref or clientRequestId. | Sandboxed published Agent execution, model/provider configuration, tool execution, Agent runtime behavior, Agent memory/runtime state, and public event generation. |
Quick start workflow
Use this workflow when implementing the quickstart in application code. It is based on the human quickstart, but it starts after the Agent already exists, is published, and has API access enabled.
| Step | Call | Persist or read | Stop condition |
|---|---|---|---|
| 1. Load credentials | No API call. Read MOSOO_API_TOKEN and MOSOO_AGENT_ID from the user, environment, Mosoo UI, or Mosoo CLI. | Keep the token in secret storage. Keep agentId as configuration. | Missing token or agentId; do not invent either value. |
| 2. Create a Thread | POST /agents/{agentId}/threads with the first user input. | Persist thread.id. Optionally persist client_external_ref for your app record. | A Thread exists and the first Run has been queued. |
| 3. Continue the Thread | POST /threads/{threadId}/events with user_message, permission_decision, or user_interrupt events. | Persist caller-owned references such as clientRequestId if your app needs correlation. | The follow-up input has been accepted by the API. |
| 4. Read output | GET /threads/{threadId}/events for the event log, or GET /threads/{threadId}/events/stream for streaming. | Read public Agent output, run status, usage updates, tool status, and file events from events. | The app has enough public events to render the Agent response or current status. |
| 5. Attach files if needed | Upload with POST /agents/{agentId}/files, then mount the returned file through resources. | Persist returned file.id when the app needs to reference or remove the file later. | The file is mounted into the first or later message that depends on it. |
Implementation rules:
- Build the app-side integration layer around the published Mosoo Agent running in Mosoo's sandbox; do not implement a local Agent runtime or replacement sandbox.
- Do not call model providers directly for this Mosoo Agent integration.
- Do not send provider credentials, model configuration, channel credentials, tool configuration, or Agent configuration through this public API.
- Use
Idempotency-Keyfor Thread creation and event submission. - Treat Thread events as the integration contract and
GET /threads/{threadId}/eventsas the stable source for results. - Keep Agent creation, App management, and Agent lifecycle operations outside this workflow.
- On failure, branch on
error.codeand follow the error handling table below.
Minimal call sequence
Set credentials:
export MOSOO_API_TOKEN="mst_..."
export MOSOO_AGENT_ID="01J00000000000000000000001"Create a Thread and queue the initial Run:
curl -X POST "https://try.mosoo.ai/api/v1/agents/$MOSOO_AGENT_ID/threads" \
-H "Authorization: Bearer $MOSOO_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-182-create-thread" \
-d '{
"client_external_ref": "ticket-182",
"input": {
"type": "user.message",
"content": [
{
"type": "text",
"text": "Triage this customer escalation and suggest next steps."
}
]
}
}'Store thread.id:
export MOSOO_THREAD_ID="01J00000000000000000000002"Send a follow-up message:
curl -X POST "https://try.mosoo.ai/api/v1/threads/$MOSOO_THREAD_ID/events" \
-H "Authorization: Bearer $MOSOO_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-182-follow-up-1" \
-d '{
"events": [
{
"type": "user_message",
"clientRequestId": "ticket-182-message-1",
"text": "Give me the three highest-priority next actions."
}
]
}'Read the public event log:
curl "https://try.mosoo.ai/api/v1/threads/$MOSOO_THREAD_ID/events?limit=100" \
-H "Authorization: Bearer $MOSOO_API_TOKEN"File upload flow
Use this flow when a Thread or user message needs a file attachment. Uploads are scoped to the Agent API Endpoint App, so the file can be uploaded before the Thread exists. Public uploads use multipart/form-data and accept files up to 67108864 bytes.
Upload the file:
printf 'Customer asks for an implementation plan.' > brief.txt
curl -X POST "https://try.mosoo.ai/api/v1/agents/$MOSOO_AGENT_ID/files" \
-H "Authorization: Bearer $MOSOO_API_TOKEN" \
-F "file=@brief.txt;type=text/plain"The response is a PublicFileResponse. Store file.id.
export MOSOO_FILE_ID="01J0000000000000000000000J"Use the file in the first user message by adding top-level resources to the create-Thread request:
curl -X POST "https://try.mosoo.ai/api/v1/agents/$MOSOO_AGENT_ID/threads" \
-H "Authorization: Bearer $MOSOO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_external_ref": "ticket-182",
"resources": [
{
"type": "file",
"file_id": "01J0000000000000000000000J"
}
],
"input": {
"type": "user.message",
"content": [
{
"type": "text",
"text": "Summarize the attached file."
}
]
}
}'Use the file in a later user message with event-level resources:
curl -X POST "https://try.mosoo.ai/api/v1/threads/$MOSOO_THREAD_ID/events" \
-H "Authorization: Bearer $MOSOO_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ticket-182-file-question-1" \
-d '{
"events": [
{
"type": "user_message",
"resources": [
{
"type": "file",
"file_id": "01J0000000000000000000000J"
}
],
"text": "Summarize the attached file."
}
]
}'After a file is mounted into a Thread, GET /threads/{threadId}/files lists it and GET /files/{fileId}/content downloads its bytes when visible to the API token caller.
Idempotency
Idempotency-Key is supported on:
POST /agents/{agentId}/threadsPOST /threads/{threadId}/events
Rules:
- The key is scoped to the API token, method, route, and request body.
- Reusing the same key with the same request replays the stored response.
- Reusing the same key with a different request returns
409 idempotency_conflict. - Reusing the key while the first request is still processing returns
409 idempotency_conflict. - Keys must be non-empty and 128 characters or fewer.
- Conflict responses can include
Retry-After.
Generate stable keys from your own operation IDs, such as ticket-182-create-thread or job-2026-06-23-run-1-message-3.
Reading results
The stable read surface is the Thread event log.
Use GET /threads/{threadId}/events for polling and snapshots. Use GET /threads/{threadId}/events/stream for long-running consumer UX.
Do not expect event APIs to expose raw runtime payloads, private transcripts, or internal diagnostics. Each event entry has public fields:
| Field | Meaning |
|---|---|
id | Event ID, bare ULID, monotonically increasing in chronological order. |
type | Public event type such as run.started, agent.message.delta, tool.use.started, or usage.updated. |
status | available, error, or unsupported. |
content | Public event content or a reference to the associated payload. |
occurredAt | RFC 3339 timestamp. |
durationMs | Duration in milliseconds when applicable, otherwise null. |
tokens | Token count when applicable, otherwise null. |
Important event types:
user.messageagent.message.deltaagent.thinking.deltatool.confirmation.requiredtool.use.startedtool.use.completedfile.changedsession_files.updatedrun.startedrun.completedrun.failedsession.statususage.updated
Status values
Thread status:
| Status | Meaning |
|---|---|
IDLE | No active Run. A user message can queue work. |
RUNNING | A Run is executing. |
RESCHEDULING | The Thread is between runs. |
TERMINATED | The Thread has ended. |
Run status:
| Status | Meaning |
|---|---|
queued | Run exists but has not started. |
booting | Runtime is preparing. |
running | Run is executing. |
waiting_input | Run is blocked on caller/user input, often permission decision. |
completed | Terminal success. |
failed | Terminal failure. |
cancelled | Terminal cancellation. |
expired | Terminal timeout or expiry. |
Error handling
All non-2xx public API JSON errors use this envelope:
{
"error": {
"code": "invalid_request",
"message": "Request body must be an object."
}
}Branch on error.code, not error.message. The message is for developers and should not be displayed directly to end users.
| HTTP | error.code | Meaning | Caller action |
|---|---|---|---|
| 400 | invalid_request | Request shape, field value, body size, limit, or unsupported field is invalid. | Fix the request. Do not retry unchanged. |
| 400 | invalid_json | Body is not valid JSON. | Fix serialization or Content-Type. Do not retry unchanged. |
| 401 | unauthenticated | Missing, invalid, or revoked API token. | Re-read Authorization; rotate or recreate the API token. |
| 403 | forbidden | API token is valid but the operation is not allowed for this Agent, Thread, or file. | Check that the request uses the expected token and a resource from the same Mosoo workspace. |
| 404 | not_found | Agent, Thread, or file is not visible in the current Mosoo workspace or does not exist. | Check the ID and use resource IDs returned by the API. |
| 409 | agent_not_published | Agent exists but is not published as an active API service. | Ask the user to publish the Agent and enable API access. |
| 409 | service_inactive | Published API service has no live published version. | Ask the user to republish or repair the Agent in Mosoo. |
| 409 | readiness_blocked | Agent is not ready to run. | Do not blindly retry; ask the user to fix Agent readiness or configuration in Mosoo. |
| 409 | idempotency_conflict | Same Idempotency-Key is processing or was used for a different request. | If still processing, wait for Retry-After; if body differs, use a new key. |
| 429 | rate_limited | API token exceeded public API rate limits. | Back off and retry after Retry-After. |
| 500 | internal_error | Mosoo failed internally. | Retry briefly with backoff; persist failure details if it repeats. |
Retry policy:
- Safe to retry with the same
Idempotency-Key: network timeouts, 5xx from create-thread or send-events, andidempotency_conflictcaused by in-flight processing. - Safe to retry after delay:
rate_limited, usingRetry-After. - Do not retry unchanged:
invalid_request,invalid_json,unauthenticated,forbidden,not_found,agent_not_published,service_inactive,readiness_blocked.
API contract
This section is generated from /docs/openapi/mosoo-openapi.en.generated.json. Do not edit it manually; run npm run openapi:sync.
All endpoints below are relative to /api/v1.
| Method | Path | Purpose |
|---|---|---|
POST | /agents/{agentId}/threads | Create a Thread for an Agent API Endpoint |
GET | /agents/{agentId}/threads | List Threads for an Agent API Endpoint |
GET | /threads/{threadId} | Retrieve Thread summary |
POST | /threads/{threadId}/events | Send user messages, permission decisions, or interrupts to a Thread |
GET | /threads/{threadId}/events | List Thread events |
GET | /threads/{threadId}/events/stream | Stream Thread events |
POST | /agents/{agentId}/files | Upload an Agent file |
GET | /files/{fileId} | Retrieve file metadata |
GET | /threads/{threadId}/files | List Thread files |
GET | /files/{fileId}/content | Download Thread file content |
DELETE | /files/{fileId} | Delete a file |
DELETE | /threads/{threadId}/files/{fileId} | Remove a Thread file |
POST | /threads/{threadId}/archive | Archive a Thread |
POST | /threads/{threadId}/unarchive | Unarchive a Thread |
DELETE | /threads/{threadId} | Delete a Thread |
Common error response envelope:
{
"error": {
"code": "invalid_request",
"message": "Request body must be an object."
}
}POST /agents/{agentId}/threads
Purpose: Creates a Thread and the backing AgentSession. If input is present, Mosoo also queues the initial Run. If input is omitted, the Thread is immediately visible with IDLE status and no run. API token requests are attributed to the current Mosoo user.
Path params:
agentIdrequired,string(ulid). Agent API Endpoint ID from the Agent's API Access panel. v1 IDs are bare ULIDs.
Headers:
Idempotency-Keyoptional,string. Optional key for retry-safe create-thread and send-events calls. Reusing the same key with the same request returns the original response. Reusing the key while the original request is still processing returns 409.
Request body:
application/json:CreateThreadRequest
Example emptyThread:
{
"client_external_ref": "draft-empty-thread"
}Example accessTokenWithFile:
{
"client_external_ref": "linear-ENG-123",
"input": {
"content": [
{
"text": "Summarize the attached launch plan and list follow-ups.",
"type": "text"
}
],
"type": "user.message"
},
"resources": [
{
"file_id": "01J0000000000000000000000J",
"type": "file"
}
]
}Example accessTokenBasic:
{
"client_external_ref": "demo-thread-001",
"input": {
"content": [
{
"text": "Say hello from the API.",
"type": "text"
}
],
"type": "user.message"
}
}Example cattleAgentSameShape:
{
"input": {
"content": [
{
"text": "Run this one-off Public Thread API request.",
"type": "text"
}
],
"type": "user.message"
}
}Success responses:
201: Created Thread. (application/json->CreateThreadResponse)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /agents/{agentId}/threads
Purpose: Returns Threads created by the authenticated API token.
Path params:
agentIdrequired,string(ulid). Agent API Endpoint ID from the Agent's API Access panel. v1 IDs are bare ULIDs.
Query params:
archivedoptional,boolean. Filter by archived state: true returns only archived Threads, false only active ones. Omit to return all Threads.
Success responses:
200: Thread list. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /threads/{threadId}
Purpose: Returns the current Thread summary, its most recent Run, and links.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Success responses:
200: Thread summary. (application/json->RetrieveThreadResponse)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
POST /threads/{threadId}/events
Purpose: Applies a batch of events to the Thread: send user messages, answer pending permission requests, or interrupt the current Run. A user message queues a new Run when the Thread is idle.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Headers:
Idempotency-Keyoptional,string. Optional key for retry-safe create-thread and send-events calls. Reusing the same key with the same request returns the original response. Reusing the key while the original request is still processing returns 409.
Request body:
application/json:SendEventsRequest
Example:
{
"events": [
{
"text": "Say hello from the API.",
"type": "user_message"
}
]
}Success responses:
200: Accepted event batch. (application/json->SendEventsResponse)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /threads/{threadId}/events
Purpose: Returns the latest public event log entries for this Thread in chronological order. If older public entries are omitted because the limit was reached, truncated is true. Event IDs are stable, so callers can retry or poll without treating the same ID as a new event. This is the stable snapshot read surface for CLI and API consumers; it does not expose raw runtime payloads, transcript, or diagnostics.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Query params:
limitoptional,integer. Maximum number of latest Thread events to return.
Success responses:
200: Thread event list. (application/json->ThreadEventListResponse)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /threads/{threadId}/events/stream
Purpose: Streams public Thread event log entries as Server-Sent Events. Each thread.event data payload uses the same ThreadEventLogEntry shape as GET /threads/{threadId}/events. Events are emitted by stable event ID and the stream suppresses duplicate IDs observed during polling. The stream is for long-running consumer UX and does not expose raw runtime payloads, internal diagnostics, or private transcripts.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Query params:
limitoptional,integer. Maximum number of latest Thread events to return.
Success responses:
200: Thread event stream. (text/event-stream->string)
Example 200:
": connected\n\nevent: thread.event\nid: 01J00000000000000000000010\ndata: {\"id\":\"01J00000000000000000000010\",\"runId\":\"01J0000000000000000000000A\",\"type\":\"run.started\",\"status\":\"available\",\"content\":\"01J0000000000000000000000A\",\"occurredAt\":\"2026-05-19T00:00:01.000Z\",\"durationMs\":null,\"tokens\":null}\n\n"Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
POST /agents/{agentId}/files
Purpose: Uploads a file into the Agent API Endpoint's App draft scope before a Thread exists. Use the returned file ID in create-thread or send-events resources.
Path params:
agentIdrequired,string(ulid). Agent API Endpoint ID from the Agent's API Access panel. v1 IDs are bare ULIDs.
Request body:
multipart/form-data:object
Success responses:
201: Uploaded file. (application/json->PublicFileResponse)
Example 201:
{
"file": {
"createdAt": "2026-05-19T00:02:00.000Z",
"id": "01J0000000000000000000000J",
"mimeType": "text/plain",
"name": "brief.txt",
"size": 19
}
}Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /files/{fileId}
Purpose: Returns public file metadata for a pre-Thread uploaded file or a file attached to a public Thread visible to the API token.
Path params:
fileIdrequired,string(ulid). File ID returned by add or list Thread files. v1 IDs are bare ULIDs.
Success responses:
200: File metadata. (application/json->PublicFileResponse)
Example 200:
{
"file": {
"createdAt": "2026-05-19T00:02:00.000Z",
"id": "01J0000000000000000000000J",
"mimeType": "text/plain",
"name": "brief.txt",
"size": 19
}
}Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /threads/{threadId}/files
Purpose: Lists files attached to the Thread, including caller attachments and Agent artifacts.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Success responses:
200: Thread file list. (application/json->ThreadFileListResponse)
Example 200:
{
"files": [
{
"committed": true,
"createdAt": "2026-05-19T00:02:00.000Z",
"id": "01J0000000000000000000000J",
"kind": "attachment",
"mimeType": "text/plain",
"name": "brief.txt",
"size": 19
}
]
}Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
GET /files/{fileId}/content
Purpose: Downloads bytes for a ready Thread attachment or Agent artifact. The file must belong to a public Thread visible to the API token.
Path params:
fileIdrequired,string(ulid). File ID returned by add or list Thread files. v1 IDs are bare ULIDs.
Query params:
dispositionoptional,"attachment" | "inline". Controls the Content-Disposition response header. Use attachment for downloads or inline for previewable content.
Success responses:
200: Thread file content. (application/octet-stream->string(binary))
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
DELETE /files/{fileId}
Purpose: Deletes a pre-Thread uploaded file or a file attached to a public Thread visible to the API token.
Path params:
fileIdrequired,string(ulid). File ID returned by add or list Thread files. v1 IDs are bare ULIDs.
Success responses:
200: Deleted. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
DELETE /threads/{threadId}/files/{fileId}
Purpose: Detaches a file from the Thread.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.fileIdrequired,string(ulid). File ID returned by add or list Thread files. v1 IDs are bare ULIDs.
Success responses:
200: Removed. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
POST /threads/{threadId}/archive
Purpose: Archives the Thread so it is hidden from default Thread lists.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Success responses:
200: Archived. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
POST /threads/{threadId}/unarchive
Purpose: Restores a previously archived Thread to active Thread lists.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Success responses:
200: Unarchived. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
DELETE /threads/{threadId}
Purpose: Permanently deletes the Thread and its backing AgentSession.
Path params:
threadIdrequired,string(ulid). Thread ID returned by create thread. v1 IDs are bare ULIDs.
Success responses:
200: Deleted. (application/json->object)
Error responses:
400InvalidRequest: The request shape or query value is invalid.401Unauthenticated: A valid API token is required.403Forbidden: This operation is not allowed for this Agent.404NotFound: The resource was not found in the current Mosoo workspace.409Conflict: The Agent/session state rejects this action, or an Idempotency-Key is already processing or was reused for a different request.429RateLimited: The API token exceeded the public API request budget for the current window.500InternalError: The request failed unexpectedly.
Schema quick reference
ThreadEventInput
A single event posted to a Thread. Exactly one variant applies: send a user message, answer a pending permission request, or interrupt a running Run.
Variants:
-
object: Send a new user message into the Thread, optionally with file attachments.resourcesoptional,FileResource[]. Files to attach to this message. Each file must be a ready draft file uploaded through the Agent file endpoint by the same API token.clientRequestIdoptional,string | null. Optional caller-supplied correlation ID echoed back on the matching event result so you can pair responses with the message you sent.textrequired,string. The user message text. Must not be empty.typerequired,"user_message". Discriminator selecting the send-user-message variant.
-
object: Answer a permission request the Agent raised while waiting for input (for example a tool confirmation).decisionrequired,"allow_once" | "reject_once". Whether to allow or reject the requested action for this single occurrence.allow_oncepermits it now;reject_oncedenies it now.requestIdrequired,string. ID of the permission request being answered, taken from the correspondingtool.confirmation.requiredevent.typerequired,"permission_decision". Discriminator selecting the permission-decision variant.
-
object: Interrupt a Run that is currently executing on the Thread.runIdoptional,string(ulid) | null. Run ID (bare ULID) to interrupt. Omit or send null to interrupt the Thread's current Run.typerequired,"user_interrupt". Discriminator selecting the interrupt variant.
SendEventsRequest
Request body for posting a batch of events to a Thread.
Fields:
eventsrequired,ThreadEventInput[]. Ordered list of events to apply to the Thread. At least one is required.
FileResource
A file resource to mount into a Thread or user message.
Fields:
file_idrequired,string(ulid). ID of a ready draft file uploaded through the Agent file endpoint.typerequired,"file". Resource discriminator. Onlyfileis supported today.
PublicFile
Public file metadata.
Fields:
createdAtrequired,string(date-time). Timestamp (RFC 3339) at which the file record was created.idrequired,string(ulid). File ID (bare ULID).mimeTyperequired,string | null. Detected MIME type of the file, or null when unknown.namerequired,string. Original file name.sizerequired,integer. File size in bytes.
PublicFileResponse
A single public file.
Fields:
filerequired,PublicFile. Public file metadata.
ErrorResponse
Standard error envelope returned for any non-2xx public API response.
Fields:
errorrequired,object. Details about why the request failed.coderequired,"agent_not_published" | "forbidden" | "idempotency_conflict" | "internal_error" | "invalid_json" | "invalid_request" | "not_found" | "rate_limited" | "readiness_blocked" | "service_inactive" | "unauthenticated". Stable, machine-readable error code you can branch on.messagerequired,string. Human-readable explanation of the error. Not intended for end users.
SendEventsResponse
Result of accepting a batch of events posted to a Thread.
Fields:
acceptedAtrequired,string(date-time). Timestamp (RFC 3339) at which the event batch was accepted for processing.eventsrequired,ThreadEventResult[]. Per-event outcomes, in the same order as the submitted events.threadrequired,ThreadSummary. The Thread state after applying the batch.warningsrequired,UserWarning[]. Non-fatal warnings raised while accepting the batch (for example a partially honored request). Empty when there are none.
ThreadEventLogEntry
A single public event log entry for a Thread. This is the stable read surface and never exposes raw runtime payloads, transcripts, or diagnostics.
Fields:
contentrequired,string. Public content of the event — typically a reference to the associated payload (such as a message ID) rather than the raw runtime data.durationMsrequired,integer | null. Wall-clock duration of the event in milliseconds, when applicable (for example a completed Run). Null when not measured.idrequired,string(ulid). Unique event ID (bare ULID), monotonically increasing in chronological order.occurredAtrequired,string(date-time). Timestamp (RFC 3339) at which the event occurred.runIdrequired,string(ulid) | null. Run ID (bare ULID) associated with this event, or null when the event is not run-scoped. Use this to reconstruct output for one current Run without mixing earlier Thread output.statusrequired,"available" | "error" | "unsupported". Delivery status of the event:availablewhen the event is fully populated,errorwhen it failed,unsupportedwhen this event type cannot be rendered on the public surface.tokensrequired,integer | null. Token count associated with the event when applicable (for example model usage). Null when not measured.typerequired,"agent.message.delta" | "agent.thinking.delta" | "file.changed" | "run.completed" | "run.failed" | "run.started" | "session.status" | "session_files.updated" | "tool.confirmation.required" | "tool.use.completed" | "tool.use.started" | "usage.updated" | "user.message". Event type, such asrun.started,run.completed,agent.message.delta, ortool.use.started.
ThreadEventListResponse
A page of the latest Thread event log entries in chronological order.
Fields:
eventsrequired,ThreadEventLogEntry[]. The returned event log entries, oldest first within the requested window.truncatedrequired,boolean. True when older events exist beyond the returned window because the requested limit was reached.
ThreadEventResult
Outcome of a single submitted event.
Fields:
clientRequestIdrequired,string | null. TheclientRequestIdechoed from the submitted user message, or null when none was provided or the event type does not carry one.runrequired,RunSummary | null. The Run created or affected by this event, or null when the event did not start or change a Run.typerequired,"permission_decision" | "user_interrupt" | "user_message". The kind of event this result corresponds to.
CreateThreadRequest
Request body for creating a Thread. All fields are optional: omit input to create an empty IDLE Thread, or include it to queue the initial Run.
Fields:
client_external_refoptional,string. Optional client-owned reference (for example an external ticket key) stored on the Thread for correlation. Not unique and not validated by Mosoo.resourcesoptional,FileResource[]. Files uploaded through the Agent file endpoint and mounted into the first Run.inputoptional,object. Initial user message that seeds the Thread and queues the first Run. Omit to create an empty Thread with no run.contentrequired,object[]. Ordered content parts that make up the initial message.typerequired,"user.message". Discriminator for the initial input. Alwaysuser.message.
CreateThreadResponse
Result of creating a Thread.
Fields:
linksrequired,ThreadLinks. Convenience links for the created Thread.runrequired,RunSummary | null. The initial Run queued wheninputwas provided, or null when an empty Thread was created.threadrequired,ThreadSummary. The created Thread.
RetrieveThreadResponse
Current state of a Thread.
Fields:
linksrequired,ThreadLinks. Convenience links for the Thread.runrequired,RunSummary | null. The Thread's most recent Run, or null when no Run has been created yet.threadrequired,ThreadSummary. The Thread summary.
ThreadFile
A file associated with a Thread.
Fields:
committedrequired,boolean. True once the file is durably attached to the Thread; false while it is still a draft handle.createdAtrequired,string(date-time). Timestamp (RFC 3339) at which the file was created.idrequired,string(ulid). Unique file ID (bare ULID).kindrequired,"attachment" | "artifact". Files added through the public API are attachments; artifacts are files produced by the Agent.mimeTyperequired,string | null. Detected MIME type of the file, or null when unknown.namerequired,string. Original file name.sizerequired,integer. File size in bytes.
ThreadFileListResponse
List of files attached to a Thread.
Fields:
filesrequired,ThreadFile[]. The Thread's files.
ThreadFileResponse
A single Thread file.
Fields:
filerequired,ThreadFile. The Thread file metadata, including its identifier, name, MIME type, and origin.
ThreadAttributedUser
The account a Thread is attributed to (the current Mosoo user).
Fields:
idrequired,string(ulid). Account ID (bare ULID) the Thread is attributed to.
ThreadCaller
The credential that created the Thread.
Fields:
idrequired,string(ulid). ID (bare ULID) of the caller that created the Thread.kindrequired,"access_token". Caller credential type.access_tokenidentifies an API token.
ThreadLinks
Convenience links for a Thread.
Fields:
threadrequired,string. Absolute API URL of the Thread resource.
ThreadSummary
Summary of a Thread on a Agent API Endpoint.
Fields:
agent_idrequired,string(ulid). ID (bare ULID) of the Agent API Endpoint this Thread belongs to.attributed_userrequired,ThreadAttributedUser | null. The account the Thread is attributed to, or null when not attributed to an account.client_external_refrequired,string | null. The client-owned reference supplied at creation, or null when none was provided.created_atrequired,string(date-time). Timestamp (RFC 3339) at which the Thread was created.created_byrequired,ThreadCaller. The credential that created the Thread.idrequired,string(ulid). Unique Thread ID (bare ULID).kindrequired,"pet" | "cattle". Agent kind backing this Thread (for example a persistent or one-off Agent API Endpoint).last_run_idrequired,string(ulid) | null. ID (bare ULID) of the most recent Run, or null when no Run exists yet.sourcerequired,"api". Origin of the Thread. Alwaysapifor Threads created via this API.statusrequired,"IDLE" | "RUNNING" | "RESCHEDULING" | "TERMINATED". Lifecycle status of the Thread:IDLE(no active run),RUNNING(a Run is executing),RESCHEDULING(between runs), orTERMINATED(ended).titlerequired,string | null. Human-readable Thread title, or null when one has not been derived yet.updated_atrequired,string(date-time). Timestamp (RFC 3339) of the most recent change to the Thread.
RunSummary
Summary of a single Agent Run on a Thread.
Fields:
completedAtrequired,string | null(date-time). Timestamp (RFC 3339) at which the Run reached a terminal state, or null while it has not finished.createdAtrequired,string(date-time). Timestamp (RFC 3339) at which the Run was created.errorrequired,RunError | null. Structured failure summary when status isfailed; null for successful, active, cancelled, or expired Runs.finalOutputrequired,RunFinalOutput | null. Stable final answer for a completed Run. Mosoo builds this from that Run's publicagent.message.deltaevents in chronological order. Null until the Run status iscompleted.idrequired,string(ulid). Unique Run ID (bare ULID).startedAtrequired,string | null(date-time). Timestamp (RFC 3339) at which the Run began executing, or null while it is still queued.statusrequired,"queued" | "booting" | "running" | "waiting_input" | "completed" | "failed" | "cancelled" | "expired". Current Run status.queuedandbootingprecede execution;runningandwaiting_inputare active;completed,failed,cancelled,expiredare terminal.triggerrequired,"user_prompt" | "retry" | "resume" | "system". What started the Run:user_prompt(a user message),retry,resume, orsystem.updatedAtrequired,string(date-time). Timestamp (RFC 3339) of the most recent change to the Run.
RunError
Public-safe Run failure summary exposed on failed public Runs.
Fields:
coderequired,string. Stable, machine-readable failure code.messagerequired,string. Human-readable failure summary.retryablerequired,boolean. Whether retrying the Run may succeed without changing input.
RunFinalOutput
Final assistant answer for a completed public Thread Run.
Fields:
textrequired,string. Text reconstructed from the current Run's publicagent.message.deltaevents in chronological order.
UserWarning
A non-fatal warning surfaced to the caller.
Fields:
coderequired,string. Stable, machine-readable warning code.messagerequired,string. Human-readable explanation of the warning.
Implementation guardrails for coding agents
- Always send
Authorization: Bearer $MOSOO_API_TOKEN. - Always treat
agentId,threadId,fileId, andrunIdas bare ULIDs. - Use
Idempotency-Keyfor create-thread and send-events retries. - Use event log APIs as the source for public results.
- Do not assume raw model output, private runtime payloads, or internal diagnostics are exposed.
- Do not send provider credentials, model configuration, channel credentials, or Agent configuration through this public API.
- Do not retry invalid requests unchanged.
- Do not treat
403as an authentication problem;403means the token was understood but the operation is not allowed for that resource. - Do not treat a published Agent as ready unless create-thread succeeds or the user confirms Agent readiness in Mosoo.
- Prefer stable caller-owned references such as
client_external_refandclientRequestIdfor correlation.