Consent-aware CDP ingest: bring a consented contact base in with lawful basis attached
You already own a consented audience: a CSV export, a warehouse table, a legacy ESP list. Getting the identifiers into the Orbit CDP is the easy half. The half that makes those people sendable is the consent metadata that travels with each record: which disclosure version the person accepted, on what lawful basis, captured when, through which source, and what happens when they change their mind. This guide walks that loop end to end: configure the tenant-owned controls, map your ledger to the consent envelope, wire the source with signed ingest, prove enforcement in the sandbox, and package the evidence. It sits between three existing guides that each cover one depth, not the migration shape: the console tour (CDP integration console), the identity resolver (anonymous identity stitching), and the exit path (erasure propagation).1. The task, and the five ways ingest without consent fails
Ingesting identifiers alone takes an afternoon. Ingesting them without consent metadata creates five gaps that surface later, always at the worst moment:
Consent posture is tenant-owned in Orbit: the platform records, gates, and proves; you set the posture. Everything in this guide is a control you configure, not a platform mandate.
2. Configure tenant-owned controls before ingest
Do this before the first row moves, so every ingested record lands already governed:- Pick a compliance profile. Run the compliance profile wizard and choose the template that matches your market. The template you pick becomes the
policy_templateon every ledger row this source writes. - Declare lawful basis per source. For each list or table you migrate, record the basis your counsel determined for it (
consentfor opted-in marketing lists, another basis only where counsel says so). You will attach it to every row from that source in section 3. - Pin quiet hours per country. Set the sending windows your markets require, per the country rules posture playbook. Ingested contacts become sendable immediately; the windows must exist before they do.
- Pin data residency where required. If part of the base is region-pinned, pin it before ingest per data residency pin, lock, migrate so no row ever lands outside its pinned region (failure mode 5).
3. Map your warehouse columns to the consent envelope
Start from the shape your ledger actually holds. A typical three-column consent ledger export:{consent_version, lawful_basis, source, captured_at}. Two of them (lawful_basis, source) are declared once per source in section 2; two (consent_version, captured_at) ride on every row. A dbt model that emits the envelope:
where clause is the point: a row with a missing version or timestamp is failure mode 2 or 3, and it must stop here, not in Orbit.
The warehouse-to-Orbit mapping:
4. Wire the source, and sign every event
- Create the source. In the dashboard, open Integrations → CDP → Sources, create a source for this migration, and copy the ingest id and the secret shown once. The API equivalent is
POST /api/v1/cdp/secrets. The full signing contract (the three headers, the canonical string, the replay rules) is CDP ingest signing; every request below carries those headers. - Identify each row. Send one signed
/identifyper row to/cdp/v1/:ingest_id/identifywith the email intraits. The 200 response returns thecontact_idthe consent ledger keys on. - Record the grant. For each row, append the durable consent decision with the mapped envelope:
idempotency_key makes the migration re-runnable: a replayed row is deduped, not double-granted.
4. Make the envelope mandatory on ingest events. In your tracking plan, declare consent_text_version, lawful_basis, source, and captured_at required on the events this source produces, and set the plan to strict enforcement. From now on, an event that arrives without its envelope is rejected at the gateway instead of silently persisting.
Every event this source emits now either carries its consent envelope or does not persist at all.
5. Verify enforcement in the sandbox
Run both captures in sandbox mode before the production cutover. Capture 1: an event without consent is rejected. Send one signedtrack for a contact whose envelope fields you deliberately omitted. With the tracking plan in strict mode, expect a 422:
POST /api/v1/cdp/consent/check for that identity and purpose now returns the withdrawn state; a send to the contact is blocked by your tenant’s consent gate (see consent-required blocked sends); and POST /api/v1/cdp/consent/{contactId}/{channel}/propagate-revocation pushes the withdrawal to your connected destinations with a per-destination audit row. An rtbf action goes further: it revokes every purpose and feeds the erasure-propagation pipeline, fanning the deletion out to every downstream store per CDP erasure propagation.
6. Prove it with an evidence binder
When counsel or a regulator asks “show me the basis for contacting these people”, the compliance evidence binder assembles the answer from the artifacts this guide created:- The per-identity ledger scroll,
GET /api/v1/cdp/consent/{contactId}: every grant and revoke withlawful_basis,consent_text_version,source,granted_at, andrevoked_at. - The re-consent surface,
GET /api/v1/cdp/consent/renewals: identities whose grants are expiring under your configured retention window, before they lapse. - The revocation trail from capture 2: per-destination propagation outcomes with timestamps.
- The per-message proof-of-consent receipt that binds each send to the consent record it relied on.
captured_at predates the send and whose consent_text_version matches the disclosure in force at capture.
See also
- CDP ingest signing — the signing contract every request in this guide carries
- CDP tracking plan — the strict-mode contract that rejects envelope-less events
- CDP erasure propagation — the destination fan-out a revocation or rtbf triggers
- Compliance profile wizard — pick the template before ingest
- Country rules posture playbook — pin quiet hours per country
- Consent and suppression model — how grants, suppression, and sends interact