Skip to main content
The feeding data and applying prices pages show the raw loop: you open a batch, page your records, commit, poll, then claim and acknowledge write-backs by hand. The connector framework does all of that for you. You implement functions that read your system, and the runtime handles paging, per-page checkpoints, retries, batching, the commit, the drain wait, and the write-back leases. It ships in every SDK: defineConnector in TypeScript, define_connector in Python, ConnectorDefinition in PHP and Java, ConnectorRuntime in Go. Same model, same guarantees.

The two functions that matter

You implement two required readers, fetchProducts and fetchCustomers, and add the optional ones as you need them: Each reader takes a cursor and returns one page of records plus the next cursor, or a null cursor when the entity is exhausted. Page everything that can grow; a reader that returns its whole table in one page works in a demo and times out at a million rows.

A complete connector

This implements all four readers and the write-back applier, runs the sync, then drains approved prices. Leave out fetchQuotes, fetchOrders, or applyPrice and the runtime skips what you did not implement, so a catalog-only storefront implements the first two and stops.

The sync is crash-safe

The checkpoint store saves the open batch id and each entity’s cursor after every page. A process that dies mid-sync resumes from the last saved cursor and the same open batch, and re-sent pages are deduplicated on your external ids, so a retry never doubles your data. Use InMemoryCheckpointStore for a one-shot run and FileCheckpointStore (or your own store) for a scheduled job that must survive a restart. The runtime stages entities in dependency order (products, then customers, then quotes and orders) no matter what order you pass, so a line always resolves to a product and customer already sent. The sync report tells you what landed: status, the per-entity staged counts, skippedOverCap, and any warnings.

Write-backs are leased

drainWritebacks claims a batch of approved prices, calls your applyPrice for each, and acknowledges the results, with leases handled for you. Delivery is at-least-once, so make applyPrice idempotent: setting the same price twice must be harmless. A task whose lease expires before you finish is counted as expired and returned to the queue, never acknowledged, so it reaches you again on the next drain.
Echo the decision id on your quote lines. When you map a closed quote in fetchQuotes, carry the pricingDecisionId Elastly returned when it priced the line. That id is the whole learning loop: it ties what Elastly recommended to what your rep charged. Quote lines without it are still ingested, but the runtime warns loudly and the model learns nothing from them.