Shared Session, resource, event, and thread structures.
Session object
Returned by create, get, list, update, and archive endpoints.
| Field | Type | Description |
|---|---|---|
id | string | Session ID with the sess_ prefix |
type | string | Always "session" |
agent | object | Agent snapshot used by this Session. See Session embedded agent for the field shape |
environment_id | string | Environment ID used by this Session |
status | string | Session lifecycle status: rescheduling, running, idle, or terminated. The canceling value in a Cancel endpoint response is a fixed acknowledgement value, not a persisted Session object status |
title | string | null | Session title |
metadata | object | Session metadata |
environment_variables | object | Session-level environment variables exported into the agent runtime as a map of string keys to string values ({"NAME":"value"}). Empty Sessions return {}. See Create a Session |
resources | array of Session resource | File, GitHub, generic Git, or Memory Store resources attached to the Session |
vault_ids | array of string | Vault IDs attached to the Session |
deployment_id | string | null | Deployment ID when the Session was created by a Deployment, otherwise null |
outcome_evaluations | array | Outcome evaluation results. New Sessions return [] |
stats | Session stats | Session statistics |
usage | Session usage | Cumulative model, sandbox runtime, and total credits snapshot. Omitted when usage data is unavailable |
archived_at | string | null | Archive time, or null when not archived |
created_at | string | Creation time |
updated_at | string | Last update time |
agent_id, turn_status, or memory_store_ids.
Agent reference
agent in create requests can be either a string Agent ID or this object:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Agent ID with the agent_ prefix |
type | string | Yes (object form only) | Must be the literal "agent". Missing or other values return 400 when the object form is used. The bare-string form (passing the Agent ID directly) skips this check |
version | integer | No | Agent version to snapshot. Omit or pass 0 to use the latest active version |
Session embedded agent
The agent returned inside a Session object is the Agent snapshot pinned to the Session, but several Agent fields are stripped before they are exposed:
Publishing newer source Agent configuration does not replace this snapshot. Submitting agent fields through Update a session can change supported runtime fields locally for the Session without advancing its embedded agent.version; the linked guide also explains Skill version behavior.
created_at,updated_at— never included on the embedded Agent.archived,archived_at— never included; the Session preserves access to the snapshot regardless of the source Agent's archive state.metadata— Agent-level metadata is stripped; only Session-levelmetadatais exposed.instructions— replaced bysystem.
agent.multiagent.agents[] response structure and Session Thread object for the Agent structure returned in each thread.
agent.model.effective_context_window
Sessions return an additional response-only effective_context_window (int64, in tokens) inside agent.model. It is the runtime-resolved context window the Session will use for this Agent (after applying environment-level overrides). Absent or non-positive values are omitted; clients should treat the field as informational.
Session resource
resources[] is a union distinguished by type.
File resource
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Response only | Resource ID |
type | string | Yes | "file" |
file_id | string | Yes | File ID with the file_ prefix. The file must be ready |
mount_path | string | No | Mount path in the container. Defaults to /mnt/session/uploads/<file_id> when omitted |
created_at | string | Response only | Resource creation time |
updated_at | string | Response only | Resource update time |
GitHub repository resource
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Response only | Resource ID |
type | string | Yes | "github_repository" |
url | string | Yes | Repository URL |
authorization_token | string | No (write only) | GitHub token used to access a private repository or push. It is not returned in responses |
mount_path | string | No | Clone target path in the container. Defaults from the repository name when omitted |
checkout | object | No | Git checkout target, for example {"type":"branch","name":"main"} |
created_at | string | Response only | Resource creation time |
updated_at | string | Response only | Resource update time |
Generic Git repository resource
Use this resource for GitLab, Gitee, Bitbucket, and other HTTP(S) Git providers.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Response only | Resource ID |
type | string | Yes | "git_repository" |
url | string | Yes | HTTP(S) clone URL. Public repositories need no username; authenticated repositories include it, e.g. https://username@gitlab.com/group/repo.git |
password | string | No (write only) | Required together with a username for private repositories or push. Use the account password or the Access Token/PAT required by the provider. It is not returned in responses |
mount_path | string | No | Clone target inside the container; derived from repository name when omitted |
checkout | object | No | Git checkout target, e.g. {"type":"branch","name":"main"} |
created_at | string | Response only | Resource creation time |
updated_at | string | Response only | Resource update time |
Memory Store resource
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "memory_store" |
memory_store_id | string | Yes | Memory Store ID with the memstore_ prefix |
access | string | null | No | Optional access mode. Allowed values: "read_write", "read_only". Empty string or omitted means default (no override) |
instructions | string | null | No | Optional instructions stored on the Session resource. Maximum 4096 characters |
name | string | null | Response only | Current Memory Store name when available |
description | string | Response only | Current Memory Store description when available |
mount_path | string | null | Response only | Current implementation returns null unless an existing resource snapshot contains a value |
id, created_at, or updated_at fields.
Session stats
| Field | Type | Description |
|---|---|---|
active_seconds | number | Active processing time in seconds. New Sessions start at 0 |
duration_seconds | number | Session duration in seconds. New Sessions start at 0 |
Session usage
usage is the cumulative snapshot for a Session:
| Field | Type | Description |
|---|---|---|
model_credits | number | Credits accumulated from recorded model calls in the Session |
sandbox_runtime_credits | number | Credits accumulated from billable cloud sandbox runtime used by the Session |
total_credits | number | Total credits accumulated across all usage components |
usage field. Each credits value is floored rather than rounded to at most 2 decimal places; for example, 7.6681 is returned as 7.66. JSON numbers do not preserve trailing zeroes, so 1.20 may be serialized as 1.2. Treat all three fields as one snapshot: overwrite local values by Session ID instead of adding them again on every query.
Multiagent roster element
In a Session response, ordinary Agent and self entries in agent.multiagent.agents[] return the corresponding Agent definitions with the fields below, excluding their own multiagent field.
Advisor entries return only type and model, for example {"type":"advisor","model":"ultimate"}. See Advisor object.
| Field | Type | Description |
|---|---|---|
type | string | "agent" for a sibling Agent reference, or "self" for the coordinator itself |
id | string | Agent ID. Present for type = "agent"; mirrors the coordinator's own ID when type = "self" |
version | integer | Pinned Agent version. Present for type = "agent" |
name | string | Hydrated Agent name |
description | string | null | Hydrated Agent description |
system | string | Hydrated Agent system prompt (replaces instructions) |
model | string | object | Same shape as on the embedded Agent, including effective_context_window when set |
| Other Agent fields | varies | Tools, MCP servers, skills, and other Agent fields, with the same field stripping rules as the embedded Agent |
Event object
Events returned by send, list, and stream endpoints are event-specific JSON objects. Public event responses expose only the documented public fields for each event type.
| Field | Type | Description |
|---|---|---|
id | string | Event ID with the evt_ prefix |
type | string | Event type |
processed_at | string | Present when the event has been processed. Many agent-generated events omit this field. |
type, an event may also include fields such as content, input, name, tool_use_id, mcp_tool_use_id, custom_tool_use_id, result, deny_message, rubric, outcome_id, session_thread_id, stop_reason, error, usage, or model_usage.
Client event request types
POST /api/v1/cloud/sessions/{session_id}/events accepts exactly these client-sent event types:
| Type | Required fields | Notes |
|---|---|---|
user.message | content | content must be a non-empty array of content blocks |
user.interrupt | none | session_thread_id is optional and is echoed as null when omitted |
user.tool_confirmation | tool_use_id, result | result must be allow or deny; deny_message is optional |
user.tool_result | tool_use_id | Use this to return a built-in tool result from a self-hosted worker. content is optional; when present, it must be an array of content blocks. is_error is optional |
user.custom_tool_result | custom_tool_use_id | content is optional; when present, it must be an array of content blocks. is_error is optional |
user.define_outcome | description, rubric | rubric is an object such as {"type":"text","content":"..."} or {"type":"file","file_id":"file_..."}; max_iterations is optional |
system.message | content | content must be a non-empty array of text content blocks; the event must follow a user/tool result event |
Message content blocks
events[].type identifies the event, content[].type identifies the content block, and an image's source.type identifies its source.
| Event | Accepted content[].type | content requirements |
|---|---|---|
user.message | text, image | Required, non-empty array; text and images may be mixed |
system.message | text | Required, non-empty array |
user.tool_result, user.custom_tool_result | text, image, document, search_result | Optional; when supplied, must be an array, which may be empty |
User messages
All fields below are required. Use only the fields for the selected block type.
content[].type | Fields | Description |
|---|---|---|
text | type, text | text must be a non-empty, non-whitespace string |
image | type, source | source is one of the three formats below |
source fields are strings:
source.type | Required fields | Description |
|---|---|---|
base64 | type, media_type, data | media_type is image/png, image/jpeg, image/webp, or image/gif; data is raw Base64, with optional trailing = padding and no Data URL prefix |
url | type, url | External HTTPS image URL readable by the model service; private, loopback, and other restricted destinations are rejected |
file | type, file_id | Image File ID from Upload file, readable by the current identity with status ready; supports PNG, JPEG, WebP, and GIF |
- Each
user.messageaccepts at most 100 image blocks. Use a Session model that supports image input. - Each Base64 value is limited to 10 MiB (10,485,760 bytes) of encoded text, with width and height each at most 8000 pixels. Use a File source when the encoded length exceeds the limit.
- Base64 and File images may be resized or compressed; URL images are fetched by the downstream model service.
User message examples
Each example is a single event object to place in the events array.
Text:
Public event types
List and stream endpoints can expose these event types:
user.message, user.interrupt, user.tool_confirmation, user.custom_tool_result, user.define_outcome, user.tool_result, system.message, agent.custom_tool_use, agent.mcp_tool_result, agent.mcp_tool_use, agent.message, agent.thinking, agent.thread_context_compacted, agent.thread_message_received, agent.thread_message_sent, agent.tool_result, agent.tool_use, session.deleted, session.error, session.status_idle, session.status_rescheduled, session.status_running, session.status_terminated, session.thread_created, session.thread_status_idle, session.thread_status_rescheduled, session.thread_status_running, session.thread_status_terminated, session.updated, span.model_request_start, span.model_request_end, span.outcome_evaluation_start, span.outcome_evaluation_ongoing, and span.outcome_evaluation_end.
session.updated event
A successful Session update emits session.updated. The event always contains id, type, and processed_at. Depending on the request, it can additionally contain these fields:
| Field | Type | Description |
|---|---|---|
title | string | null | Included when the request supplied title |
metadata | object | Included when the resulting metadata object is non-empty and the request supplied metadata |
agent | object | Updated embedded runtime snapshot, included after runtime configuration is changed through Update a session |
environment_variables emits only the fixed fields. Environment-variable names and values are never included in this event.
session.error event
session.error reports an error during Session execution. The event contains id, type, processed_at, and error.
The error object has these fields:
| Field | Type | Description |
|---|---|---|
type | string | Error category. Clients should handle unknown_error and future types |
message | string | Human-readable error description |
retry_status | object | Retry state. Its type is retrying, exhausted, or terminal |
qoder_error_code | string | Optional diagnostic code. Clients must not use it to decide whether to retry |
retry_status.type has these meanings:
| Value | Description |
|---|---|
retrying | The service is retrying automatically; the client should continue waiting |
exhausted | The retry count or recovery window has been exhausted, or a non-retryable error failed immediately. No further automatic recovery is scheduled for this turn. Wait for subsequent status events before deciding whether to send a new message |
terminal | The error is not recoverable and will not be retried automatically. Use subsequent Session/Thread status events to determine the final state |
Advisor events
Advisor lifecycle events have agent_name: "qoder.advisor". Use session_thread_id to identify each consultation.
| Event | Where to read it | Key fields |
|---|---|---|
agent.thread_message_received | Main thread event stream | from_session_thread_id identifies the consultation thread, from_agent_name is qoder.advisor, and content contains the advice |
agent.thread_message_sent | Advisor Thread event stream | to_session_thread_id and to_agent_name identify the main thread; content contains the advice |
session.error | Advisor Thread event stream | error contains the cause and retry status; see session.error event |
session.thread_status_idle | Session event stream | stop_reason.type is end_turn when the consultation ends (including interruption), or retries_exhausted on failure. See the thread's session.error for the cause |
Event delta stream frames
A buffered event is a complete public Event object emitted after generation finishes and recorded in Session event history. It is the authoritative result.
event_start and event_delta are stream-only SSE payloads used for incremental output. They are not public Event objects and do not appear in event list/history responses. Their JSON payloads have no top-level id or processed_at; the SSE id: field carries the ID of the event being streamed and can be used with Last-Event-ID.
Event start frame
An event_start frame identifies the public event whose incremental output has begun.
| Field | Type | Description |
|---|---|---|
type | string | Always "event_start" |
event | object | Streamed event reference |
event object has these fields:
| Field | Type | Description |
|---|---|---|
id | string | Event ID with the evt_ prefix. The SSE id:, related deltas, and buffered event use this same ID. |
type | string | "agent.message" or "agent.thinking" |
agent.message start is followed by text event_delta frames. An agent.thinking start is start-only: no delta follows, and the buffered agent.thinking event with the same ID marks the end of that thinking phase when one is emitted.
Event delta frame
An event_delta frame appends text to an incrementally streamed agent.message.
| Field | Type | Description |
|---|---|---|
type | string | Always "event_delta" |
event_id | string | ID from the matching event_start.event.id and SSE id: field |
delta | object | Content delta |
delta object has these fields:
| Field | Type | Description |
|---|---|---|
type | string | Always "content_delta" |
index | integer | Zero-based index of the content block being updated |
content | object | Text fragment with type: "text" and a text string |
Model request span events
span.model_request_start marks the beginning of one model request.
| Field | Type | Description |
|---|---|---|
id | string | Event ID with the evt_ prefix |
processed_at | string | RFC 3339 timestamp |
type | string | Always "span.model_request_start" |
span.model_request_end marks completion of that model request and includes model_usage when credits are available for the call. model_usage.credits is floored to at most 2 decimal places.
| Field | Type | Description |
|---|---|---|
id | string | Event ID with the evt_ prefix |
is_error | boolean | Whether the model request ended with an error or cancellation |
model_request_start_id | string | ID of the corresponding span.model_request_start event |
model_usage | object | Optional usage for this model call. Omitted when credits are unavailable |
processed_at | string | RFC 3339 timestamp |
type | string | Always "span.model_request_end" |
model_usage contains only:
| Field | Type | Description |
|---|---|---|
credits | number | Credits consumed by this model call. The value may be 0 and is floored to at most 2 decimal places |
Session Thread object
In managed-agent scenarios, each thread within a Session is represented by this structure.
| Field | Type | Description |
|---|---|---|
id | string | Thread ID with the sthr_ prefix |
type | string | Always "session_thread" |
session_id | string | Owning Session ID |
parent_thread_id | string | null | Parent thread ID. null for the coordinator thread |
agent | object | An ordinary thread uses the Session embedded agent shape with multiagent removed; an Advisor Thread uses {"type":"advisor","model":"..."} |
status | string | Thread lifecycle status: running, idle, rescheduling, or terminated |
stats | object | null | Thread statistics. Current implementation returns null |
archived_at | string | null | Archive time, or null when not archived |
created_at | string | Creation time |
updated_at | string | Last update time |
agent_id, agent_version, name, role, stop_reason, created_by_tool_use_id, or usage.
