> ## 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.

# Add an agent to your app

> Create a Session from your backend and project its durable log into your UI.

Your application keeps its authentication, business data, and user interface.
Checkfu supplies the Agent, Environment admission, durable Session log,
governed actions, and execution lanes.

Before this guide, create or select:

* a Workspace-bound API key held only by your backend;
* an Agent; creating one also creates immutable AgentVersion 1;
* an Environment that defines execution authority; and
* model access for the model selected by the Agent.

Add tools, skills, Files, Memory, and Connections to the Agent or Session only
when the corresponding capability is available. They are not required to prove
the basic integration.

<Warning>
  The Checkfu CLI and TypeScript SDK are private-alpha artifacts with no self-service public installation channel.
  Part of this flow is behind a rollout fence; a deployment that has not enabled it refuses the request rather than running it.
  Confirm [capability status](/getting-started/status) before making availability part of your application's contract.
</Warning>

## Create the server-side client

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { Checkfu } from "@checkfu/sdk"

const checkfu = new Checkfu({
  apiKey: process.env.CHECKFU_API_KEY!,
})
```

Never expose this client or its API key to the browser. An ordinary
Workspace-bound key already selects its Workspace; do not add a Workspace
selector header.

## Create a Session

Create one Session when your application begins a durable agent interaction:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const session = await checkfu.sessions.create(
  {
    agent: { type: "agent", id: agentId },
    environment_id: environmentId,
    title: `${ticket.id}: ${ticket.subject}`,
  },
  { idempotencyKey: `support-session-${requestId}` },
)
```

The Agent is mutable, but this Session resolves and freezes one exact
AgentVersion. It also freezes the admitted Environment authority. Updating the
Agent or Environment affects later admissions, not work already inside this
Session.

## Send application context as user input

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const inputEvent = await checkfu.sessions.events.send(
  session.id,
  {
    type: "user.message",
    payload: {
      content: `Ticket ${ticket.id}: ${ticket.subject}\n\n${prompt}`,
      caused_by: { kind: "api", request_id: requestId },
    },
  },
  { idempotencyKey: `support-message-${requestId}` },
)
```

Actor attribution comes from the authenticated request. Do not accept or insert
a caller-supplied actor identifier into event bytes. Do not place provider keys,
Connection credentials, or other secrets in the message. Checkfu keeps
credential material out of model context, harness configuration, Session
events, and the sandbox.

## Read settlement from the event log

Request completion means the input was stored. It does not mean the turn
finished. Resume after that stored event so the stream replays every later event
without stopping on an earlier Session boundary:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const terminalSessionEvents = new Set([
  "session.status_completed",
  "session.status_failed",
  "session.status_canceled",
])

for await (const event of checkfu.sessions.events.stream(session.id, {
  lastEventId: inputEvent.seq,
})) {
  console.log(event.seq, event.type)

  if (
    terminalSessionEvents.has(event.type) ||
    (event.type === "session.status_idle" &&
      event.payload.stop_reason !== "requires_action")
  ) {
    break
  }
}
```

Runs, child Runs, subagents, approvals, checkpoints, recovery, and continuation
remain part of this Session truth. A harness transcript or request duration is
not an alternate authority. An idle boundary with `requires_action` is
intermediate, so do not present the turn as complete until the admitted
continuation settles.

When a turn pauses for an ActionApproval, render the frozen action and send the
human decision through your authorized backend. Follow
[Handle an approval](/guides/handle-an-approval); approval is a governance
resource, not a chat event or browser-only confirmation.

## Render the Session in your UI

Expose narrow, authenticated backend routes for the Session event page and SSE
stream, then use [Embed a Session view](/guides/embed-a-session-view). Your
backend must verify that the application user may observe the requested Session
before attaching the Checkfu key upstream.

## Add capabilities after the first turn

<CardGroup cols={2}>
  <Card title="Tools and Connections" href="/guides/connect-a-providers-account">
    Add provider-neutral tools while keeping credentials out of the model and
    sandbox.
  </Card>

  <Card title="Files, Memory, and Skills" href="/concepts/context">
    Add retained context through explicit resources and immutable versions.
  </Card>

  <Card title="Automations and triggers" href="/concepts/automations">
    Start fresh Session work from schedules, webhooks, or subscriptions.
  </Card>

  <Card title="Your own messaging app" href="/guides/connect-your-own-messaging-app">
    Map each conversation in your messaging app to a Session through the API.
  </Card>

  <Card title="Computer" href="/concepts/work-environments">
    Use provider-neutral Computer authority and durable Screen observation only
    where support evidence permits.
  </Card>

  <Card title="Usage and Budgets" href="/guides/attribute-usage">
    Attribute authoritative Usage before enforcing or presenting a Budget.
  </Card>

  <Card title="Retention, audit, and recovery" href="/concepts/tenancy-and-governance">
    Choose standard or ZDR semantics and inspect governance and audit truth.
  </Card>
</CardGroup>


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