Syncing Web Consent from Secure Privacy to Salesforce
Salesforce API v67.0 (Summer ’26) · Node.js 22 · TypeScript
The API calls are trivial. The real work is identity resolution — Secure Privacy knows a browser, Salesforce knows a person, and only CustomUserId connects them. Section 5 is the one to read closely.
The sync in one page
Section titled “The sync in one page”A scheduled job, one pass per run:
- Read every consent whose
LastUpdatedfalls in a fixed window — section 4. - Resolve each one to a Salesforce
Individual, or set it aside — section 5. - Write one
ContactPointTypeConsentrow per consented category — section 6. - Advance the watermark, but only if the whole pass succeeded.
// The whole program. Everything else in this guide is one of these four// steps in detail.
async function runSync(): Promise<void> { const from = await readWatermark(); // ISO string, persisted const to = new Date().toISOString(); // fixed end -- see section 4
const consents = await fetchWindow(from, to); // 1. read
const stats = { written: 0, anonymous: 0, unresolved: 0, failed: 0 };
for (const consent of consents) { try { const individualId = await resolveIndividualId(consent); // 2. resolve
if (individualId === SKIP_ANONYMOUS) { stats.anonymous++; continue; } if (individualId === null) { stats.unresolved++; continue; }
await applyConsent(consent, individualId); // 3. write stats.written++; } catch (error) { // One bad record must not abandon the rest of the window. It stays // unwritten, and the failure count below stops the watermark moving // past it. stats.failed++; logger.error({ consentId: consent.ConsentId, error }, 'consent failed'); } }
// 4. Only advance on a clean pass. Moving the watermark past records that // failed means they are never retried and the gap is invisible. if (stats.failed === 0) { await writeWatermark(to); } else { logger.warn({ stats }, 'watermark held back; window will be re-read'); }
logger.info({ stats }, 'sync complete');}Re-reading a window is safe: writes are keyed so a repeat updates the existing row rather than adding a second one. That is what makes holding the watermark back the right response to a failure.
Run it from your platform’s scheduler — ECS Scheduled Task, Kubernetes CronJob with concurrencyPolicy: Forbid, or similar. Not an in-process timer: two replicas each running their own would process every window twice.
What’s next
Section titled “What’s next”The rest of the guide is split by who does the work, not by length.
| Page | Covers |
|---|---|
| Salesforce setup | Sections 1–2 — consent objects, custom fields, permissions and authentication. Mostly Salesforce admin work, and all of it has to be right before any code runs. |
| Building the sync | Sections 3–6 — reference data, pulling consent, matching it to people, and writing it back. |
| Troubleshooting | Section 7 — symptoms and their causes. |
The whole guide is also available as a single page, for printing, sending on, or handing to an AI agent in one fetch.
