> ## Documentation Index
> Fetch the complete documentation index at: https://docs.checkfu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sessions and Runs

> Create a Session, follow a Run through waits, and reconnect without repeating work.

A **Session** keeps an interaction with an Agent and its ordered history. A
**Run** carries out one request in that Session. Model calls, tool rounds,
questions, approvals, and recovery continue the same Run; they do not create
new Runs by themselves.

For example, ask a support Agent to draft a reply to ticket 482. It may request
order data from your application, wait for the result, and finish the reply.
After that work finishes, a separate request to shorten the reply has its own
Run in the same Session.

<Note>
  Plain HTTP against the Checkfu API needs no private package.
  The documented path is usable as written for an admitted Workspace.
  Confirm [capability status](/getting-started/status) before making availability part of your application's contract.
</Note>

## Start a Session

<span id="start-and-drive-a-session" />

Create a Session with an Agent and an Environment. Checkfu freezes the selected
AgentVersion and Environment policy when the Session starts. This example pins
AgentVersion 3:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST https://api.checkfu.com/v1/sessions \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Idempotency-Key: create-session-001" \
  --header "Content-Type: application/json" \
  --data '{
    "agent": {
      "type": "agent",
      "id": "agent_0123456789abcdef0123456789abcdef",
      "version": 3
    },
    "environment_id": "env_0123456789abcdef0123456789abcdef"
  }'
```

Replace the example IDs with your resources. The Agent needs permission to use
the Environment. An API-key request for an Agent with governed Connection
bindings also needs an authorized `acted_as` Principal. See
[Session identity](/reference/access#session-identity) and the
[Quickstart](/getting-started/quickstart).

Keep the returned `sess_…` ID in `CHECKFU_SESSION_ID` for the following requests.

## Submit work

Post an input event to ask the Agent to draft the reply:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request POST \
  "https://api.checkfu.com/v1/sessions/$CHECKFU_SESSION_ID/events" \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Idempotency-Key: message-001" \
  --header "Content-Type: application/json" \
  --data '{
    "type": "user.message",
    "payload": {
      "content": "Draft a reply to ticket 482.",
      "caused_by": {
        "kind": "api",
        "request_id": "message-001"
      }
    }
  }'
```

The response acknowledges **accepted input**, not completed work. Retain the
event ID and `seq` for correlation and reconnect. Accepted work may still be
queued. If the write response is lost, retry the same request with the same
idempotency key; changing the payload with that key is a conflict.

Authentication supplies the durable author. Client event bytes cannot choose
`authored_by`. Naming a collaboration space in the body does not grant access
or select a scope.

## Read progress

Follow ordered Session events. For example, if the accepted input has sequence
12, read subsequent events with:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --no-buffer \
  "https://api.checkfu.com/v1/sessions/$CHECKFU_SESSION_ID/events/stream" \
  --header "Authorization: Bearer $CHECKFU_API_KEY" \
  --header "Checkfu-Version: 2026-08-31" \
  --header "Last-Event-ID: 12"
```

Correlate output and Run outcomes with the request you submitted. A message
saying “done,” a live preview, or a closed stream does not prove the work
finished. `run.completed`, `run.failed`, and `run.canceled` record Run outcomes.
A provider receipt is separate evidence that an external action happened.

<span id="status-and-settlement" />

The Session resource reports `rescheduling`, `running`, `idle`, or `terminated`.
**Idle can mean waiting for input or approval.** A `session.status_idle` event
with `stop_reason: "requires_action"` is an intermediate wait. Other idle
boundaries can finish a sequential turn while leaving the Session reusable.
Session completion, failure, cancellation, or archival can project to
`terminated`; that value alone does not say whether the work succeeded.

Use the [status mapping](/reference/sessions#session-status) for exact states.
With overlapping work, an idle event is not evidence that every Run finished.
Follow each Run's recorded outcome.

## Respond to a wait

<span id="waiting-and-continuation" />

The support Agent may need order data before it can finish. Return the response
for the exact pending request, using its recorded identity:

| Wait | Response |
| - | - |
| Question | `user.question_answer` names the Question and answers its requested items. |
| Custom tool | `user.custom_tool_result` names the recorded `tool_use_id` and carries your application's result. |
| Approval | The authorized reviewer decides the exact proposed action through the approval flow. |

A matching response continues the **original Run**. A question answer does not
finish one Run and create another. Internal continuation and recovery retain
the same work identity even if the native process changes.

Approval does not grant missing permission or provide a tool result. If an
approved custom tool runs in your application, the Run still waits for its
matching result. Before continuing, Checkfu rechecks current authority for the
original action and resources. A prior approval cannot override revoked access
or authorize changed arguments.

See [event payloads](/reference/events#client-drive-events),
[Approvals](/concepts/action-approvals), and
[Serve tools from your app](/guides/serve-tools-from-your-app). Wait and resume
capabilities depend on the selected harness release.

## Send a follow-up

After the reply is complete, send “Make it shorter” as a separate request. It
has a new Run intent; it does not reuse the completed Run.

While work is active, a harness that supports steering can deliver a message
to the existing Run. Steering contributes to that Run rather than creating an
independent one. To request separate work while busy, set the message payload's
`run_delivery` to `"next_run"`. Acceptance does not mean it starts immediately.
Read the recorded delivery and Run relationships instead of treating every
message as a new Run.

<span id="turns-runs-and-attempts" />

A **Turn** groups a user-meaningful interaction. **SessionThread** records
execution lineage. Supported subagent work keeps its parent relationships;
a native helper or internal generation does not automatically become a new
public Run. Independent requests keep separate Run identities even when their
configuration matches.

A **RunAttempt**, where exposed, records an execution attempt. It is not another
user request or a promise of process recovery. Overlap, steering, subagents,
and resume depend on the exact harness's
[capabilities](/concepts/harness-extensions).

## Stop work

Post `user.interrupt` to stop current work. Its optional `target_event` narrows
the request to a particular API-authored `user.message`. Before that input is
consumed, cancellation withdraws only that input and leaves unrelated queued
work available.

If the target has already contributed to shared work, cancellation also
interrupts that shared group. Consumed peers are recorded as interrupted;
their history and effects remain, and they are not automatically replayed.
Follow the accepted cancellation outcome rather than assuming the request
rolled back an external action or stopped every process.

Cooperative interruption is available only when the selected capability allows
it. Interrupting work does not by itself end the Session or erase its history.
See [interrupt payloads](/reference/events#interrupt-the-current-turn).

## Reconnect

After a disconnect, resume the stream with `Last-Event-ID` set to the last
sequence your application fully processed. Do not resend the prompt merely
because observation stopped. Reconnecting reads history; it does not restart
execution or restore native state.

Handle retained-history gaps explicitly. Do not invent missing events or infer
successful work from their absence. See [Resume a stream](/guides/resume-a-stream).

## Keep the original context

<span id="two-freeze-horizons" />

<span id="filetree-and-memory-mounts" />

The Session freezes resource references and selection policy along with its
AgentVersion and Environment. A new user-driven turn then records its exact
resolved inputs. For this ticket, the next new request after the current task
finishes can select newer content through a `latest` reference.

Tool rounds, steering within the original work, waits, and recovery keep the
original turn's resolved context. They do not silently replace its FileTree revisions,
Skills, or Memory. Current access is still checked; unavailable original
resources cause a refusal rather than a same-name replacement.

Supported [Session updates](/reference/sessions#update-a-session) can change
tools or MCP servers for later work without changing the reusable Agent. They
do not rewrite active or recovering inputs.

FileTree mount paths cannot overlap. Changes remain disposable unless governed
writeback is enabled. Memory access is narrowed by permission and ownership;
at most one writeback-capable store may settle changes in a Turn. Memory keeps
its own version and erasure history. See [Context](/concepts/context).

## Recover safely

<span id="provider-effects-and-recovery" />

If a provider may have received a request but no authoritative receipt was
accepted, its effect is **indeterminate**. Keep the original effect identity
and reconcile through provider lookup, idempotency, an accepted receipt, or a
governed decision. Neither a checkpoint nor a Session event makes blind replay
safe. This is not a blanket exactly-once guarantee for external actions.

Readable history, native continuation, retained files, and live processes are
separate capabilities. Restoring one does not establish the others. Recovery
must preserve the original work, exact required state, and current authority,
or refuse visibly. See [Checkpoints](/concepts/checkpoints).

The Session log does not replace ActionApproval decisions, provider-effect
receipts, or authoritative model Usage. Failure or cancellation does not erase
consumption that already occurred. See [Billing](/concepts/billing-and-platform-supply).

## Inspect Runs

<span id="reading-runs" />

`GET /v1/runs` and `GET /v1/runs/{id}` derive Run lifecycle from the Session
journal. `kind: "native"` carries no public Principal or execution identity.
`kind: "attributed"` exposes its committed `acted_as` as `principal` and carries
its execution identity.

List pages use an opaque keyset cursor ordered by `created_at` and Run ID. Keep
the same `order` when following `next_page`. Reads check Workspace authorization.
An erased journal cannot be rebuilt from a replay placeholder. Missing lifecycle
evidence must not be displayed as an earlier queued or running status.

## Fork history

<span id="forking-a-retained-prefix" />

`POST /v1/sessions/{id}/fork` creates an independent Session from the committed
head or a selected retained event. Copied events keep their IDs and sequences;
`session.forked` marks the branch. Later events on either Session do not change
the other. `GET /v1/sessions/{id}/diff` compares their tails.

Forked history does not automatically copy files or native state. Adopting a
checkpoint requires the exact eligible retained state and compatible execution
support; otherwise the operation refuses. It cannot reconstruct erased bytes.

## External wakeups

<span id="watches-and-wakeups" />

A Watch lets verified external state wake an idle Session. Provider webhook
bytes are a hint: Checkfu reads the source again before deciding whether to
start work. See [`watch.*` events](/reference/events#watch).

## Limits

<span id="turn-deadlines" />

Execution limits come from the selected Environment and supported execution
path. A timeout is a failure boundary, not permission to replay uncertain
effects. Use the recorded Run outcome and error when handling it.

<Accordion title="Prompt integrity">
  Before accepting `user.message`, Checkfu detects mixed-script visual confusables and bidirectional controls. When it finds one, the author must choose a corrected prompt or preserve the exact original. This check applies to authored message text, not mounted files, tool results, or Agent output.
</Accordion>

## Retention

<span id="retention-and-zdr" />

Standard retention can preserve content, checkpoints, and supported continuation
material according to Workspace policy. Zero-data-retention and later erasure
can keep structural identities while omitting or shredding content bytes.
Stopping work does not itself choose a retention policy.

Readable structure does not mean omitted content, provider-effect state, files,
or native continuation bytes can be reconstructed. Export also requires current
access and must disclose unavailable positions. See
[Retention](/concepts/retention-and-zdr) and
[Export your logs](/guides/export-your-log).

## Next steps

* [Sessions API](/reference/sessions): create, update, and inspect Sessions.
* [Events](/reference/events): event envelopes, writable bodies, pagination, and streams.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.