---
title: "The event history — the same event objects the stream delivers [read]"
method: GET
path: "/sessions/{id}/events"
---

# The event history — the same event objects the stream delivers \[read\]

`GET /sessions/{id}/events`

## Request

- Base URL: `https://api.agentsky.dev/v1`
- URL: `https://api.agentsky.dev/v1/sessions/{id}/events`
- Auth: HTTP bearer

The session's history, one event per message: user.message and system.message (with content), agent.message (with parts), user.interrupt, and the turn marks session.status_running, session.status_idle (stop_reason.type is end_turn, retries_exhausted, provider_lost or budget_reached) and session.error. context.input_observed is an authenticated history-only bound context-presence fact, not model usage or task success. agent.reasoning, agent.tool_use, agent.tool_result and agent.status appear on the live stream only, not in history. Oldest-first with an opaque numeric cursor; order=desc reads newest-first and its cursor continues older, so a reader can open on the end of a long session. Every event carries rowId, the number the stream frames carry, so a reader resumes the stream after the newest one it holds. Reconnect = open the stream, list events, dedupe by event id. types[] filters (e.g. types[]=user.message&types[]=agent.message is the transcript view).

## Path parameters

- `id` string, required

## Query parameters

- `cursor` string
- `limit` integer
- `types[]` string[]
- `order` 'asc' | 'desc'

## Response `200`

OK

- EventsPage
  - `events` Event[], required: Oldest-first; newest-first with order=desc
    - `id` string, required: Stable event id — the dedupe key across stream ∪ events
    - `rowId` integer: Position in the session's history; the stream resumes after the newest one a reader holds
    - `type` string, required: user.message · system.message (both history only — never on the live stream; they carry `content`) · agent.message · agent.reasoning · agent.tool_use · agent.tool_result · agent.status · user.interrupt · session.status_running · session.status_idle · session.error · session.status_terminated · session.deleted · context.input_observed (authenticated history only: host-admitted input/client UUID/response/gateway identifiers, scope digests and UTF-8 byte coverage; no pod-declared native session authority, raw capture or private pointer)
    - `sessionId` string, required
    - `agentId` string, nullable: The agent id (agent_…)
    - `at` string: ISO 8601
    - `messageId` string: agent.message
    - `parts` MessagePart[]: agent.message
      - union
        - object
          - `index` integer, required
          - `type` 'text', required
          - `text` string
          - `stream_id` string, nullable
          - `stream_index` integer, nullable
        - object
          - `index` integer, required
          - `type` 'reasoning', required
          - `text` string
          - `redacted` boolean
          - `stream_id` string, nullable
          - `stream_index` integer, nullable
        - object
          - `index` integer, required
          - `type` 'tool_call', required
          - `call_id` string, required
          - `tool_name` string, required
          - `args` object
          - `args_partial` string, nullable
        - object
          - `index` integer, required
          - `type` 'tool_result', required
          - `call_id` string, required
          - `tool_name` string, required
          - `status` 'ok' | 'error'
          - `result` object
        - object
          - `index` integer, required
          - `type` 'file', required
          - `name` string, required
          - `media_type` string, required
          - `uri` string, nullable
          - `data` string, nullable
          - `size_bytes` integer, nullable
        - object
          - `index` integer, required
          - `type` 'image', required
          - `media_type` string, required
          - `uri` string, nullable
          - `data` string, nullable
          - `alt` string, nullable
          - `width` integer, nullable
          - `height` integer, nullable
        - object
          - `index` integer, required
          - `type` 'video', required
          - `media_type` string, required
          - `uri` string, nullable
          - `data` string, nullable
          - `alt` string, nullable
          - `width` integer, nullable
          - `height` integer, nullable
          - `duration_ms` integer, nullable
          - `size_bytes` integer, nullable
          - `thumbnail_uri` string, nullable
        - object
          - `index` integer, required
          - `type` 'status', required
          - `level` 'thinking' | 'working' | 'waiting' | 'idle' | 'done', required
          - `text` string, nullable
        - object
          - `index` integer, required
          - `type` 'error', required
          - `code` string, required
          - `message` string, required
          - `retryable` boolean
    - `text` string: agent.message — parts flattened to plain text
    - `content` object[]: user.message / system.message — the CMA content blocks as sent (text · image · document); every image/document source is a `file` source naming a per-session copy readable through GET /files/{file_id}/content
    - `part` union
      - object
        - `index` integer, required
        - `type` 'text', required
        - `text` string
        - `stream_id` string, nullable
        - `stream_index` integer, nullable
      - object
        - `index` integer, required
        - `type` 'reasoning', required
        - `text` string
        - `redacted` boolean
        - `stream_id` string, nullable
        - `stream_index` integer, nullable
      - object
        - `index` integer, required
        - `type` 'tool_call', required
        - `call_id` string, required
        - `tool_name` string, required
        - `args` object
        - `args_partial` string, nullable
      - object
        - `index` integer, required
        - `type` 'tool_result', required
        - `call_id` string, required
        - `tool_name` string, required
        - `status` 'ok' | 'error'
        - `result` object
      - object
        - `index` integer, required
        - `type` 'file', required
        - `name` string, required
        - `media_type` string, required
        - `uri` string, nullable
        - `data` string, nullable
        - `size_bytes` integer, nullable
      - object
        - `index` integer, required
        - `type` 'image', required
        - `media_type` string, required
        - `uri` string, nullable
        - `data` string, nullable
        - `alt` string, nullable
        - `width` integer, nullable
        - `height` integer, nullable
      - object
        - `index` integer, required
        - `type` 'video', required
        - `media_type` string, required
        - `uri` string, nullable
        - `data` string, nullable
        - `alt` string, nullable
        - `width` integer, nullable
        - `height` integer, nullable
        - `duration_ms` integer, nullable
        - `size_bytes` integer, nullable
        - `thumbnail_uri` string, nullable
      - object
        - `index` integer, required
        - `type` 'status', required
        - `level` 'thinking' | 'working' | 'waiting' | 'idle' | 'done', required
        - `text` string, nullable
      - object
        - `index` integer, required
        - `type` 'error', required
        - `code` string, required
        - `message` string, required
        - `retryable` boolean
    - `stop_reason` object: session.status_idle — discriminate on type; never break on bare idle
      - `type` string: "end_turn" (also after an interrupt) | "retries_exhausted" (preceded by an exhausted engine error) | "provider_lost" (confirmed runtime Pod loss, preceded by an exhausted session.error) | "budget_reached"; more reserved
    - `error` object: session.error — the stream stays open; a session.status_idle follows once the turn is over
      - `type` string: e.g. "pod_unavailable"
      - `message` string
      - `retry_status` string: "retrying" (the turn continues) | "exhausted" (the turn is over)
    - `by` string: user.interrupt — who requested the interrupt
    - `mode` 'save': user.interrupt — present on a save interrupt: the run was asked to save its work and end itself
    - `deadline_at` string, date-time: user.interrupt with mode save — when the run is stopped if it has not ended by then
    - `cause` 'save_timeout': user.interrupt — present when the platform stopped a run whose save grace window ran out
    - `actor` object: user.message only, in history and in the send echo: who sent it, present only when that was not the session's owner
      - `id` string
      - `name` string, nullable
  - `cursor` string, nullable, required: Pass back as ?cursor= for the next page; null when the session has no events
  - `hasMore` boolean, required

## Other responses

- `default`: Error — { error: { code, message, request_id } }

## Changes

- **2026-11-02** `e5e8f0229a99`: 9 info
  - added the new optional `query` request parameter `order`
  - added the optional property `error/request_id` to the response with the `default` status
  - added the optional property `events/items/cause` to the response with the `200` status
  - added the optional property `events/items/deadline_at` to the response with the `200` status
  - …5 more

[Operation history](https://skmtc.dev/agentsky/apis/agentsky-developer-api/changes/sessions/:id/events/get.md)

---

[API](https://skmtc.dev/agentsky/apis/agentsky-developer-api.md) - [All operations](https://skmtc.dev/agentsky/apis/agentsky-developer-api/llms.txt) - [OpenAPI document](https://skmtc.dev/agentsky/apis/agentsky-developer-api/revisions/8280a065ef6a?raw)
