Task Reference
sync_record
Create or update a destination record idempotently in one step: mapping lookup, content-hash change detection, create/update call, and mapping upsert.
sync_record
Performs the full idempotent write cycle for one record: looks up an existing mapping, compares content hashes, creates or updates the destination record, and persists the mapping — in a single step.
When to use it
Use sync_record for migration and sync writes to a destination system. It replaces the get_destination_id → create/update → set_destination_id triad with one step, so prefer it in new tasks over wiring those three yourself.
Configuration
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
mapping.connector |
string | Yes | — | Connector slot used as the mapping store. Must support getMapping/setMapping (SQL Connectors: sqlite, postgres, mysql, mssql). |
mapping.resource |
string | Yes | — | Resource name the mapping is stored under. |
mapping.source_id |
string | Yes | — | The source record's ID. Coerced to a string. Missing values fail with mapping.source_id is required. |
hash.fields |
string[] | No | — | Fields included in the content hash. Omitted, every field not prefixed with _ is hashed. |
hash.algorithm |
string | No | sha256 |
sha256 or md5. |
hash.from |
string | No | — | Hash a nested object field of the input instead of the whole record. |
destination.connector |
string | Yes | — | Connector slot for the destination system. |
destination.create |
object | Yes | — | Create call: { method, resource?, args?, id? }. method is called on the destination Connector; resource is injected into the args; id names the response field holding the new record's ID. |
destination.update |
object | No | — | Update call, same shape as create. When omitted, mapped records are never re-touched (create-once). |
writeback.connector |
string | With writeback |
— | Connector for an optional source-row update after a successful sync. |
writeback.table |
string | No | — | SQL table to update (uses the Connector's update method). |
writeback.collection |
string | No | — | MongoDB collection to update (uses update_one with $set). |
writeback.key_column |
string | No | id |
Column/field used to match the source row. |
writeback.key |
any | No | — | Key value. Omitted, the input record's key_column field is used. |
writeback.fields |
object | No | — | Fields to write back. destination_id and hash are added automatically when not set. |
Example
name: sync_contacts
connectors:
source:
type: sqlite
destination:
type: freshdesk
mapping_db:
type: sqlite
steps:
- name: read_contacts
type: call_method
config:
connector: source
method: select
args:
sql: SELECT * FROM contacts
- name: sync_contact
type: sync_record
config: |
{
"mapping": {
"connector": "mapping_db",
"resource": "contact",
"source_id": input.source_id
},
"hash": { "fields": ["name", "email"] },
"destination": {
"connector": "destination",
"create": {
"method": "create",
"resource": "api/v2/contacts",
"args": { "data": { "name": input.name, "email": input.email } }
},
"update": {
"method": "update",
"resource": "api/v2/contacts",
"args": { "data": { "name": input.name, "email": input.email } }
}
}
}Behavior notes
The step runs this flow per item:
- Mapping lookup. Calls
getMapping(resource, source_id)on the mapping Connector. A record counts as already mapped only when the storeddestination_idis non-empty (null,'','null', and'undefined'all count as empty). - Hash comparison. When
hashis configured, a content hash of the record (or of thehash.fromobject) is computed. An already-mapped record is re-touched only when anupdatecall and a hash are configured and the stored hash differs from the computed one. Otherwise the item passes through untouched — this covers create-once (noupdate), no-hash, and unchanged-content cases. - Create or update. Unmapped records trigger
destination.create; mapped-and-changed records triggerdestination.updatewith the existing destination ID injected asargs.id(unless the call config sets its ownid). For creates, the new destination ID is read from the response field named bycreate.id, falling back toid,Id,contactid, thenaccountid. - Mapping upsert. Calls
setMapping(resource, source_id, destination_id, hash). An empty destination ID fails the item withrefusing to write empty destination_idrather than storing a broken mapping. - Writeback (optional). Updates the source row/document with
destination_idandhashplus anywriteback.fields.
The step returns the input item unchanged.
Mapping records
SQL mapping Connectors store mappings in a resource_mapping table the Connector creates on init:
| Column | Meaning |
|---|---|
resource |
Resource name from mapping.resource. |
source_id |
Source record ID (string). Unique together with resource. |
destination_id |
ID of the record created in the destination. |
hash |
Content hash stored at the last successful sync; drives change detection. |
created_at / updated_at |
Timestamps maintained by the Connector. |
Keep hash.fields identical across every task that syncs the same resource — a different field selection produces a different hash and forces spurious updates.
Related
- get_destination_id and set_destination_id — the manual steps this one replaces
- compute_hash — standalone hashing with the same field semantics
- Idempotent sync and the mapping DB — the full idempotency design guide