---
title: Sessions and runs
description: How sessions, runs, and the event log fit together.
---

A **session** is one unit of work — a conversation, a ticket, a background job. It belongs to a workspace, binds an agent version when it is created, and holds an append-only **log** of everything that happened in it.

A **run** is one turn of the agent's work over that log. Input starts a run; the run appends its own events as it goes, and ends in exactly one terminal event.

The distinction matters because a session outlives its runs. A run can fail, be stopped, or lose the connection you were watching it on, and the session is still there with its log intact — ready for the next input.

## What binds to what

| | Fixed when | |
| --- | --- | --- |
| Agent version | The session is created | The latest version then. A version published later changes only later sessions. |
| Skill and function versions | The session is created | Each grant's **Latest** resolves to the newest version then; **Pinned** stays where it is. |
| Vaults | The session is created | The session's credentials, chosen per session. |
| Metadata | The session is created | Your own keys, copied onto every usage record. |

So a session started this morning finishes on the same instructions, tools, and credentials it started with, whatever is published in the meantime.

## The log

Every event carries a sequence number, and the log is the whole truth: messages, the agent's thinking, tool calls and their results, approvals, forms, clients joining and leaving, and each run's start and end. The console's **Events** tab shows it; the API [pages and streams](/build/streaming-events) it; the [event reference](/reference/events) lists every type.

Because the log is the truth rather than any connection, a client can drop and come back with the last sequence number it saw, and a page reloaded an hour later shows the same conversation.

## What a run does

1. **It starts from the log**

    A run rebuilds its state from the events already committed, so a run that
    follows a failed one starts from what actually happened.

2. **It calls the model**

    Through Subako, never with a key the run holds: the provider's key stays
    sealed in Subako. Long conversations are compacted as they near the
    model's context window.

3. **It calls tools**

    Each through the grant that offers it, under that grant's policy — with
    the session's credentials attached for MCP servers and functions, and
    routed to your app for client tools.

4. **It ends**

    In `run_completed`, `run_failed`, or `run_cancelled`. A run waiting on a
    person — an approval or a form — simply waits, for up to a day.

Input sent while a run is working **steers** it: the run reads it at its next step rather than queuing behind it. Stopping a run is cooperative: it ends at its next checkpoint with `run_cancelled`, and what it already committed stays in the log.
