Session object
This object is returned by the endpoints that create, get, list, update, and archive a Session.| Field | Type | Always returned | Description |
|---|---|---|---|
id | string | Yes | Session ID with the sess_\ prefix. |
type | string | Yes | Always\ "session". |
identity_id | string | Yes | Forward Identity ID, representing the end-user identity that owns this Session. |
template | object | Yes | Forward Template summary; for the fields, see Template summary. |
source_type | string | Yes | Session source: api, im\ or\ schedule. |
status | string | Yes | Session runtime status: idle, running, rescheduling, canceling\ or\ terminated. The archived state is expressed through\ archived_at. |
title | string | Yes | Session title. |
incremental_streaming_enabled | boolean | Yes | Whether incremental streaming events are enabled for this Session. Defaults to\ false\ if omitted at creation, and cannot be changed after creation. |
metadata | object | No | Caller-defined business metadata. |
config | object | No | Session configuration; may be omitted when not provided. |
config.environment_variables | object | No | Session-level environment variables, as key-value pairs. |
stats | object | No | Session statistics; for the fields, see Session stats. |
usage | object | No | Usage information; may be omitted when the related billing module is not enabled. |
usage.credits | number | No | Credit consumption. |
archived_at | string | null | Yes | Archive time; null\ when 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 | The 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; usually\ 0\ for a new Session. |
duration_seconds | integer | No | Session duration, in seconds; usually\ 0\ for a new Session. |
Event object
The Events returned by the endpoints are JSON objects that vary bytype. Every returned Event includes the common fields, while different event types carry different payload fields.
| Field | Type | Always returned | Description |
|---|---|---|---|
id | string | Yes | Event ID with the evt_\ prefix. |
type | string | Yes | Event type. |
session_id | string | Yes | The ID of the Session this Event belongs to. |
processed_at | string | No | The time the event was processed, in RFC 3339 format. Some agent-generated events or incremental events may not include this field. |
id, type, session_id, and processed_at.
| 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 |
Event types the client can send
POST /api/v1/forward/sessions/{session_id}/events accepts only the following event types.
| 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 | Request to interrupt the current processing. |
user.tool_confirmation | tool_use_id, result | Tool-call confirmation. result\ is\ allow\ or\ deny; when denying, you may pass\ deny_message. |
user.tool_result | tool_use_id | Returns a built-in tool result; content\ and\ is_error\ are optional. |
user.custom_tool_result | custom_tool_use_id | Returns a client-defined custom tool result; content\ and\ is_error\ are optional. |
user.define_outcome | description, rubric | Defines the expected outcome and grading criteria; max_iterations\ is optional. |
system.message is a public Event type, but it is not open as a Forward client write event.
Public event types
When querying history and subscribing to the SSE event stream, you may receive 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 theincremental_streaming_enabled field set when creating the Session, not by the request parameters of history queries or SSE subscriptions:
-
true: The event stream returns assistant output fragments before the final completeagent.message; history queries also return the same batch of incremental events. -
falseor omitted: Normal mode is kept, returning only complete public events and no incremental events.
agent.message is still returned. The client can use incremental events for instant display, then use the final agent.message as the persisted or display-calibrated result.
There are only the following 6 top-level incremental event types:
| Event type | Key fields | Description |
|---|---|---|
agent.message_start | message_id, message | Starts an assistant message. |
agent.content_block_start | message_id, index, content_block | Starts a content block, such as text, thinking, or tool use. |
agent.content_block_delta | message_id, index, delta | Carries an incremental fragment for the content block at\ index. |
agent.content_block_stop | message_id, index | Ends the content block at\ index. |
agent.message_delta | message_id, delta, usage | Carries a message-level increment, such as\ stop_reason, stop_sequence, or usage information. |
agent.message_stop | message_id | Ends an assistant message. |
text_delta, thinking_delta, signature_delta, input_json_delta, and tool_output_delta are not top-level Event types; they only appear as agent.content_block_delta.delta.type.
delta.type | Field | Description |
|---|---|---|
text_delta | text | A text output fragment; the client can append\ delta.text\ to reconstruct the text. |
thinking_delta | thinking | A thinking fragment when the model or provider outputs thinking. |
signature_delta | signature | A signature fragment of the thinking block, surfaced when present. |
input_json_delta | partial_json | A JSON fragment of the tool input parameters. |
tool_output_delta | varies | Reserved for future streaming of tool output; currently the complete\ agent.tool_result\ still takes precedence. |
agent.content_block_delta example:
-
Both the SSE
event:and the JSONdata.typeuse public Event types. -
agent.content_block_delta.indexis used to distinguish between multiple content blocks. -
processed_atmay be missing on incremental events; the client should treat it as an optional field. -
After a network interruption, you can use
Last-Event-IDto carry the last received Event ID when reconnecting. -
When
include_thinking=false,thinking_delta,signature_delta, and recognizable thinking content block start/stop events are filtered out. -
When
include_tool_calls=false,input_json_delta,tool_output_delta, and recognizable tool content block start/stop events are filtered out.