Sync jobs are now operations

When you create, update, delete, or refund an event through the API, the response returns immediately and the heavy lifting (recurrence fan-out, ticket structure setup, Shopify product mirroring) runs asynchronously. Until now you polled that work through the sync jobs endpoint, which reported a single status and a coarse progress counter. That endpoint has grown up: it is now the operations resource, and it shows you what is actually happening inside.

What’s new

An operation now exposes a phases tree: the individual units of work it planned, each with its own status, progress, and error. For a Shopify-connected event that means you can watch tickets, catalog, inventory, metafields, delivery, and publish move independently instead of staring at one opaque counter.

That unlocks two things integrations have asked for:

  • Partial readiness. The tickets phase completing means the ticket structure and products exist and are editable, even while Shopify-side finishing work is still running. If that is all your script needs, you can proceed without waiting for the whole operation.
  • Root-cause failures. When an operation fails, its error now names the originating phase and carries a specific, machine-readable code (for example INVENTORY_RECONCILE_RAISED), instead of a generic failure.

Operations also report a running status while work is in flight, so pending now means exactly what it says: planned but not started.

Renamed path and header

Before Now
GET /events/{id}/sync_jobs/{id} GET /events/{id}/operations/{id}
X-Event-Sync-Job-ID header X-Event-Operation-ID header

The old path and header continue to work as deprecated aliases so nothing breaks today. They will be removed on September 4, 2026 (90 days from this announcement). Migrate to the new names before then; it is a find-and-replace.

Breaking changes if you poll this endpoint

The richer resource reshapes a few fields. If you have an integration polling sync jobs today, review these:

  • operation is now action. The field that reports save / delete / refund was renamed. Code reading operation from the response body needs updating.
  • running is a new status. If your polling loop treats anything other than pending as done, it now stops too early, while work is still in flight. Treat only completed and failed as terminal.
  • progress can be null. It was previously always an object with zeroed counts; it is now null until there is something meaningful to report. Guard before reading progress.percent.
  • sub_jobs is now phases. If you picked up the briefly exposed (and never documented) sub_jobs array, it is now phases, with slimmer per-phase nodes.

Where to read more

The full contract, including every phase name, status, error code, and polling guidance, is in the Operations documentation. The bulk event import guide has been updated to use the new names throughout.

Jeff Blake