CortexDB Docs
Docs for CortexDB 0.12.8, the version running on CortexDB Cloud (api.cortexdb.ai).
Connectors

Connectors Overview

Continuously ingest third-party sources into CortexDB — self-hosted with cortexdb-sync, or managed. The shared mechanics for all 18 connectors.

Connectors keep CortexDB in sync with the systems your team already uses — chat, tickets, docs, code, CRM. There are 18 connectors, and every one runs two ways:

  • Self-hosted (recommended) — the cortexdb-connectors package ships a cortexdb-sync CLI you run yourself against your own CortexDB instance. Nothing leaves your infrastructure, and it's the path documented on each connector page and below. Point it at http://localhost:3141 (or your server's URL) and it ingests into your scopes.
  • Managed — alternatively, CortexDB can run the connector as a worker on its infrastructure; configure it once from your dashboard and it handles webhook registration, retries, backfill, and idempotency.

Install the CLI

pip install cortexdb-connectors

This provides the cortexdb-sync command with six subcommands:

SubcommandWhat it does
sync <connector>One-shot sync.
watch <connector> --interval NSync forever with a sleep between cycles.
serveRun the webhook receiver for real-time create/update/delete.
statusShow cursor state for every connector.
listList available connectors and their required env vars.
authShow the resolved CortexDB credentials (redacted).

Add a connector's optional extra to pull its dependencies, e.g. pip install 'cortexdb-connectors[slack]'.

Point it at your instance

The CLI defaults to the cloud — override for self-host

cortexdb-sync targets the cloud API by default. For a self-hosted server, pass --api-url (or set CORTEXDB_URL) to your instance, e.g. http://localhost:3141.

CortexDB credentials resolve in precedence order: CLI flags → environment → ~/.cortexdb/state.json (written by cortexdb init). state.json supplies the token, actor, scope and tenant, but not the server URL: cortexdb init --endpoint keeps the endpoint in the CLI's own config.toml. So for a self-hosted server, always pass --api-url or set CORTEXDB_URL, even after cortexdb init. The relevant global flags:

cortexdb-sync \
  --api-url http://localhost:3141 \
  --api-key <PASETO-or-CORTEX_API_KEY> \
  --actor user:alice \
  --scope-template "org:acme/source:slack/project:{channel}" \
  sync slack

cortexdb-sync auth prints the resolved (redacted) credentials so you can confirm what it will use.

Configure a source

Each connector needs its third-party credentials. Two ways to supply them:

  1. Environment variables — run cortexdb-sync list to see exactly which are required per connector (they're the required env column on each connector page).
  2. A YAML --config file keyed by connector slug — useful for selectors that aren't plain auth (e.g. Jira's project_keys, Teams' team_ids). Reading the file needs PyYAML (pip install pyyaml, or the [all] extra); without it the file is silently ignored with only a warning.

The scope template shapes where events land

--scope-template (or CORTEXDB_SCOPE_TEMPLATE) controls the scope each event is written to, with per-connector placeholders like {channel}, {author}, {workspace}. See Scopes. Every segment type must be an allowed scope type: on the hosted cloud (and on a self-hosted server with the cloud_shared_saas preset) org, dept, team, app, user, agent, service, ws, project, source; the on_prem_enterprise, cloud_private and dev_local presets also allow global and system (the table). A template such as .../channel:{channel} or .../repo:{repo} is rejected on first write with 422 UNREGISTERED_SCOPE_TYPE, and registering the scope first is refused the same way. Put the placeholder under an allowed type, e.g. org:acme/source:slack/project:{channel}.

Run modes

# One-shot: sync everything new since the last cursor, then exit
cortexdb-sync sync slack

# Watch: loop forever, sleeping --interval seconds between cycles
cortexdb-sync watch slack --interval 60

# Serve: receive real-time webhooks (create/update/delete)
cortexdb-sync serve

Cursor state persists in ~/.cortexdb/sync_state.json (per-connector), so re-running picks up where the last cycle left off. --state-file overrides the location, and CORTEX_SYNC_STATE_PATH is the environment equivalent — useful when the connector runs in a container with a mounted state volume. (The packaged worker entrypoint reads SYNC_INTERVAL, default 300 seconds, for its own loop.)

There is a second piece of durable state next to it: the event ledger, a SQLite file at ~/.cortexdb/connector_event_ledger.sqlite3 (or under CORTEXDB_STATE_DIR, or exactly CORTEX_CONNECTOR_EVENT_LEDGER_PATH). It records every CortexDB event id and blob id a connector created per logical source, without the source text, so retries after a crash and later source erasure stay exact. Persist it alongside the state file; a container without a mounted state volume loses both on restart.

Waiting for derived layers

Pass --wait-derivation to have a sync block until the derived layers catch up, rather than returning as soon as events are captured. Derived layers (Facts/Beliefs) require enrichment on a self-host — see Self-hosting defaults.

Webhooks (real-time)

cortexdb-sync serve runs a receiver for connectors that support push. It needs the webhooks extra (pip install 'cortexdb-connectors[webhooks]'; without it serve exits with ModuleNotFoundError: No module named 'uvicorn') and listens on --port (default 8088) and --host (default 0.0.0.0). Verification is per-connector: some sources sign their payloads, while sources that don't (e.g. tl;dv) use a static shared secret header instead. The receiver reads these environment variables:

Env varDefaultWhat it does
WEBHOOK_PORT8081Port for python -m cortexdb_connectors.webhooks only; cortexdb-sync serve ignores it and uses --port (default 8088).
SLACK_SIGNING_SECRET—Verifies Slack request signatures.
GITHUB_WEBHOOK_SECRET—Verifies GitHub's X-Hub-Signature-256 header.
JIRA_WEBHOOK_SECRET—HMAC secret: verifies Jira's X-Hub-Signature (sha256=<hex>) body signature.
FRESHDESK_WEBHOOK_SECRET—Static shared secret for Freshdesk deliveries.
TLDV_WEBHOOK_SECRET—Sent by tl;dv as Authorization: Bearer <secret>.

A secret left unset makes the receiver reject every delivery for that source (fail-closed, 401) — set one for every connector you actually expose. Individual connector pages cover the webhook path and payload details.

Cross-connector notes

preceded_by is not set by any connector

Connector pages sometimes describe thread replies linking via context.preceded_by. No connector sets preceded_by — a connector doesn't have the parent's CortexDB evt_… id at emit time. Instead it attaches a thread=<source-specific-id> label, which you can filter recall by. Each connector page lists its thread label.

  • Idempotency keys are per-connector and version-aware where the source supports edits (a content-version or updated timestamp segment lets an edit land as a new version rather than colliding). The shape on each connector page is the connector's internal record identity; the key actually sent to CortexDB is derived from it (see below), so an edit still lands as a new event and a redelivery still replays.
  • Self-host auth may differ from the dashboard. Some connectors use OAuth apps in the managed dashboard but simpler token/password auth self-hosted (GitHub, Salesforce, ServiceNow). Each page notes both.

Sync behaviour

  • GitHub stores the full content: pull-request descriptions, push commits, issue bodies, full comments, review text, and inline review comments with their file, line and diff hunk. It backfills history (GITHUB_BACKFILL_DAYS, default 30) and re-reads the last 6 hours on each later sync so late events aren't skipped. GITHUB_REPOS is required. Webhooks (serve) build the same content as polling. See GitHub.
  • cortexdb-sync list prints each connector's optional settings next to the required ones.
  • Given-up items stay given up. An item abandoned after the dead-letter budget is not re-read when a lookback window revisits it. Connectors that keep their own state (GitHub) save it with the cursor in the state file.
  • Actor and key. The packaged worker entrypoint adopts user:local as the actor on a static-key server. The one-shot cortexdb-sync sync needs CORTEXDB_ACTOR, and every command needs CORTEXDB_API_KEY, even against a server running without auth (any placeholder works there).

Source identity and keys

  • Every event carries a source descriptor: the canonical source block with a stable source_id (connector:<system digest>:<record digest>), the content kind, a sha256: fingerprint of the exact bytes, and a fragment locator with a byte_range. Recall and GET /v1/events return it, so a citation can be traced to the exact upstream record.
  • The wire idempotency_key is cxsrc:<56 hex>. It is derived from the scope, the canonical source id, the content fingerprint and the fragment range. The source-facing key each page documents (for example jira:{issue_key}:{updated}) decides identity and versioning, but it is not what appears on the event. A re-sync or webhook redelivery of unchanged content is skipped locally (the ledger already holds its event id), so it cannot duplicate even after the server's 24 h idempotency window; changed content gets a new fingerprint and therefore a new event; and GET /v1/experience/status?idempotency_key= needs the cxsrc: value from the connector log, not the source-facing one.
  • Very long content is split without loss. Oversized text becomes several envelopes, each with its own fragment byte_range and its own key; the ledger records all of them as one logical source.
  • Blob uploads are idempotent. Attachments go through POST /v1/blobs/idempotent with a ledger-persisted upload token, so a retried upload cannot duplicate a blob.
  • Two global flags set the identity. --source-instance-id (env CORTEXDB_SOURCE_INSTANCE_ID): a stable, non-secret upstream account or site id, required when several accounts of one provider share an endpoint, actor and scope, because it becomes part of the source identity. --cortex-tenant-id (env CORTEXDB_TENANT_ID): the billing tenant you expect; it is checked against /v1/auth/whoami before any durable ledger state is used, which prevents a ledger built against one tenant from being reused against another.
  • Exact source erasure. Because the ledger holds the full set of event and blob ids per source, the connector library's forget path (forget_episode) can remove one source's events exactly, fragments and attachments included. It is a library call; cortexdb-sync has no delete subcommand.

Upgrading from an older connector release? See Upgrading.

The 18 connectors

ConnectorRequired env
SlackSLACK_BOT_TOKEN
GitHubGITHUB_TOKEN, GITHUB_REPOS
GitLabGITLAB_TOKEN
JiraJIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN
FreshdeskFRESHDESK_DOMAIN, FRESHDESK_API_KEY
tl;dvTLDV_API_KEY
LinearLINEAR_API_KEY
ConfluenceCONFLUENCE_URL, CONFLUENCE_EMAIL, CONFLUENCE_API_TOKEN
NotionNOTION_TOKEN
PagerDutyPAGERDUTY_API_KEY
DiscordDISCORD_BOT_TOKEN
Microsoft TeamsTEAMS_TENANT_ID, TEAMS_CLIENT_ID, TEAMS_CLIENT_SECRET
Google WorkspaceGW_SERVICE_ACCOUNT_KEY, GW_DELEGATED_USER
SalesforceSF_INSTANCE_URL, SF_CLIENT_ID, SF_CLIENT_SECRET, SF_USERNAME, SF_PASSWORD
HubSpotHUBSPOT_TOKEN
ZendeskZENDESK_SUBDOMAIN, ZENDESK_EMAIL, ZENDESK_TOKEN
IntercomINTERCOM_TOKEN
ServiceNowSNOW_INSTANCE, SNOW_USERNAME, SNOW_PASSWORD

On this page