# Export

Write a selected slice of history as NDJSON for your own tools, from the CLI or as a consistent snapshot in the SDK.

Rendered page: https://agentrelay.com/docs/relayhistory/export
Markdown endpoint: https://agentrelay.com/docs/relayhistory/markdown/export.md

---

History stays local. `ai-hist export` writes the slice you select as NDJSON — one stored record per line — for your own programs to consume.

## Select

```json selection.json
{
  "all_sources": false,
  "sources": ["claude", "codex"],
  "sessions": [],
  "kinds": ["history", "session_event", "tool_call", "file_edit", "presence"],
  "excluded_sessions": []
}
```

- `sources` and `sessions` form a union. Set `all_sources: true` to take every source.
- `kinds` is always explicit.
- A session in `excluded_sessions` is left out, along with any relationship that names it.

## Export from the CLI

```bash
ai-hist export --selection selection.json > history.ndjson
ai-hist export --selection selection.json --out history.ndjson
```

Records go to stdout and errors to stderr. With `--out`, the file is replaced only after the export completes.

Each record carries:

| Field | Meaning |
|---|---|
| `payload` | The stored row's columns. |
| `record_id` | A stable SHA-256 of the row's key, the same id the change feed uses. |
| `revision` | The row's change-feed revision. |
| `origin_id` | The store's change-feed epoch. |

## Export from the SDK

```ts
import { exportHistory } from 'ai-hist';

for await (const record of exportHistory(selection, { dbPath })) {
  await consume(record);
}
```

The iterator reads one consistent snapshot — the store exactly as it stood when the export began, whatever is written while it runs. For paged consumers, use `beginHistoryExport`, `readHistoryExportPage`, and `closeHistoryExport`; an abandoned snapshot expires after an hour.
