Send supported user input events to a Forward session.
POST /api/v1/forward/sessions/{session_id}/events
Adds supported user input events to a session. Callers cannot forge agent or session status events.
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <PAT or SAT> |
Content-Type | Yes | application/json |
Idempotency-Key | No | Optional idempotency key for unsafe requests. |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | Session ID. |
Body parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
events | array | Yes | Event objects to append. |
events[].type | string | Yes | Input Event type. |
events[].content | array | Conditional | Required for user.message; must be a non-empty content block array. Only text and image types are supported. |
events[].tool_use_id | string | Conditional | Required for user.tool_confirmation and user.tool_result. |
events[].custom_tool_use_id | string | Conditional | Required for user.custom_tool_result. |
events[].result | string | Conditional | Required for user.tool_confirmation: allow or deny. |
events[].deny_message | string | No | Denial reason when result=deny. |
events[].description | string | Conditional | Required for user.define_outcome. |
events[].rubric | object | Conditional | Required for user.define_outcome. |
events[].reason | string | No | Interrupt reason for user.interrupt. |
events[].is_error | boolean | No | Error flag for tool result events. |
Allowed input event types
Example request
Example response
HTTP 200 OK
Response fields
| Field | Type | Description |
|---|---|---|
data | array | Created Event objects after Forward filtering. |
Errors
“-” in the table below means the response does not include error.code.
| HTTP | Type | Code | Trigger |
|---|---|---|---|
| 503 | api_error | session_materialization_busy | Session configuration refresh conflict; the response includes Retry-After: 1. |
| 400 | invalid_request_error | invalid_request_body | The request body cannot be parsed or its structure is invalid. |
| 400 | invalid_request_error | invalid_request | events is empty, exceeds the count limit, or is missing a type. |
| 400 | invalid_request_error | invalid_event | Event type or fields are invalid. |
| 404 | not_found_error | session_not_found | Session does not exist. |
| 404 | not_found_error | - | The runtime cannot find the Session or an unresolved Pending Action. |
| 409 | conflict_error | identity_disabled | The Identity is disabled; new executions cannot start. |
| 409 | invalid_request_error | session_archived | Session is archived. |
| 409 | invalid_request_error | - | The current Session is processing a Turn and cannot start a new Turn yet. |
| 401 | authentication_error | - | Forward authentication failed. |
Notes
- On
session_materialization_busy, back off according toRetry-Afterand retry with the original request body andIdempotency-Key(if present); check the Session state if conflicts persist. - Allowed input types are
user.message,user.interrupt,user.tool_confirmation,user.tool_result,user.custom_tool_result, anduser.define_outcome. - Disabling an Identity does not cancel accepted executions. While disabled, only tool confirmations or results matching real pending actions may be submitted, without new user messages. After re-enabling, a new turn can start in the same Session. See Disable an identity.
- The response uses the filtered Forward Event object and does not expose raw runtime event JSON.

