CDP sync run log
When a CRM or reverse-ETL destination stops landing data, the sync run log is the first surface to open. It is a read-only, per-destination history of every sync run — and a drilldown into the failed rows of any single run, grouped by the cause of the failure. Two endpoints back the surface:GET /api/v1/cdp/sync-run-log/runs— the run list plus a per-destination health summary.GET /api/v1/cdp/sync-run-log/runs/:runId— one run’s failed rows, bucketed by error class.
1. What the run log is
Every CRM/reverse-ETL destination run — Salesforce, HubSpot, or a warehouse you sync into — appends one entry to the run history. Each entry carries:- Identity —
id,destination, the object type and the segment the run synced with, plus the run’s start/finish timestamps. - Status —
ok,partial,failed, orskipped. - Record-delta breakdown —
attempted(records that produced an upsert candidate),delivered(records in successfully dispatched batches),rejected(rows dropped before dispatch because the upsert identifier was missing or empty), andfailed(records in batches whose dispatch failed). - Error classes — the distinct failure classes present in the run, so the log line already tells you whether a partial run was a rate limit or a broken field map.
failing (the most recent run ended failed or partial) and overdue.
The freshness SLA
A destination isoverdue when its last successful run is older than
26 hours — or when it has runs but has never succeeded. The window leaves a
full day of slack for a nightly cadence before flagging, so an on-demand-only
destination is not spuriously alarmed unless it is also failing. Watch
overdue together with failing: a destination that is overdue and failing
is down; a destination that is merely overdue is a scheduler that stopped
running.
2. Prerequisites
- An owner, admin, or developer role on the organization — the log is an operator surface and rejects member roles.
- An API key with that role, or a dashboard session with it.
- At least one CRM/reverse-ETL destination configured and run — the endpoints return an empty list when no destination has ever synced.
3. Reading the run list
GET /api/v1/cdp/sync-run-log/runs returns the recent runs (newest first),
plus the per-destination summary. All filters are optional:
destination—salesforce,hubspot, or another destination id.status—ok,partial,failed, orskipped.limit— 1–200, default 50.
needs_attention: true tells you any destination is
failing or overdue before you look at a single run; the per-destination row
then points you at the destination to filter on. Only then open the run list
for the concrete run ids.
4. Drilling into a run
GET /api/v1/cdp/sync-run-log/runs/:runId returns one run with its failed rows
grouped into buckets by error class. Each bucket carries:
class— the stable taxonomy value (see the next section).rows— records attributed to this class.occurrences— distinct failure events (failed batches or rejected rows).retryable— whether a bare retry could clear it without operator action.samples— a bounded sample (up to five, each trimmed) of the transport error messages in this bucket.
404 with code SYNC_RUN_NOT_FOUND.
5. Diagnosing the failure classes
Every failure lands in one of nine classes, and the class decides the retry loop. Retryable classes may clear on their own; the rest need an operator change first — retrying them just fails again.
Two of these have a fixed shape worth memorizing:
validationbuckets from rejected rows always carry the sample “Row dropped: missing or empty upsert identifier value” — the row left the segment but had no value in the mapped upsert-identifier field. Fix the mapping (or backfill the field at the source) before the next run.- Legacy runs (from before the enriched history wrote per-batch failures) attribute the run’s failed rows to the class of the single last-recorded error. The buckets still work — they just have coarser samples.
6. Worked example: a failed Salesforce auth run
A nightly Salesforce Contact sync stops landing. The summary row showsfailing: true, so filter the list to that destination:
"error_classes": ["auth"] and
"rows": { "attempted": 4120, "delivered": 0, "rejected": 0, "failed": 4120 }.
Drill it:
retryable: false, so re-running changes nothing. Reconnect
the destination from the CDP integrations page with a fresh Salesforce
credential, then trigger a run and confirm:
status: "ok" and delivered equal to attempted. The summary row
flips back to failing: false and overdue: false once a success lands.
7. Security: no secret material in the log
The buckets contain no payload chain. Samples carry transport error copy only — never contact records, never field values, never credentials — and each sample is truncated so the detail payload stays bounded. The endpoints read the run history projection and nothing else, so the log is safe to share with an audit channel while still naming the cause of the failure. Credentials for the destinations themselves remain write-only on the config surfaces; the run log never touches them.8. Production checklist
- Check the summary’s
needs_attentionflag before scanning individual runs. - Treat
failing && overdueas down; treatoverduealone as a stopped schedule. - Read the bucket class before retrying: retry only
rate_limit,network,timeout,server, and (once)unknown. - Fix
auth,permission,validation, andnot_foundat the destination, the mapping, or the record — then re-run. - On
rate_limit, slow the destination’s cadence instead of hammering retries. - Keep polling within the 60-requests-per-minute per-endpoint limit.
- Route the destination’s config edits through the CDP integrations page; the run log is read-only by design.
Related guides
- CDP reverse ETL and warehouse exports — the operator walkthrough for the destinations themselves.
- Reverse ETL to Snowflake and BigQuery — the per-destination setup recipes.
- API reference — CDP endpoints — the per-operation shapes for every endpoint named above.