---
title: Integrating ClickHouse with Circleback
description: Install the editable Circleback raw ingestion example.
---

The Circleback registry item copies a small API reader and raw ClickHouse tables into a chkit project.


## Install

```sh
bunx chkit add circleback
bunx chkit check
bunx chkit generate --name add_circleback
bunx chkit migrate --apply
bunx chkit ingest run --tag provider:circleback
```

Set `CIRCLEBACK_API_KEY` in the runtime environment before the ingestion run. Edit `src/integrations/circleback/index.ts` to select meetings or skip transcript requests.

| Resource | Default ClickHouse table | Records synced | API reference |
| --- | --- | --- | --- |
| Meetings (`meetings`) | `circleback_meetings_raw` | Meeting metadata and notes, with a transcript where access permits it. | [`GET /meetings`](https://circleback.ai/docs/api/meetings/list-meetings), [`GET /meeting/{meetingId}/transcript`](https://circleback.ai/docs/api/meetings/get-meeting-transcript) |

## Sync behavior

Each new scan cycle reads all meetings with `ownership=All`, follows [provider Link continuations](https://circleback.ai/docs/api), and rechecks every observed transcript. The [meeting listing](https://circleback.ai/docs/api/meetings/list-meetings) has no documented modification-time filter or durable cursor lifetime; interrupted cycles restart pagination from the first page and skip only parent enrichment already acknowledged by the destination in that cycle. Unfinished parents are replayed. Completing the cycle clears the acknowledged ID set, so the next run rechecks every accessible meeting. A meeting timestamp is not assumed to track delayed transcript availability.

Sink-acknowledged checkpoints include explicit source/filter scope, bounded active-cycle parent IDs, unavailable transcript diagnostics with distinct `forbidden` and `not_found` statuses, and the last fully completed cycle's `completedAt`. Neither transcript `403` nor `404` is assumed to mean temporary processing. A new cycle retries listed meetings even when their metadata is unchanged. IDs absent from the listing remain unavailable diagnostics, not executable queued work; they are retried only when listed again or resolved by an explicit reconciliation policy. Recovery can defer updates to acknowledged parents until the next cycle. Listing permission failures fail the stream.

The editable `maxRetainedMeetings` setting bounds both recovery IDs and diagnostics at `10_000`; exceeding the bound fails visibly while preserving acknowledged progress. Source/filter scope changes require a new stream identity.

```sh
bunx chkit ingest status --tag provider:circleback --json
```

Removed meetings remain stored; a full scan is not an atomic source snapshot. The raw tables preserve provider fields and require ClickHouse 25.3 or later. See the installed README and [registry installation](/cli/add/).

## Test the reader

```sh
bunx chkit add circleback --with-tests
bun test src/integrations/circleback/tests/basic.test.ts
```

## Changelog

### Version 0.2.0

- Checkpoint acknowledged meetings within a full scan and replay unfinished parent enrichment after failure.
- Retain explicit forbidden and not-found transcript diagnostics, retry listed meetings on each new scan, and bound saved recovery state.
- Keep raw meeting observations and add portable fixtures for pagination, transcript availability, and destination failures.

### Version 0.1.0

- Introduce raw meeting ingestion with transcript enrichment.

## Related pages

- [App registry](/integrations/)
- [Ingestion plugin](/plugins/ingest/)
