Skip to main content
A data source tells IMP how to ingest items from an external system. This tutorial builds a complete source for the support_tickets_context defined in Defining contexts: a cron job that fetches closed tickets from a generic ticketing API with cursor pagination, skips unchanged items via a content hash, and upserts the results into the context.

Prerequisites

What you will build

A source with:
  • A daily cron schedule.
  • A dedicated BullMQ queue.
  • Exponential-backoff retries.
  • Cursor-based pagination that fetches all changed tickets from the API.
  • A content hash check that skips items whose content has not changed since the last sync.
1

Register a source queue

Register a queue for the source sync job. Source queues run one job at a time by default — a sync job is long-running and should not overlap itself:
src/contexts/index.ts
2

Write a paginated API fetcher

Create a helper that fetches tickets from a generic REST API. It uses cursor-based pagination (a cursor token returned in each response) and waits when the API signals rate-limit throttling:
src/integrations/ticketing/fetcher.ts
3

Add the source to the context

Now attach the source to supportTicketsContext. The source fetches only tickets updated since the last run (via start_time), computes a hash of each ticket’s content, and skips items whose hash has not changed:
src/contexts/index.ts (continued)
4

Understand upsert behavior

When execute returns items, IMP calls createItem on each one. The upsert logic depends on external_id:This means returning the same external_id on every run is safe — IMP updates the item in place rather than creating duplicates. Processor and embedding triggers apply to both inserts and updates according to the context’s calculateVectors and processor.config.trigger settings.To skip processing unchanged items, store a content_hash in a custom field and check it before returning the item from execute:
Add content_hash to the context’s fields array ({ name: "content_hash", type: "shortText", calculated: true }) so IMP creates the column.
5

Trigger the source manually

Start the worker:
In the IMP admin interface, go to Build → Knowledge → support_tickets_context → Pipeline → Sources. Click Run on the ticket_api_source row. In the dialog, leave start_time empty for the default (25 hours ago) or enter a specific ISO date. Click Trigger source to enqueue the job.You can also trigger it programmatically:
ExuluApp does not expose a public config accessor, so keep a reference to the config object you passed to app.create(). In src/exulu.ts, extract it as a named const before calling app.create():
src/exulu.ts

What you built

  • A daily-scheduled source that fetches tickets with cursor pagination and rate-limit-aware retries.
  • Content-hash-based incremental sync that skips unchanged items.
  • Upsert-by-external_id semantics that keep items idempotent across runs.

Next steps

Custom processors

Transform items after ingestion — extract text from file attachments, compute derived fields, and trigger embeddings.

Queues and workers

Size queues to API rate limits and scope worker processes.

ExuluContext — configuration

Full source and processor configuration reference.