CortexDB Docs
Connectors

Freshdesk Connector

Ingest Freshdesk tickets, replies, private notes, and attachments into CortexDB.

Captures Freshdesk tickets, their full conversation thread (public replies + private notes), and their attachments as CortexDB experiences. Each item keeps its real source timestamp.

Two ways to run this connector

Self-hosted — pip install cortexdb-connectors then cortexdb-sync sync freshdesk. Managed — CortexDB runs the connector as a worker. See the Connectors overview.

1. Prepare credentials in Freshdesk

Freshdesk → Profile settings → Your API Key. The connector authenticates as HTTP Basic with the API key as the username and X as the password. You also need your Freshdesk domain, e.g. acme.freshdesk.com.

2. Configure (managed dashboard)

Settings → Connectors → Add Connector → Freshdesk. Paste the domain and API key, set the scope template (default org:<org>/source:freshdesk), and Start sync.

What gets written

EventEpisode typeNotes
TicketissueSubject + description; content prefixed [FreshDesk ticket #N]
Public replycommentPrefixed [FreshDesk reply on ticket #N]; tagged reply
Private notecommentPrefixed [FreshDesk note on ticket #N]; tagged note
Ticket/reply attachmentdocumentUploaded to /v1/blobs and ingested as content.kind="blob_ref" so the content processors extract and index the file

Every episode carries thread_id = "freshdesk:ticket:<id>", an entity reference of type ticket, and metadata with ticket_id, status, priority, and a source_url back to the agent view.

Visibility

All Freshdesk episodes are stored restricted — support data is customer-facing and sensitive. Public replies and private notes land at the same visibility; the distinction is carried by the reply / note tag and the content prefix.

Idempotency and history

Tickets and conversations use a content-versioned key:

ticket:<id>:<updated_at>:<content-digest>
conv:<id>:<created_at>:<content-digest>
freshdesk:att:<attachment_id>

Each edited state is retained as a new version. The content digest is what makes edited replies and merged tickets work: a Freshdesk merge moves conversations to the primary ticket without changing their id or created_at, so a timestamp-only key would collide and the corrected attribution could never be recorded. Attachments key on the stable attachment id, so a re-synced ticket replays instead of re-uploading the bytes.

The key on the wire is derived

The key format above is this connector's internal record identity: it decides which source record an event belongs to. The idempotency_key actually sent to CortexDB is a derived cxsrc:<56 hex> value that also hashes the content, labels, observed time and actor, so an unchanged redelivery converges on the same event while any edit lands as a new one, even where the key format itself is not content-versioned. Every event also carries a source descriptor with the record's fingerprint. See Source identity and keys.

Real-time delivery (webhook)

Freshdesk automations don't sign their payloads, so the receiver authenticates on a static header:

pip install 'cortexdb-connectors[webhooks]'   # serve needs starlette + uvicorn
export FRESHDESK_WEBHOOK_SECRET=<a long random string>
cortexdb-sync serve --port 8081

Then in Freshdesk → Admin → Workflows → Automations, add a Trigger webhook action pointing at POST https://<your-host>/webhooks/freshdesk/events with Authorization: Bearer <the same secret>. The webhook path uses the same normalizer as polling, so running both serve and sync is safe.

Run it yourself

pip install cortexdb-connectors
pip install cortexdb-cli && cortexdb init

export FRESHDESK_DOMAIN=acme.freshdesk.com   # required
export FRESHDESK_API_KEY=...                 # required
export FRESHDESK_INCLUDE_CONVERSATIONS=1     # 0 = tickets only, bodies still ingested
export FRESHDESK_INCLUDE_ATTACHMENTS=1       # 0 = skip attachment blobs

cortexdb-sync --api-url http://localhost:3141 sync freshdesk
cortexdb-sync --api-url http://localhost:3141 watch freshdesk --interval 300

FRESHDESK_INCLUDE_CONVERSATIONS=0 drops only the reply and note episodes — the ticket description is always ingested.

Limits and behaviour worth knowing

  • Attachments over 32 MiB are recorded metadata-only: the filename survives, the bytes are not uploaded.
  • Rate limits are handled: requests retry 429/5xx with Retry-After, up to 5 attempts.
  • A ticket that cannot be fetched holds the cursor and is retried; after 5 consecutive failed cycles it is dead-lettered and cortexdb-sync status reports it.
  • Deletions are not propagated from the poll path — a deleted reply remains as retained history.

See also

On this page