Skip to main content

Session and event data structures

Reference for the Session and Event objects returned by the Forward Session API.

Session object

The Create, Get, List, Update, and Archive Session endpoints all return this object.
{
  "id": "sess_xxx",
  "type": "session",
  "identity_id": "idn_xxx",
  "template": {
    "id": "tmpl_support",
    "type": "template",
    "name": "Customer support assistant",
    "model": "ultimate",
    "version": 3
  },
  "source_type": "api",
  "status": "idle",
  "title": "Customer support conversation",
  "incremental_streaming_enabled": true,
  "metadata": {
    "source": "web",
    "biz_id": "ticket_123"
  },
  "config": {
    "environment_variables": {
      "API_KEY": "sk-xxx"
    }
  },
  "stats": {
    "active_seconds": 30,
    "duration_seconds": 3600
  },
  "usage": {
    "credits": 12.5
  },
  "archived_at": null,
  "created_at": "2026-06-22T10:00:00Z",
  "updated_at": "2026-06-22T11:00:00Z"
}

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

FieldTypeAlways returnedDescription
idstringYesForward Template ID.
typestringYesAlways "template".
namestringYesTemplate name.
modelstringYesModel tier or model identifier used by the Template.
versionintegerYesTemplate version number.

Session stats

FieldTypeAlways returnedDescription
active_secondsintegerNoActive processing time in seconds. Typically 0 for a new Session.
duration_secondsintegerNoTotal 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.
{
  "id": "evt_xxx",
  "type": "agent.message",
  "session_id": "sess_xxx",
  "content": [
    {
      "type": "text",
      "text": "Here is the analysis result."
    }
  ],
  "processed_at": "2026-06-22T11:00:03Z"
}
FieldTypeAlways returnedDescription
idstringYesEvent ID prefixed with evt_.
typestringYesEvent type.
session_idstringYesID of the Session this event belongs to.
processed_atstringNoTime the event was processed, in RFC 3339 format. May be absent on certain agent-generated or incremental events.
Payload fields allowed on each event type are listed below. The common fields id, type, session_id, and processed_at are not repeated in the table.
Event typeAllowed fields
user.messagecontent
user.interruptNone
user.tool_confirmationtool_use_id, result, deny_message
user.tool_resulttool_use_id, content, is_error
user.custom_tool_resultcustom_tool_use_id, content, is_error
user.define_outcomedescription, rubric, outcome_id, max_iterations
system.messagecontent
agent.messagecontent
agent.thinkingNone
agent.message_startmessage_id, message
agent.content_block_startmessage_id, index, content_block
agent.content_block_deltamessage_id, index, delta
agent.content_block_stopmessage_id, index
agent.message_deltamessage_id, delta, usage
agent.message_stopmessage_id
agent.tool_usename, input, evaluated_permission
agent.tool_resulttool_use_id, content, is_error
agent.custom_tool_usename, input
agent.mcp_tool_usemcp_server_name, name, input, evaluated_permission
agent.mcp_tool_resultmcp_tool_use_id, content, is_error
agent.artifact_deliveredfile_id, original_filename, size, content_type
session.status_runningNone
session.status_idlestop_reason
session.status_terminatedNone
session.errorerror
session.updatedagent, metadata, title

Client-writable event types

POST /api/v1/forward/sessions/{session_id}/events only accepts the event types below.
TypeRequired fieldsDescription
user.messagecontentUser message. content must be a non-empty array of content blocks and supports block types such as text, image, and document.
user.interruptNoneRequests that the current turn be interrupted.
user.tool_confirmationtool_use_id, resultTool call confirmation. result must be allow or deny. When denying, you can also send deny_message.
user.tool_resulttool_use_idReturns the result of a built-in tool. content and is_error are optional.
user.custom_tool_resultcustom_tool_use_idReturns the result of a client-defined custom tool. content and is_error are optional.
user.define_outcomedescription, rubricDefines the desired outcome and its evaluation rubric. max_iterations is optional.
system.message is a public event type but is not accepted as a Forward client-writable event.

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.
When incremental streaming is enabled, the final complete agent.message is still returned. Clients can use incremental events for immediate rendering and rely on the final agent.message as the source of truth for persistence and display reconciliation. Only the following six top-level event types are incremental:
Event typeKey fieldsDescription
agent.message_startmessage_id, messageMarks the start of an assistant message.
agent.content_block_startmessage_id, index, content_blockMarks the start of a content block, such as text, thinking, or tool use.
agent.content_block_deltamessage_id, index, deltaDelivers an incremental fragment for the content block at index.
agent.content_block_stopmessage_id, indexMarks the end of the content block at index.
agent.message_deltamessage_id, delta, usageDelivers message-level increments such as stop_reason, stop_sequence, and usage information.
agent.message_stopmessage_idMarks the end of 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 values of agent.content_block_delta.delta.type.
delta.typeFieldDescription
text_deltatextText output fragment. Clients can concatenate delta.text to reconstruct the full text.
thinking_deltathinkingA fragment of the model or provider's thinking output.
signature_deltasignatureSignature fragment for a thinking block. Emitted only when a signature is present.
input_json_deltapartial_jsonFragment of the tool input JSON.
tool_output_deltavariesReserved for future streaming of tool output. Today, the complete agent.tool_result remains authoritative.
Example of an agent.content_block_delta:
{
  "id": "evt_delta_xxx",
  "type": "agent.content_block_delta",
  "session_id": "sess_xxx",
  "message_id": "msg_xxx",
  "index": 0,
  "delta": {
    "type": "text_delta",
    "text": "Here"
  },
  "processed_at": "2026-06-22T11:00:01Z"
}
Rules for parsing incremental events:
  • 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.