Skip to main content
Uses: Python · TypeScript · CLI
The most common Engini job isn’t an agent at all - it’s a scheduled sync. One connector reads, another writes, and the whole thing is two tool calls plus error handling.

Discover both sides

Slugs differ per connector, so resolve them once and reuse. (Discovery is shown in the CLI - it’s a one-time setup step; the same lookups are client.tools.get(...) / client.tools.get_one(...) in the SDKs.)
Read the write-side contract carefully before you build the payload - it tells you which fields are required and whether the tool supports filters or paging:

The sync

Three things that matter more than the sync logic:
  • Partial failure is the normal case. One bad record shouldn’t abort the run - collect failures, finish the batch, then exit non-zero so your scheduler notices.
  • Keep history_id for every failure. It’s how you or support reconstruct exactly what was sent.
  • Retries are yours. Neither SDK retries automatically, by design - see errors & pagination.

Large source sets

If the read tool reports supports_top_offset, page it rather than pulling everything into memory. (The flag means top and offset together - a tool can support SelectTop alone, capping results without paging; check the input_schema for which of SelectTop / SelectOffset it takes. Salesforce, for instance, takes top but not offset.)
Same contract as the catalog paging recipe, applied to tool output.

Scheduling it

GitHub Actions
Add a pre-flight check so a dead credential fails loudly instead of silently syncing nothing:

From the CLI alone

For a simple one-way push, you may not need Python at all: