Skip to main content

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). 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:
  1. Pick a compliance profile. Run the compliance profile wizard and choose the template that matches your market. The template you pick becomes the policy_template on every ledger row this source writes.
  2. Declare lawful basis per source. For each list or table you migrate, record the basis your counsel determined for it (consent for opted-in marketing lists, another basis only where counsel says so). You will attach it to every row from that source in section 3.
  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.
  4. 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).
Start from the shape your ledger actually holds. A typical three-column consent ledger export:
The envelope Orbit’s consent ledger stores has four fields: {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:
The 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

  1. 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.
  2. Identify each row. Send one signed /identify per row to /cdp/v1/:ingest_id/identify with the email in traits. The 200 response returns the contact_id the consent ledger keys on.
  3. Record the grant. For each row, append the durable consent decision with the mapped envelope:
The 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 signed track for a contact whose envelope fields you deliberately omitted. With the tracking plan in strict mode, expect a 422:
If that send returns 200, the tracking plan is still in soft mode; fix step 4 of section 4 before migrating real rows. Capture 2: a revocation propagates. Record a withdrawal for one sandbox contact:
Then verify the chain: 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 with lawful_basis, consent_text_version, source, granted_at, and revoked_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.
The migration is done when a sample of those receipts, pulled at random, each trace back to a ledger row whose captured_at predates the send and whose consent_text_version matches the disclosure in force at capture.

See also