sync block turns a connector definition into a two-way task sync. It says how to identify a tracker item, which operations to call, how each task field maps to a tracker field, and how to read the tracker’s webhook. The engine does the rest: it receives signed events, writes tasks, pushes task changes back and records every run.
Connecting a tracker that ships with a sync block takes no flow and no code. See Connect a tracker. The platform ships one such definition today, for Shortcut. The examples below use a made-up tracker called Acme Tracker so they apply to any service.
Reference syntax
Inside the block, these forms are available.
A sync block holds no secret references. The webhook’s signing secret is stored by name on the connection’s ingress record, not in the definition.
Top-level keys
A deleted item on one side archives its counterpart on the other. Nothing is hard-deleted.
A minimal block
entity
The task’s
external_id is the prefix plus the item id. That is how the engine finds the task for an item, and the item for a task. See External ids.
operations
Each value names one of the definition’s own operations.
scope and echo
remote_actor is a JSONPath on the event. connection_actor is a $probe.* or $binding.* value, usually the member id the probe returned.
fields
Each entry is {task, remote, rule, ...parameters}. task is one of the nine synced task fields, each mapped at most once. remote is the tracker’s field name, with no spaces. A parameter the rule does not list is refused.
Every rule works in both directions and answers “equal” as well: both sides are compared in a canonical form, and a write is sent only for a field that differs. A field already in step writes nothing.
Parameters that take a map or a list, such as
map, exclude or snap_to, accept $binding.* and $probe.* references. The map for role_map usually comes from the status map a person fills in during setup.eval rule, which runs JavaScript snippets for a field the rules above cannot express, is available only to definitions that ship with the platform. A definition you store yourself that uses it is refused.
Roles
role_map goes through a role, not a status name. Each Space status has a role such as todo, working or done. The tracker’s states map to roles, and each role maps back to one state, so a Space can rename or add statuses without breaking the sync. A status with no role is never overwritten by an inbound change, unless keep_roleless_unless says otherwise.
inbound
Event normalisation
Normalising turns one event body into the items it concerns. It is pure and writes nothing, and the Connector step’ssync_normalise runs it for your own flows.
A change is dropped without an error when its id fails
id_pattern, its action is not in actions, its kind is not matched, or it is a comment whose parent is empty or fails the pattern. An event that yields no items is reported as skipped with reason no_items, and an echo as skipped with reason echo.
Comment parents
Some trackers send a comment change with no pointer to the item it belongs to.comment_parent is a list of rules; set exactly one selector in each.
outbound
A push is a hint: the engine re-reads the task before writing, so a burst of events does not send stale values. An event caused by the integration’s own writes is skipped as
integration_origin, and an event from another Space as other_space. Both stop a loop between the two sides.
comments
Mirrors comments in both directions. Add operations.comments as well.
A comment that is only whitespace is skipped as
empty_comment.
Outcomes and reasons
Every sync run ends with{outcome, reason?, task_id?, remote_id?, changed?, unmapped_owners?}. The set of outcomes is closed.
no_parent and scale_empty are reserved and not currently reported.
How a run behaves
Applying an item creates the task when none is linked and the item exists, archives the task when the item is gone, and updates it otherwise. A create that loses anexternal_id race waits briefly, re-reads and applies once. An update that meets a version conflict re-applies once on the version it was given.
Pushing creates the tracker item at most once. It searches by external id first, so a redelivery links instead of duplicating, and if linking back fails after a create, the duplicate is removed with operations.delete, or archived if there is none.
Deliveries are idempotent: a redelivered event lands on the same run and does nothing. A run that failed with a retryable error is run again on redelivery. Items that touch one tracker object run one at a time, and a comment waits for its parent item.
The webhook address
Each connection has two signed addresses on your gateway. Both takePOST /connector/sync/<ingress id>, where the id is in followed by 24 hex characters, and the account is read from the address, never from the request.
The body is verified as raw bytes before it is read, and is limited to 4 MiB. You never create these addresses yourself. Connecting a tracker registers the tracker’s webhook at its address, and creates the task subscription pointing at the other.
Refused calls are counted on the connection card. Runs, one per item or task event, are kept for 30 days and appear in the card’s Run log.
Where to go next
Connector definitions
The document the sync block belongs to.
Connector step
Normalise, apply and push from your own flow.
Task sync
External ids, versions and the changes feed.
Connect a tracker
The setup wizard and connection card.