Session object
The Create, Get, List, Update, and Archive Session endpoints all return this object.
Field | Type | Always returned | Description |
id | string | Yes | Session ID prefixed with sess_. |
type | string | Yes | Always "session". |
identity_id | string | Yes | Forward Identity ID that identifies the end user this Session belongs to. |
template | object | Yes | Forward Template summary. See the Template summary table below. |
source_type | string | Yes | Session source: api, im, or schedule. |
status | string | Yes | Session runtime status: idle, running, rescheduling, canceling, or terminated. Archival state is expressed via archived_at. |
title | string | Yes | Session title. |
incremental_streaming_enabled | boolean | Yes | Whether incremental streaming events are enabled for this Session. Defaults to false when omitted at creation. Cannot be changed after creation. |
metadata | object | No | Caller-defined business metadata. |
config | object | No | Session configuration. Omitted when no configuration was provided. |
config.environment_variables | object | No | Session-level environment variables as key-value pairs. |
stats | object | No | Session usage statistics. See the Session stats table below. |
usage | object | No | Usage information. May be omitted when the billing module is not enabled. |
usage.credits | number | No | Credits consumed. |
archived_at | string | null | Yes | Archival timestamp. null when the Session is not archived. |
created_at | string | Yes | Creation time in RFC 3339 format. |
updated_at | string | Yes | Last update time in RFC 3339 format. |
Template summary
| Field | Type | Always returned | Description |
|---|---|---|---|
| id | string | Yes | Forward Template ID. |
| type | string | Yes | Always "template". |
| name | string | Yes | Template name. |
| model | string | Yes | Model tier or model identifier used by the Template. |
| version | integer | Yes | Template version number. |
Session stats
| Field | Type | Always returned | Description |
|---|---|---|---|
| active_seconds | integer | No | Active processing time in seconds. Typically 0 for a new Session. |
| duration_seconds | integer | No | Total session duration in seconds. Typically 0 for a new Session. |
Event object
Events returned by the API are JSON objects whose payload varies with type. Every event carries the same set of common fields, plus type-specific payload fields.
| Field | Type | Always returned | Description |
|---|---|---|---|
| id | string | Yes | Event ID prefixed with evt_. |
| type | string | Yes | Event type. |
| session_id | string | Yes | ID of the Session this event belongs to. |
| processed_at | string | No | Time the event was processed, in RFC 3339 format. May be absent on certain agent-generated or incremental events. |
| Event type | Allowed fields |
|---|---|
| user.message | content |
| user.interrupt | None |
| user.tool_confirmation | tool_use_id, result, deny_message |
| user.tool_result | tool_use_id, content, is_error |
| user.custom_tool_result | custom_tool_use_id, content, is_error |
| user.define_outcome | description, rubric, outcome_id, max_iterations |
| system.message | content |
| agent.message | content |
| agent.thinking | None |
| agent.message_start | message_id, message |
| agent.content_block_start | message_id, index, content_block |
| agent.content_block_delta | message_id, index, delta |
| agent.content_block_stop | message_id, index |
| agent.message_delta | message_id, delta, usage |
| agent.message_stop | message_id |
| agent.tool_use | name, input, evaluated_permission |
| agent.tool_result | tool_use_id, content, is_error |
| agent.custom_tool_use | name, input |
| agent.mcp_tool_use | mcp_server_name, name, input, evaluated_permission |
| agent.mcp_tool_result | mcp_tool_use_id, content, is_error |
| agent.artifact_delivered | file_id, original_filename, size, content_type |
| session.status_running | None |
| session.status_idle | stop_reason |
| session.status_terminated | None |
| session.error | error |
| session.updated | agent, metadata, title |
Client-writable event types
POST /api/v1/forward/sessions/{session_id}/events only accepts the event types below.
| Type | Required fields | Description |
|---|---|---|
| user.message | content | User message. content must be a non-empty array of content blocks and supports block types such as text, image, and document. |
| user.interrupt | None | Requests that the current turn be interrupted. |
| user.tool_confirmation | tool_use_id, result | Tool call confirmation. result must be allow or deny. When denying, you can also send deny_message. |
| user.tool_result | tool_use_id | Returns the result of a built-in tool. content and is_error are optional. |
| user.custom_tool_result | custom_tool_use_id | Returns the result of a client-defined custom tool. content and is_error are optional. |
| user.define_outcome | description, rubric | Defines the desired outcome and its evaluation rubric. max_iterations is optional. |
Public event types
When you query event history or subscribe to the SSE stream, you may receive any of the following public event types:
user.message, user.interrupt, user.tool_confirmation, user.tool_result, user.custom_tool_result, user.define_outcome, system.message, agent.message, agent.thinking, agent.message_start, agent.content_block_start, agent.content_block_delta, agent.content_block_stop, agent.message_delta, agent.message_stop, agent.tool_use, agent.tool_result, agent.custom_tool_use, agent.mcp_tool_use, agent.mcp_tool_result, agent.artifact_delivered, session.status_running, session.status_idle, session.status_terminated, session.error, and session.updated.
Incremental streaming events
Whether incremental streaming events are exposed is controlled by the incremental_streaming_enabled field set at Session creation, not by request parameters on history queries or SSE subscriptions:
- true: The event stream returns partial assistant output before the final agent.message. History queries return the same incremental events.
- false or omitted: Standard mode. Only complete public events are returned; no incremental events are emitted.
| Event type | Key fields | Description |
|---|---|---|
| agent.message_start | message_id, message | Marks the start of an assistant message. |
| agent.content_block_start | message_id, index, content_block | Marks the start of a content block, such as text, thinking, or tool use. |
| agent.content_block_delta | message_id, index, delta | Delivers an incremental fragment for the content block at index. |
| agent.content_block_stop | message_id, index | Marks the end of the content block at index. |
| agent.message_delta | message_id, delta, usage | Delivers message-level increments such as stop_reason, stop_sequence, and usage information. |
| agent.message_stop | message_id | Marks the end of an assistant message. |
| delta.type | Field | Description |
|---|---|---|
| text_delta | text | Text output fragment. Clients can concatenate delta.text to reconstruct the full text. |
| thinking_delta | thinking | A fragment of the model or provider's thinking output. |
| signature_delta | signature | Signature fragment for a thinking block. Emitted only when a signature is present. |
| input_json_delta | partial_json | Fragment of the tool input JSON. |
| tool_output_delta | varies | Reserved for future streaming of tool output. Today, the complete agent.tool_result remains authoritative. |
- Both the SSE event: line and JSON data.type use the public event types.
- agent.content_block_delta.index distinguishes between multiple content blocks.
- processed_at may be absent on incremental events. Clients should treat it as optional.
- After a network interruption, use the Last-Event-ID header carrying the last received Event ID to resume.
- Setting include_thinking=false filters out thinking_delta, signature_delta, and any recognizable thinking content block start/stop events.
- Setting include_tool_calls=false filters out input_json_delta, tool_output_delta, and any recognizable tool content block start/stop events.