Skip to main content
GET
/
api
/
v2
/
sessions
/
{id}
/
changes
Get session changes
curl --request GET \
  --url https://agp.eu.hcompany.ai/api/v2/sessions/{id}/changes \
  --header 'Authorization: Bearer <token>'
Returns a stream of changes (events, status transitions, agent actions) that have occurred since your last request. Uses long polling: the server holds the connection open until new changes are available or the timeout expires. Returns 200 with a TrajectoryChanges object, or 204 No Content if no new events arrive within the wait period.

Path parameters

id
string
required
The session ID.

Query parameters

from_index
integer
default:"0"
Event index to start from. Use this to resume from where you left off.
limit
integer
Maximum number of events to return.
include_events
boolean
default:"true"
Whether to include event details in the response.
wait_for_seconds
integer
default:"0"
How long the server should hold the connection waiting for changes. Max: server-configured. Default: 0 (return immediately).Set to 2025 for efficient long polling.

Response

{
  "status": "running",
  "started_at": "2026-05-07T14:30:02Z",
  "finished_at": null,
  "error": null,
  "answer": null,
  "metrics": {
    "steps": 2,
    "total_cost": 0.0093874,
    "input_cost": 0.0084664,
    "output_cost": 0.000921,
    "cost_per_model": [
      { "name": "holo3-122b-a10b", "input_tokens": 21166, "output_tokens": 307, "total_cost": 0.0093874 }
    ]
  },
  "new_events": [
    { "type": "AgentEvent", "data": { "...": "..." }, "timestamp": "2026-05-07T14:30:05Z" }
  ]
}
FieldTypeDescription
statusstringCurrent session status.
started_atstring | nullISO 8601 timestamp when the agent started executing.
finished_atstring | nullISO 8601 timestamp when the session reached a terminal state.
errorstring | nullError message if the session failed.
answerstring | object | nullThe agent’s final result once produced; null otherwise. A string by default, or an object matching the request’s answer_format JSON Schema when one was set. This is the canonical place to read the output; it is not returned on the Session object.
metricsobjectUsage and cost rolled up to the moment of the response: steps, total_cost, input_cost, output_cost, and cost_per_model[].
new_eventsarrayEvents since from_index, each following the event shape (type, data, timestamp).

Examples

curl "https://agp.eu.hcompany.ai/api/v2/sessions/$SESSION_ID/changes?from_index=0&wait_for_seconds=25" \
  -H "Authorization: Bearer $H_API_KEY"

Long-polling pattern

Long polling is more efficient than repeated status checks because the server only responds when something actually changes. The SDK ships a helper that runs the loop for you: it drives termination off status (authoritative) while streaming events from changes, resuming from_index and handling the 204 no-change responses automatically.
from hai_agents import wait_for_session

result = wait_for_session(client, session_id, wait_for_seconds=25)

for event in result.events:
    print(event.type)
print(result.status, result.answer)

# client.run_session(...) creates the session and runs this loop in one call.

Comparison: polling vs. long polling

ApproachEndpointLatencyAPI calls
Status pollingGET /sessions/{id}/status every 3sUp to 3s delay~20/min
Long pollingGET /sessions/{id}/changes?wait_for_seconds=25Near-instant2–3/min
Use status polling for simplicity. Use long polling when you need real-time updates or want to minimize API calls.