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

# Sessions: start, run, and close each agent trace

> Create a session to open a trace, wrap your agent's work inside session.run(), and close it with complete or fail when the run finishes.

A session represents one complete agent run — one decision cycle, one trade attempt, one strategy evaluation. Every session becomes a trace in the Mortem dashboard with a full chronological replay of everything the agent did. Start a session at the beginning of a run, and close it when the run ends.

## Start a session

Call `mortem.startSession(options)` to open a new trace. The method always returns a `Session` — if session creation fails internally, the SDK returns a no-op session that silently absorbs further calls rather than throwing into your agent code.

```ts theme={null}
const session = await mortem.startSession({
  inputSummary: "Evaluate whether to swap 1 SOL for JUP at current prices",
  tags: ["swap", "jup", "devnet"],
})
```

### SessionOptions

<ParamField path="inputSummary" type="string" required>
  A plain-text description of what the agent is trying to do in this run. This is the first thing visible in the trace list and detail view.
</ParamField>

<ParamField path="tags" type="string[]">
  Arbitrary labels attached to the trace. Use these to filter runs by strategy, market, cluster, or any other dimension that matters to your team.
</ParamField>

<ParamField path="traceId" type="string">
  Override the auto-generated trace ID. Must be a valid ULID or a string that is unique across your agent's traces. Useful when you generate correlation IDs upstream and want them to match inside Mortem.
</ParamField>

<ParamField path="agentId" type="string">
  Override the client-level `agentId` for this specific session. Useful when a single process manages multiple logical agents.
</ParamField>

<ParamField path="startedAt" type="Date">
  Backfill the session start time. Defaults to `new Date()` at the moment `startSession` is called.
</ParamField>

## Wrap agent work with `session.run()`

Pass your agent's main logic to `session.run(callback)`. This is the recommended way to structure every run.

```ts theme={null}
const result = await session.run(async () => {
  // all LLM calls, tool calls, and Solana transactions go here
  return { ok: true }
})
```

`session.run()` does three things:

1. **Activates async trace context** so that child events from wrapped clients (OpenAI, Solana, etc.) are automatically linked to this session — even across `await` boundaries.
2. **Calls `session.complete()`** automatically when the callback resolves.
3. **Calls `session.fail(error)`** automatically when the callback throws, then re-throws the error so your own error handling is unaffected.

<Warning>
  Without `session.run()`, you still get a top-level trace, but child events from instrumented wrappers will not be captured. The async context that links LLM calls and tool calls to the active session only exists inside `session.run()`.
</Warning>

## Close a session manually

If you are not using `session.run()`, close the session explicitly after the agent's work is done.

Use `session.complete()` when the run succeeds:

```ts theme={null}
await session.complete("Swap submitted — signature abc123")
```

Use `session.fail()` when the run errors:

```ts theme={null}
await session.fail(error, "Swap aborted due to slippage check failure")
```

Use `session.end()` when you want to set the status explicitly:

```ts theme={null}
await session.end({
  status: "completed",
  outputSummary: "Position closed at target price",
})
```

### Completion methods

<ParamField path="session.complete" type="(outputSummary?: string) => Promise<void>">
  Marks the trace as `completed` and flushes buffered data. Accepts an optional plain-text description of the outcome.
</ParamField>

<ParamField path="session.fail" type="(error: unknown, outputSummary?: string) => Promise<void>">
  Marks the trace as `errored`, records the error message, and flushes. Accepts any thrown value — `Error`, string, or unknown.
</ParamField>

<ParamField path="session.end" type="(options?: SessionEndOptions) => Promise<void>">
  Generic completion with explicit control over `status`, `outputSummary`, and `errorMessage`. Status defaults to `"completed"` if not provided.
</ParamField>

## Access the trace ID

Every session exposes its trace ID through `session.traceId` (an alias for `session.id`):

```ts theme={null}
console.log(session.traceId) // "01HZ..."
```

Use this value to build dashboard URLs, correlate logs, or pass as a `traceId` override to a downstream session.

## Recommended session pattern

This is the full pattern from the Mortem README. Use it as your starting point:

```ts agent.ts theme={null}
import { Mortem } from "@mortemlabs/sdk"

const mortem = new Mortem({
  apiKey: process.env.MORTEM_API_KEY ?? "",
  agentId: process.env.MORTEM_AGENT_ID,
  verifyToken: process.env.MORTEM_VERIFY_TOKEN,
  environment: "devnet",
  ingestUrl: process.env.MORTEM_INGEST_URL,
})

const session = await mortem.startSession({
  inputSummary: "Evaluate a Solana trade setup and optionally submit the swap",
  tags: ["swap", "local-dev"],
})

try {
  const result = await session.run(async () => {
    const planning = session.beginEvent("custom", {
      step: "planning",
    })

    planning.complete({
      payload: {
        step: "planning",
        result: "ready",
      },
    })

    return { ok: true }
  })

  await session.complete("Agent completed successfully")
  console.log(session.traceId, result.ok)
} catch (error) {
  await session.fail(error)
} finally {
  await mortem.close()
}
```

<Note>
  Session methods — `complete`, `fail`, `end`, and `run` — are best-effort. Internal failures are swallowed and reported through the optional logger rather than propagating into your agent code. Your bot will not crash because of an SDK error.
</Note>
