Skip to main content

Sync a site's contacts

POST 

/contacts/sync

A connected site's customers, up to 500 per call. It is what the WordPress plugin calls to bring in the site's users, customers and leads — and any custom platform holding a connected site's API key can call it too. The answer is 200 even when rows fail: each row's outcome comes in results, in the order sent.

POST /contacts/batch is a spreadsheet uploaded once. This route is the opposite: a system reporting the same people again and again, so its rules only add, never destroy:

  • a contact is found first by who they are on the site (ref: WordPress user 42), then by phone. Someone who changed their number is still the same contact; if the new number already belongs to another contact, nothing is merged and the row comes back with phone_conflict;
  • with no phone and no link to the site, nobody is created (no_phone, invalid_phone);
  • tags only come in, by name, and missing ones are created. To take one off, use removeTags;
  • names, e-mail and custom fields only fill what is empty: what someone typed in the dashboard wins over what the site reports. The fields the site computes itself (WooCommerce's wc_…) overwrite — unless occurredAt is older than the last one applied for that link (stale_snapshot);
  • an opt-out given on the site always applies. Consent only moves from unknown to opted_in, with evidence, and never over an opt-out (kept_opt_out) or a suppression (kept_suppression);
  • a value for a field the account does not have, or of the wrong type, is dropped and listed in warnings — the rest of the row is applied;
  • new contacts count against the plan's cap (contact_limit_reached).

With options.triggers set to false — the default, what a backfill sends — nothing fires: no flow starts and no contact.created webhook goes out. A backfill of ten thousand customers must not greet ten thousand people. Send true for what just happened on the site.

Idempotency. With the Idempotency-Key header, a batch retried after a dropped connection returns the first result, with Idempotent-Replayed: true, instead of being applied twice. The same key with another body is refused with 422 idempotency_key_reused; while the first request is still running, the repeat gets 409 idempotency_in_progress.

Only a connected site's API key syncs — it comes with the contacts:sync permission. A regular API key gets 404 site_not_found, and an API key limited to some numbers, 403.

Request​

Responses​

Outcome per row.