Skip to main content
Languages: every operation supports cURL, Node.js (TypeScript), Python, Go, Ruby, and PHP. The first 15 operations on this page show all six languages; the remaining 105 show cURL and TypeScript — the two most-used.

Contacts API

Create, update, and manage your contact directory Base path: /api/v1/contacts Endpoint count: 120

title: “Contacts orientation: worked examples with full response bodies” description: “Hand-curated contact domain walk-through — create, set custom-field values, read back inline, and cursor-paginate the list, with the response bodies to copy.”

The contact resource

A contact is one record in your directory — phone, email, name, tags, consent, plus your own data layered on top. Custom-field values ride on the contact as the custom_fields object: set them on a contact and they come back inline on every contact response — create, read, list — with no separate lookup. Custom-field keys and their types are defined under /api/v1/custom-fields. Write a value with PUT /api/v1/custom-fields/values and read it back on the contact’s custom_fields object. Every response on this page follows the same envelope — data plus a meta block carrying request_id, timestamp, and, on list responses, pagination — so the examples below hold for every endpoint here. Errors follow Devotel Orbit’s { error, meta } envelope, shown once under Error envelope.

Worked sequence: create, set custom fields, read back

The run-through every integration does first: create the contact, attach your own data, then pull the contact back and see the values inline.

1. Create the contact

POST /api/v1/contacts/
At least one of phone or email is required. Send phone numbers in E.164 (+14155551234); display formats are normalized to E.164 before insert. Request
The new contact returns an empty custom_fields object until you set values.

2. Set custom-field values

PUT /api/v1/custom-fields/values
One call per field. key must match a custom-field definition you already created, and the value must match that definition’s type — values of the wrong type are rejected. Request

3. Read back — values inline

GET /api/v1/contacts/{id}
Request

Worked sequence: list with filters, then paginate

GET /api/v1/contacts/
Filters combine on the query string — tags=vip, country_code=US — search narrows by name, phone, or email. The response is cursor-paginated: while meta.pagination.has_more is true, pass meta.pagination.cursor back as the cursor query parameter to fetch the next page. Here the list is filtered to one tag. Request
has_more is true, so request the next page:
Treat the cursor as opaque. Keep the same filters across pages and stop when has_more comes back false.

Error envelope

Validation failures return 422 with a VALIDATION_ERROR code. The classic case is a phone value that fails the format and length checks — below the E.164 floor or not recognizable:
422
When you hit this on create or update, normalize the number to E.164 (country code, digits only, leading +) and retry. A missing-or-unknown custom-field key on PUT /custom-fields/values surfaces the same envelope with a four-hundred status, so handle both before you code a special case.

Duplicate detection and merge review

Two endpoints handle duplicate detection: a cheap aggregate count for banner surfaces and pre-merge checks, and the full group list you fetch when you open the merge workflow.
GET /api/v1/contacts/duplicates/count
Returns extras — the number of contacts that would be merged away — plus hasMore indicating whether duplicates exist beyond the slice the count scanned. Use it for banner headlines and pre-merge checks.
string
exact (default) or fuzzy. exact is the right choice for banner counts; fuzzy mirrors the detection pass the merge endpoint uses.
integer
Per-strategy group cap, default 100, range 1200. Raise it when hasMore returns true and you need to scan deeper before reporting “0 duplicates.”
Use GET /duplicates to fetch the full group list (with per-group contact records) when you actually render the merge review UI — fetching it just for a banner paints the contacts page with data you don’t read.

List contacts

GET /api/v1/contacts
Retrieve contacts with cursor-based pagination, search, and filtering.
string
Opaque cursor for the next page (from previous response meta.pagination.cursor)
any
Number of items per page (default 25). Values above the page-size cap are silently clamped; negative, fractional, or unparseable values fall back to the default. Never 422s.
Free-text search across name, phone, email
string
Filter by lifecycle stage
string
Filter by country code
string
Filter by company (contains)
string
Comma-separated tag filter
boolean
Only contacts with a phone number
boolean
Only contacts with an email address
string
Created after this date
string
Created before this date
string
Only contacts that have this custom-field key populated (in attributes or custom_attributes)
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get a contact by ID

GET /api/v1/contacts/{id}
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List activity

GET /api/v1/contacts/{id}/activity
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List campaigns

GET /api/v1/contacts/{id}/campaigns
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List cap-status

GET /api/v1/contacts/{id}/cap-status
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List channel-recommendations

GET /api/v1/contacts/{id}/channel-recommendations
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List channel-state

GET /api/v1/contacts/{id}/channel-state
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

GET /api/v1/contacts/{id}/consent
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get CRM context for a contact

GET /api/v1/contacts/{id}/crm-context
Returns a normalised, cross-CRM overlay for a single contact — linked records, deals/opportunities, recent activity, e-commerce orders and per-provider lifetime value — aggregated across every CRM the contact is linked to (HubSpot, Salesforce, Pipedrive, Zendesk, Intercom, Shopify, WooCommerce). One provider being slow or down never blanks the others: each provider’s outcome is reflected in a per-provider sections[].status. Powers the Inbox conversation “CRM Context” panel. Requires contacts:read (or contacts:write) scope; viewer-tier callers are rejected because the overlay can carry pipeline/deal-value data above their read scope.
string
required
Contact identifier.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Deliverability health for a contact on one channel

GET /api/v1/contacts/{id}/deliverability-health
Score one contact’s deliverability on a single channel (default sms) from the rolled-up outbound + inbound message signals, then apply the consent-suppression overlay — an externally suppressed (unsubscribe / hard-bounce / complaint list) or explicitly opted-out contact may NOT be sent to on that channel, regardless of how healthy the raw delivery record looks. The response carries the raw (pre-overlay) score with its auditable component breakdown, the sendable score (0 when blocked), the block reason (suppressed | opted_out | null), the label (healthy | watch | at_risk | consent_blocked | insufficient_data), and the insufficient-data flag for a sent: 0 cohort.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List duplicates

GET /api/v1/contacts/{id}/duplicates
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get a contact’s engagement profile

GET /api/v1/contacts/{id}/engagement
Return the per-contact engagement profile learned by the engagement-profiler: the contact’s best send window (best_hour_utc + best_dow + sample_count), last engagement timestamp, and message/SDK-event counters split so ops can sanity-check whether smart-send has enough signal yet. Use this to power the contact card’s engagement panel and to decide when smart-send timing can be trusted. Degrades to null counters on a freshly-migrated tenant rather than erroring.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get the enabled frequency-cap config rule rows (grouped_by_channel + global_caps) that apply to a contact

GET /api/v1/contacts/{id}/frequency-caps
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List a contact’s GDPR erasure requests

GET /api/v1/contacts/{id}/gdpr/erasure-requests
Return every GDPR Article-17 erasure request filed for a contact — each with its status (pending | executing | cancelled | completed), who requested it, and the cooling-off window. Use this to show the erasure history on the contact’s compliance tab and to find the pending request id to cancel via POST /:id/gdpr/erasure-request/:requestId/cancel.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Preview the data impact of a GDPR erasure/export

GET /api/v1/contacts/{id}/gdpr/preview
Return per-category row counts (messages, calls, notes, events, …) plus a total_records figure for everything that would be exported or deleted for a contact. Use this to render the “X messages, Y calls, Z notes — confirm?” summary before an operator triggers an irreversible GDPR delete. Returns 404 when the contact does not exist in the tenant.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Unified customer-journey timeline for a contact

GET /api/v1/contacts/{id}/journey
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Export the contact journey timeline as CSV

GET /api/v1/contacts/{id}/journey.csv
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List lists

GET /api/v1/contacts/{id}/lists
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Predictive next-best-action suggestions for a contact

GET /api/v1/contacts/{id}/next-best-action
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List notes for a contact

GET /api/v1/contacts/{id}/notes
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

GET /api/v1/contacts/{id}/preferences
Return the explicit per-channel consent state for a contact across all six channels (sms, whatsapp, rcs, viber, email, voice) using the tri-state model — opted_in, opted_out, or unknown — with the source and timestamp of the latest consent record for each. Also surfaces the tenant’s unknown_marketing_policy (refuse or allow_with_logging) so the UI can show whether marketing will send to contacts whose state is unknown. Use this to render a consent panel without inferring consent from absent keys (a TCPA/GDPR risk).
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Lightweight contact preview for the inbox hover-card

GET /api/v1/contacts/{id}/preview
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Customer 360 unified profile for a contact

GET /api/v1/contacts/{id}/profile
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get a contact’s predictive scores

GET /api/v1/contacts/{id}/scores
Return the per-contact predictive scoring blob — churn_risk, intent_score, propensity_score, ltv_estimate_cents, the derived segment_label and the raw signals the scores were computed from. Scores are recomputed nightly by the webhook-worker scoring scheduler. Use this to prioritise outreach or gate automations on a contact’s risk/propensity. Returns 200 with scored: false and null score fields when the contact has not been scored yet, rather than a 404.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List the segments a contact belongs to

GET /api/v1/contacts/{id}/segments
Return every contact segment the given contact is currently a member of. Membership is answered from a single source shared with the CDP profile / Customer 360 view — it unions the materialised contact_segment_members table (AST-filter and manually-curated segments) with live rule evaluation, so the answer matches the CDP profile by construction. Use this on the contact detail surface to show segment chips.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Unified chronological contact timeline (messages + calls + tickets + events)

GET /api/v1/contacts/{id}/timeline
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List currently-blocked contacts (audit #INX-F-011).

GET /api/v1/contacts/blocked
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Download a background contacts export

GET /api/v1/contacts/bulk/exports/{id}/download
Download the CSV file produced by a completed POST /contacts/bulk/export job, by export id. The response streams the raw file (text/csv) rather than the { data, meta } envelope; a short-lived download token in the export job detail authorizes the fetch. Use it after polling the export job until status is completed. Owner, admin, or developer role.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Poll a bulk contact operation’s progress

GET /api/v1/contacts/bulk/jobs/{id}
Read one bulk-operation job’s lifecycle — status, total / processed / failed counters, started_at / completed_at, and error_message — for tag/segment/delete/export/send/update-properties ops launched through the bulk routes. Poll it after an enqueue call until the status settles; 404 when the id does not resolve for your tenant. Owner, admin, or developer role.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List duplicate contact groups

GET /api/v1/contacts/duplicates
List detected duplicate-contact groups for review before merging. ?strategy=exact (default) groups contacts sharing an identical email or phone; ?strategy=fuzzy also groups similar names, honouring an optional ?threshold similarity score. Cursor-paginated via ?cursor/?limit. Contact PII is masked unless the caller has an owner/admin/developer role and passes ?reveal=true (each unmasked read is audit-logged).
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Count potential duplicate contacts

GET /api/v1/contacts/duplicates/count
Cheap aggregate count of duplicate-contact groups. Returns extras (the number of contacts that could be merged away — the operator-visible ‘N potential duplicates’ figure) computed over a bounded slice of groups, and hasMore indicating whether duplicates exist beyond that slice. Strategy defaults to exact; fuzzy mirrors the full detection pass.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Export customer events (NDJSON stream)

GET /api/v1/contacts/events/export
Stream the tenant’s customer events as newline-delimited JSON (application/x-ndjson) for data-warehouse sync. Pass the timestamp of the last ingested event as the required since cursor and only the delta is returned; until (optional, defaults to now) bounds the upper edge and limit (default 5000, capped at 20000) bounds the batch. Read the last line’s timestamp and re-issue with since=<that timestamp> to paginate.
string
required
Required ISO 8601 lower bound — events at or after this timestamp are returned.
string
Optional ISO 8601 upper bound; defaults to now.
integer
Max rows returned (default 5000, capped at 20000).
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List recent contact import jobs

GET /api/v1/contacts/import-jobs
List this tenant’s contact bulk-import history — one entry per CSV/XLSX upload — newest first, cursor-paginated via ?cursor/?limit. Use it to power the imports history page or to check the row-level outcome (total/imported/skipped counts) of a previous import; pair it with GET /contacts/import-jobs/{id}/skipped.csv for the skipped-rows detail.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Download skipped-rows CSV for a contact import job

GET /api/v1/contacts/import-jobs/{id}/skipped.csv
Download a text/csv attachment listing every row an import job skipped, with a Content-Disposition: attachment header so browsers save it as a file. Columns are row_index, reason, plus the union of the original upload headers so the row can be located in the source file. Use it after POST /contacts/imports reports non-zero skipped rows. Returns 404 when the job id does not exist for the caller’s tenant.
string
required
Resource identifier
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get contact import job status

GET /api/v1/contacts/imports/{id}
Poll the progress of an asynchronous contact import previously queued via POST /contacts/imports. Returns the current status (pending, processing, completed, failed, or cancelled), the total / processed / failed row counts, start and completion timestamps, and a sample of per-row validation errors. The import wizard polls this endpoint until the job reaches a terminal state.
string
required
Resource identifier
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List contact lists

GET /api/v1/contacts/lists
Retrieve the tenant’s contact lists with cursor-based pagination. Optionally filter by a free-text search term matched against list name and description. Each row carries the list id, name, description, cached member count and timestamps. Powers the Lists dashboard tab and the list pickers in bulk / campaign flows.
string
Opaque cursor for the next page (from previous response meta.pagination.cursor)
any
Number of items per page (default 25). Values above the page-size cap are silently clamped; negative, fractional, or unparseable values fall back to the default. Never 422s.
string
Free-text filter across list name and description.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List members of a contact list

GET /api/v1/contacts/lists/{id}/members
Retrieve the contacts that belong to a list, cursor-paginated and ordered by when they were added. Accepts an optional q filter — either a Stripe-style search DSL (e.g. email:*@example.com) or plain free text matched across the member’s name, phone and email. Powers the list-members panel in the dashboard.
string
required
Resource identifier
string
Opaque cursor for the next page (from previous response meta.pagination.cursor)
any
Number of items per page (default 25). Values above the page-size cap are silently clamped; negative, fractional, or unparseable values fall back to the default. Never 422s.
string
Optional member filter — a field:op:value search-DSL expression (max 256 chars) or plain free text.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get contact-list stats

GET /api/v1/contacts/lists/stats
Return the tenant-wide aggregate totals for the Lists dashboard header cards: the number of contact lists and the total contact count across them, computed in a single server-side query. Use this instead of paginating through GET /contacts/lists just to sum the two numbers. On a transient availability failure the response may carry meta.degraded: true with all-zero placeholder counts — treat the all-zero values as non-authoritative and retry.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List contact merge history

GET /api/v1/contacts/merge-history
Return the organisation’s most recent contact.merged / contact.unmerged events (newest first), resolved into human-readable primary and secondary contact labels for the dedup Merge History table. Accepts an optional limit query parameter (1-100, default 25). This is a tenant-scoped read of the audit trail; chain hashes are intentionally omitted (chain inspection stays admin-only). data carries the entries list plus the total number of entries returned.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List opted-out contacts

GET /api/v1/contacts/optouts
Retrieve the tenant’s opt-out (suppression) records with opaque cursor pagination. Optional channel (sms, email, whatsapp, voice, rcs, …) and free-text search (across contact identifier and reason) query parameters narrow the list; an empty or repeated filter degrades gracefully to “no filter” rather than erroring, so the Compliance → Opt-outs tab always returns a page.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List contact predictive scores

GET /api/v1/contacts/scores
Return the tenant’s per-contact predictive scores — churn risk, intent, propensity, LTV estimate and the derived health segment_label — with cursor pagination. Filter by segment_label and sort by any score column via sort (prefix - for descending; default churn_risk DESC), so the dashboard “At Risk” and “Champions” panels render without an N+1 back to each contact. On a transient read blip a last-known-good page is served with meta.degraded: true rather than a 5xx.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get contact-score segment histogram

GET /api/v1/contacts/scores/histogram
Return tenant-wide contact counts bucketed by predictive health segment_label — the aggregate behind the dashboard’s “Customer health” chart. Every known segment key (champion, high_value_engaged, engaged, new, passive, at_risk, dormant, lost) is always present, defaulting to 0. A transient read blip degrades to the last-known-good (or all-zero) histogram with meta.degraded: true instead of a 5xx.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List a tenant’s contact segments

GET /api/v1/contacts/segments
Return the tenant’s contact segments using opaque cursor pagination (limit, cursor), each row carrying its cached contact_count. An optional search query parameter filters by name/description (trimmed, ≤200 chars, blank = no filter) so the Segments dashboard tab offers the same server-side search box as its sibling Audience tabs. Pagination metadata is returned under meta.pagination.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get a single contact segment

GET /api/v1/contacts/segments/{id}
Return one contact segment by id — its name, description, rule definition (the filters AST or the legacy rules shape), auto-refresh settings and cached contact_count — wrapped in the standard { data, meta } envelope. Returns 404 when the id does not exist in the tenant.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List a segment’s rule-definition version history

GET /api/v1/contacts/segments/{id}/definition-history
List the segment’s superseded rule DEFINITIONS (name, description, rules, filters, who changed it, when), newest first. Unlike size-history (audience size) and snapshots (frozen membership), this returns the filter/predicate that produced the audience at each prior version so an operator can pick one to revert to. Returns an empty list when the segment has no prior definitions yet rather than erroring.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Deliverability-health rollup for a contact segment

GET /api/v1/contacts/segments/{id}/deliverability-health
Roll the per-contact deliverability-health blend up over the segment’s materialised members on a single channel (default sms). The response carries the mean raw health of the sendable population (pre-overlay signal), the honest suppressed / opted-out counter split (the consent overlay — a healthy-but-blocked contact is a BLOCKED send, never a good send), and the reachable share of the segment, the same overlay the per-contact endpoint applies. Capped at the first-N materialised members so a 50k-member segment renders a bounded dashboard rollup.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Export a segment’s members as CSV

GET /api/v1/contacts/segments/{id}/export.csv
Stream the segment’s resolved member list as an RFC-4180 CSV download (Content-Disposition: attachment, chunked transfer). An auto-refreshing segment is re-evaluated on demand first so the file reflects current membership. One row per contact with contact_id, first_name, last_name, email, phone, country_code, lifecycle_stage, tags, created_at, segment_added_at; timestamps honour the optional ?tz= IANA zone. Rate-limited to 5 requests/minute/tenant.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List a segment’s members

GET /api/v1/contacts/segments/{id}/members
Return the contacts in a segment’s materialised membership table, using opaque cursor pagination (limit, cursor) keyed on (segment_added_at, id). This reads the last-materialised snapshot — call POST /segments/:id/refresh first if you need the very latest audience. Pagination metadata is returned under meta.pagination.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Segment performance & ROI (spend vs attributed revenue)

GET /api/v1/contacts/segments/{id}/performance
Per-segment readout over a 7/30/90-day window: message / delivery / failure / read rates, total spend + cost-per-message, attributed revenue (via journey goal conversions), ROAS and net return — all joined back to the segment’s current membership. Pass ?window=7d|30d|90d (default 30d).
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get a segment’s audience-size history

GET /api/v1/contacts/segments/{id}/size-history
Return the audience-size-over-time series ({ contact_count, snapshot_at } points) recorded after each refresh tick — the data behind the “Audience over time” chart (Braze / Iterable / Customer.io parity). Defaults to the last 30 days; narrow with optional since / until (ISO-8601) and limit (1-1000, default 200) query parameters.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List a segment’s point-in-time audience snapshots

GET /api/v1/contacts/segments/{id}/snapshots
List the segment’s frozen, versioned audience snapshots, newest first. Each row carries the member_count captured at snapshot_at plus the optional operator-supplied label. Returns an empty list when the segment has no snapshots yet rather than erroring.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List the frozen membership of one segment snapshot

GET /api/v1/contacts/segments/{id}/snapshots/{snapshotId}/members
Read the paginated point-in-time membership of one frozen audience snapshot — the audience exactly as it was when the snapshot was taken. Opaque cursor pagination (limit, cursor) mirrors the live segment-members endpoint.
string
required
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Diff cohort drift between two segment snapshots

GET /api/v1/contacts/segments/{id}/snapshots/diff
Compute cohort drift between two snapshots of the same segment. joined are contact ids present in the to snapshot but not from, left are present in from but not to; joined_count / left_count are the authoritative sizes. Both from and to snapshot ids are required query params.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get authoritative per-tenant segment totals

GET /api/v1/contacts/segments/stats
Return the authoritative per-tenant segment totals ({ totalSegments, totalMembers }) computed with one server-side COUNT/SUM across every segment — the numbers behind the Segments page subtitle. Use this instead of summing the paginated GET /segments rows, which understates both totals once a tenant has more than one page.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Get aggregate contact stats for the tenant

GET /api/v1/contacts/stats
Return the authoritative per-tenant contact summary the dashboard header cards read: total, active, leads, newThisMonth (with the newThisMonthSince cut-off) and optedOut. Computed server-side in a single aggregate pass so the totals stay correct across every page, unlike a client-side reduce over only the loaded list. Honours the same optional list filters (search, segment_label, has_custom_field) so the cards reflect the same subset the list is showing.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

List lifecycle

GET /api/v1/contacts/stats/lifecycle
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Unified contact snapshot

GET /api/v1/customer-360/contacts/{id}/snapshot
Returns the unified Customer-360 snapshot for one contact: profile, engagement summary, recent calls and video sessions, message summaries, CRM context, and AI-assist suggestions, with the caller’s PII-visibility rules applied. Viewers see masked PII unless they hold the unmask permission.
string
required
Contact id (the tenant’s own contact identifier, up to 128 characters).
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Create a contact

POST /api/v1/contacts
Create a new contact. At least one of phone or email is required.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Phone number in international (E.164) format, e.g. +14155552671. Display formats (+1 (415) 555-1234) and PBX-extension suffixes (+14155551234 x1234) are accepted and normalized server-side to E.164 before insert. Optional when an email (or other identifier) is supplied — a blank/empty string is treated as omitted; a non-empty value must be at least 3 characters (the E.164 floor).
string
Email address
string
First name
string
Last name
string
Display name
string
Company or organization
string
ISO 3166-1 alpha-2 country code
string
IANA timezone identifier
string
ISO 639-1 language code
string[]
Contact tags
object
Custom attributes

Block a contact. Inbound messages auto-route to Spam; outbound is rejected.

POST /api/v1/contacts/{id}/block
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Create channel-recommendations

POST /api/v1/contacts/{id}/channel-recommendations
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

POST /api/v1/contacts/{id}/consent
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Mint a re-auth challenge for GDPR deletion

POST /api/v1/contacts/{id}/gdpr/delete/challenge
Mint a single-use, 5-minute re-authentication token for the irreversible GDPR delete of a contact. Call this first, then pass the returned token in the X-Reauth-Challenge header on DELETE /:id/gdpr/delete within 5 minutes — the delete returns 401 REAUTH_REQUIRED without a fresh, valid challenge. This step-up guards against an accidental or hijacked one-click erasure. Requires an authenticated user (401 otherwise).
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

File a GDPR right-to-erasure request

POST /api/v1/contacts/{id}/gdpr/erasure-request
Open a GDPR Article-17 right-to-erasure request for a contact. Unlike the immediate DELETE /:id/gdpr/delete cascade, this starts a cancellable cooling-off period (per-tenant, default 7 days) after which the webhook-worker scheduler hard-deletes the contact and writes a per-resource audit chain. Returns 202 with the created request (including cooling_off_ends_at), 404 if the contact does not exist, and 409 ERASURE_COOLING_OFF_ACTIVE when a request is already pending or executing.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Cancel a pending GDPR erasure request

POST /api/v1/contacts/{id}/gdpr/erasure-request/{requestId}/cancel
Cancel a still-pending GDPR Article-17 erasure request during its cooling-off period, so the scheduled hard-delete never runs. An optional free-text reason (≤500 chars) is recorded on the audit trail. Returns 404 when the request id does not belong to this contact, and 409 CONFLICT once the request has moved out of pending (executing/completed/already-cancelled).
string
required
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Export a contact’s personal data (GDPR DSAR)

POST /api/v1/contacts/{id}/gdpr/export
Assemble and return everything the platform holds about a contact for a GDPR Article-15 subject-access / data-portability request — the contact profile plus, when include_messages=true, their message history. Rate-limited (an export-specific limiter) and audit-logged as contact.gdpr_export. Use this to fulfil a data-subject-access request; pair it with the erasure-request flow for Article-17.
string
required
boolean
Include the contact’s message history in the export (default false — profile fields only).
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Create a note on a contact

POST /api/v1/contacts/{id}/notes
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Add tags to a contact

POST /api/v1/contacts/{id}/tags
Append one or more tags to a contact (1–50 tags per call, each 1–50 chars). Tags are merged with the contact’s existing set — duplicates are ignored — and the full de-duplicated tag list is returned. Use tags to drive segment rules, filtering and audience building. Tag caches are invalidated so segment membership re-evaluates on the next refresh.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string[]
Tags to append (1–50 items, each 1–50 chars).

Unblock a contact.

POST /api/v1/contacts/{id}/unblock
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk contact actions

POST /api/v1/contacts/actions
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk import contacts

POST /api/v1/contacts/bulk
Import up to 10,000 contacts in a single request. Each contact must have at least a phone (E.164-ish) or email. Returns inserted/skipped counts plus an import_job_id that can be used to download the skipped-rows CSV (GET /import-jobs/{id}/skipped.csv) and to roll back within 24 hours.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object[]
required
object[]
object[]
integer

Bulk delete contacts (soft delete)

POST /api/v1/contacts/bulk-delete
Legacy alias of POST /contacts/bulk/delete kept for older SDKs: soft-deletes an explicit contact_ids list (1-1000 ids) and emits one contact.deleted webhook per tombstoned id. New integrations should take the canonical selector route (contact_ids OR filters AST) instead. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk soft-delete contacts by selector

POST /api/v1/contacts/bulk/delete
Soft-delete a selection of contacts — EITHER an explicit contact_ids list (up to 50 000) OR a filters AST, exactly one selector required. Use it for one-off clean-up of an audience picked in the dashboard table; for GDPR-grade full erasure prefer the erasure endpoints. The lane is rate-limited to 10 bulk starts per tenant per minute. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Start a background contacts export by selector

POST /api/v1/contacts/bulk/export
Enqueue a background CSV export of a contact selection — EITHER an explicit contact_ids list OR a filters AST, exactly one selector required — including every custom-field value. Body: format: "csv" and an optional IANA timezone (renders the timestamp columns in the requester’s local zone; falls back to UTC when garbage). Use it for audiences above the 10 000-row synchronous GET /contacts/export ceiling; download the finished file via GET /contacts/bulk/exports/{id}/download. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk add/remove contacts to a segment by selector

POST /api/v1/contacts/bulk/segment
Add or remove a contact selection on a segment in one atomic write — body: segment_id, action: "add" | "remove", plus EITHER an explicit contact_ids list OR a filters AST, exactly one selector required. Cheaper than per-contact membership writes when a dashboard selection or shared filter already names the audience. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Start an ad-hoc blast to a contact selection

POST /api/v1/contacts/bulk/send
Launch an ad-hoc broadcast campaign on a contact selection — body: name, channel (sms/whatsapp/rcs/viber/email/messenger/instagram/voice), message_template, optional subject, optional ISO scheduled_at, plus EITHER an explicit contact_ids list OR a filters AST, exactly one selector required. Use it to fire a one-off audience blast straight from the contacts table without building a campaign first; compliance/quiet-hours gates apply exactly as in the campaigns wizard. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk add/remove tags on contacts by selector

POST /api/v1/contacts/bulk/tag
Apply or remove tags across a contact selection atomically — body: action: "add" | "remove" plus EITHER tag (one tag, legacy SDK shape) OR tags (1-25 tag names), and EITHER an explicit contact_ids list OR a filters AST, exactly one selector required. Use it to clean up segmentation taxonomies on a large audience in one transaction instead of per-contact tag writes. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bulk update contact properties by selector

POST /api/v1/contacts/bulk/update-properties
Mass-correct profile properties and/or definition-backed custom fields across a contact selection — body: optional lifecycle_stage (canonical stage), optional properties patch of up to 50 custom-field keys (at least one mutation surface required), plus EITHER an explicit contact_ids list OR a filters AST, exactly one selector required. The write is a MERGE, not a replace: unlisted fields on each contact are preserved. Use it to fix a mislabeled stage or flip a mispressed custom field across an audience in one pass. Owner, admin, or developer role.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Scan for duplicate contacts

POST /api/v1/contacts/duplicates/scan
Scan the tenant’s contacts and return groups of probable duplicates, matching on normalized email (case-insensitive) and normalized phone (E.164-format tolerant). Each group lists the matching contact ids, the field they matched on, the matched value, and the group size. Read-only: follow up with the merge endpoint to consolidate a group.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Enrich contacts (bulk)

POST /api/v1/contacts/enrich
Enrich up to 200 contacts per call using the tenant’s configured enrichment provider (domain-based analysis). Pass the contact ids to process; the response reports how many were enriched, the total requested, and configuredfalse when no enrichment provider is wired, so the client can show an honest ‘enrichment not configured’ instead of a misleading ‘no new data’.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string[]
required
Contact ids to enrich (1–200 per request).

Export contacts

POST /api/v1/contacts/export
Export up to 10,000 contacts matching an optional { search, list_id, segment_id, timezone } filter as a downloadable file — CSV by default, or XLSX via ?format=xlsx — including every custom-field value. Requires an owner/admin/developer role; each attempt is audit-logged (contact.exported). Use this for a one-off download; for a background job on larger audiences use POST /contacts/bulk/export instead.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Enqueue an asynchronous contact import

POST /api/v1/contacts/imports
Queue a large contact import for asynchronous processing instead of inserting rows synchronously. Accepts already field-mapped rows (up to 1,000,000) plus an optional file_name and merge_strategy (skip the existing contact, or merge to update it). Creates a pending import job and returns its job_id; poll GET /contacts/imports/{id} for progress. Retry POST after a few seconds when the queue is unavailable (503).
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object[]
required
Already field-mapped rows keyed by contact field (phone, email, first_name, …).
string
Original upload filename shown in the imports history.
string (enum: skip|merge)
How to treat a row whose phone/email matches an existing contact: skip (default) leaves the existing contact untouched; merge updates it.

Cancel a running contact import

POST /api/v1/contacts/imports/{id}/cancel
Request cancellation of an in-progress contact import. Stamps a cancel marker the import worker re-reads between batches, so it stops enqueuing further rows and flips the job to cancelled. Best-effort: rows already inserted remain — follow with POST /contacts/imports/{id}/rollback to remove them. Returns 409 when the job is not active (already completed, failed, or cancelled).
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Roll back a completed contact import

POST /api/v1/contacts/imports/{id}/rollback
Delete every contact created by a completed / cancelled / failed import job, together with their list and segment memberships, scores, engagement profiles and consent records, in a single transaction. Allowed only within 24 hours of completion so later imports carrying downstream artefacts can’t be silently orphaned. Returns per-table deletion counts. Returns 404 when the job does not exist and 409 when it was already rolled back or the 24-hour window has expired.
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Preview a contact import (dry run)

POST /api/v1/contacts/imports/preview
Dry-run validation the import wizard runs before starting an import. Accepts the same already-mapped rows payload as POST /contacts/imports (up to 10,000 rows) and, without writing anything, returns the total row count, a normalized preview of the first 10 rows, validation counters (rows with a phone / email, invalid rows, and sample errors), and duplicate detection both against existing contacts and within the upload itself.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object[]
required
Already field-mapped rows keyed by contact field (phone, email, first_name, …).

Create a contact list

POST /api/v1/contacts/lists
Create a new static contact list the tenant can populate manually or via bulk operations. A name is required; an optional description documents the list’s purpose. Returns the created list row — use its id with POST /contacts/lists/{id}/members to add contacts.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
List name.
string
Optional description of the list’s purpose.

Duplicate a contact list

POST /api/v1/contacts/lists/{id}/duplicate
Clone a contact list INCLUDING all of its current members in a single transaction. Returns the new list row plus members_copied (how many membership rows were copied) and source_list_id (the cloned list’s id). The body is optional: omit it (or send {}) and the new list gets “<source name> (copy)” with the source description. Use this when you want a working copy of an existing list without re-adding members by hand.
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Name for the new list. Defaults to “<source> (copy)”.
string
Description for the new list. Defaults to the source list’s.

Add a contact to a list

POST /api/v1/contacts/lists/{id}/members
Add a single contact to a list. Provide EXACTLY ONE of contact_id (a canonical contact id) or identifier (a phone number, email, or contact id resolved to a contact server-side). Idempotent: re-adding an existing member returns 200 with already_member: true instead of creating a duplicate, while a freshly-added member returns 201.
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Canonical contact id (e.g. cnt_…).
string
Phone number, email, or contact id resolved to a contact server-side.

Add multiple contacts to a list

POST /api/v1/contacts/lists/{id}/members/bulk
Add up to 1,000 contacts to a list in a single request. Existing memberships are skipped (idempotent) and any id whose contact record does not exist is reported back in failed_contact_ids. Returns the number added, the total requested, and the list of failures. Far cheaper than issuing individual add-member calls for large selections.
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string[]
required
Canonical contact ids to add.

Merge duplicate contacts

POST /api/v1/contacts/merge
Merge one or more secondary contacts into a primary contact. Returns a merge_id and a 30-minute undo window.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Opt a contact out of a channel

POST /api/v1/contacts/optouts
Record a consent withdrawal for one contact on one channel. Identify the contact by phone or email in contact; channel is normalised (trimmed + lower-cased) before validation and reason is stored on the consent trail. A genuine opt-out returns 201 and fans out the contact.opted_out webhook; a duplicate opt-out of an already-suppressed contact returns 200 with data.already_opted_out: true and is not re-audited.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Contact identifier — phone (E.164) or email.
string
Channel to suppress (sms, email, whatsapp, voice, rcs, …); case-insensitive.
string
Why the contact opted out (1-500 chars).

Bulk opt contacts out

POST /api/v1/contacts/optouts/bulk
Suppress up to 500 contacts in one request — the batched path behind the suppression-file (CSV) import wizard. Each row is processed independently, so successes, already-suppressed skips and per-row failures are isolated and one bad row never fails the batch. Returns HTTP 207 with a { total, succeeded, skipped, failed, results[] } summary carrying an actionable per-row status and error message.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object[]
Opt-out rows (1-500 — chunk larger suppression files client-side).

Export opted-out contacts

POST /api/v1/contacts/optouts/export
Export the tenant’s opt-out (suppression) list as a JSON array, optionally filtered to a single channel. Capped at 10,000 rows per call. Use it to back up the suppression list or reconcile it with an external consent-of-record system. Returns { contacts, total }.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Optional channel filter (sms, email, whatsapp, voice, …). Omit to export every channel.

Create a contact segment

POST /api/v1/contacts/segments
Create a new contact segment from either the filters AST (AND/OR groups of conditions) or the legacy rules shape, with an optional auto_refresh flag (default true) and per-segment cadence. When a rule definition is supplied the membership is materialised inline — so the segment’s contact count and members are live immediately, without waiting for the refresh scheduler. Returns 201 with the created, already-materialised segment.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Display name (1-200 chars).
string
Optional description (up to 1000 chars).
object
AND/OR filter AST that defines the segment’s membership.
object
Legacy { operator, conditions } rule shape, still accepted for backwards compatibility.
boolean
Whether the scheduler re-materialises membership automatically.
integer
Per-segment refresh cadence in minutes (1-1440).

Revert a segment to a prior rule definition

POST /api/v1/contacts/segments/{id}/definition-history/{versionId}/revert
Restore a prior rule DEFINITION (one-click rollback of a bad filter edit). Re-applies the version’s name / rules / filters and re-materialises membership, then records the definition it replaced so the revert is itself reversible. 404 if the segment or the version does not exist.
string
required
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Re-evaluate a segment and rebuild its membership

POST /api/v1/contacts/segments/{id}/evaluate
Re-run the segment’s rules and transactionally rebuild its materialised contact_segment_members rows, refreshing the cached contact count and last_evaluated_at. Use this after editing data (not rules) to force the audience and its members list back into sync on demand, without waiting for the periodic refresh scheduler. Returns the evaluation result (matched count + timing).
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Preview an AI lookalike expansion of a segment

POST /api/v1/contacts/segments/{id}/expand
Generate a lookalike-audience PREVIEW (“customers like my best customers”) for a seed segment: embed a sample of its members’ cohort signals into a centroid and run a vector k-NN to propose net-new contacts that resemble the seed — WITHOUT writing any membership. Optional JSON body tunables: limit (1-500, default 50 candidates) and sample_size (1-200, default 50 seed members). When the embedding gateway is not configured the endpoint returns 200 with { available: false, reason } so the dashboard can render a hint rather than an error.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Materialize a lookalike preview into a static segment

POST /api/v1/contacts/segments/{id}/materialize-lookalike
Promote an AI lookalike PREVIEW into a persisted, static contact segment ready for one-click audience activation. Runs the same centroid-k-NN scoring as /expand (so the materialized set equals the preview), then persists the net-new candidates as a NEW static segment (no rules/filters, auto_refresh=false) whose segment_id feeds the CDP audience-activation surface. Returns 201 with materialized: true and the new segment; when the preview yields no candidates it returns 200 with materialized: false and a reason, persisting nothing.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Manually refresh a segment’s membership

POST /api/v1/contacts/segments/{id}/refresh
Re-materialise a single segment’s membership on demand — the same work the periodic auto-refresh scheduler does for every segment, run now for just this one. Recomputes the audience, fans out contact.entered_segment / contact.exited_segment webhooks for the crossing diff, and records an audience-size history point. Returns the refresh result (matched count + timing).
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Freeze a segment’s membership as a point-in-time snapshot

POST /api/v1/contacts/segments/{id}/snapshots
Capture the segment’s CURRENT materialised membership as a versioned, point-in-time audience snapshot. Returns 201 with the new snapshot_id + frozen member_count. Operators can later list versions, read the frozen membership, diff cohort drift between two snapshots, or pin the snapshot as a campaign audience.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Estimate an unsaved segment’s audience size

POST /api/v1/contacts/segments/estimate
Return a FAST (sub-second) APPROXIMATE audience-size estimate for a filter AST using the query planner’s row estimate — no full COUNT scan. Designed to fire on every keystroke in the rule-builder while the exact POST /segments/preview runs in parallel. Returns a 400 INVALID_FILTER when the AST references an unknown field or operator.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object
required
The AND/OR filter AST to estimate ({ op, conditions }).

Create a segment from a natural-language prompt (AI)

POST /api/v1/contacts/segments/from-prompt
AI segment builder: translate a natural-language audience description into a structured rule AST, persist it as a new segment, and materialise its membership inline — so the audience is live immediately, exactly like a hand-built segment. Used by the MCP create_segment_from_prompt tool. Returns 503 when no LLM provider is configured (fall back to POST /segments with explicit rules) and 422 when the model output can’t be coerced into a supported rule shape.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Name for the new segment (1-200 chars).
string
required
Natural-language description of the audience to build (1-2000 chars).

Analyse audience overlap across segments

POST /api/v1/contacts/segments/overlap
Compute the audience overlap across 2-10 contact segments (Braze / Iterable / Customer.io / Segment parity): per-segment current sizes, total intersection_count (members of ALL ids), union_count (members of AT LEAST ONE), the Jaccard index, and the pairwise overlap matrix in input order for the heatmap. Reads the live membership table, so a freshly-refreshed segment shows its true current size.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string[]
required
The 2-10 segment ids to compare (de-duplicated server-side).

Preview an unsaved segment filter

POST /api/v1/contacts/segments/preview
Evaluate a filter AST WITHOUT persisting anything and return the exact matched count plus the first 10 matching contacts. Powers the live preview in the rule-builder UI as the operator edits conditions. For a fast, approximate size estimate on every keystroke use POST /segments/estimate instead; for the persisted count use POST /segments/:id/evaluate.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object
required
The AND/OR filter AST to evaluate ({ op, conditions }).

Suggest segment rules from a prompt (AI, no persist)

POST /api/v1/contacts/segments/suggest-rules
AI segment builder (suggest-only): translate a natural-language description into the segment evaluator’s { field, operator, value } rule vocabulary and return the derived operator + flattened rules WITHOUT persisting a segment. This is a direct API/integration primitive for callers that only want the suggested rules; the Orbit dashboard’s own “Suggest” action calls the combined POST /segments/autopilot endpoint instead, which returns the same suggestion plus a live match-count preview in one round-trip, so it intentionally has no dashboard UI caller of its own. Returns 503 when no LLM provider is configured. Unlike POST /segments/from-prompt, this persists nothing.
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
required
Natural-language description of the audience (1-2000 chars).

Unmerge contacts

POST /api/v1/contacts/unmerge/{mergeId}
Revert a contact merge within the 30-minute undo window using its merge_id.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Update a contact

PUT /api/v1/contacts/{id}
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
Phone number in E.164 format, e.g. +14155552671. Send null or an empty string to clear it.
string
Email address. Send null or an empty string to clear it.
string
First name (max 100 characters).
string
Last name (max 100 characters).
string
Display name (max 200 characters).
string
Company or organization (max 200 characters).
string
ISO 3166-1 alpha-2 country code. Send null or an empty string to clear it.
string
IANA timezone identifier.
string
ISO 639-1 language code.
string[]
Contact tags (max 50).
string (enum: lead|contacted|prospect|in_progress|active|customer|re_engagement|inactive|churned|archived)
Lifecycle stage. Moving an archived contact to another stage also requires unarchive: true.
object
Custom attributes.

PUT /api/v1/contacts/{id}/preferences
Update a contact’s per-channel consent preferences using the tri-state model (opted_in | opted_out | unknown). Accepts a partial map keyed by channel (sms, whatsapp, rcs, viber, email, voice) — only the channels supplied are changed. Alongside merging the legacy channel_preferences JSONB, each real transition writes an explicit consent_records row and emits the matching CONTACT_OPTED_IN / CONTACT_OPTED_OUT webhook, so the canonical consent audit trail and any subscriber mirror stay in sync.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
object
Partial map of channel → consent state (opted_in | opted_out | unknown). Only the channels present are updated.

Update a contact list

PUT /api/v1/contacts/lists/{id}
Rename a contact list or change its description. Both fields are optional — supply only the ones you want to change. Returns the updated list row, or 404 when no list with that id exists for the caller’s tenant.
string
required
Resource identifier
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
New list name.
string
New description.

Update a contact segment

PUT /api/v1/contacts/segments/{id}
Edit a contact segment’s name, description, rule definition (the filters AST or the legacy rules shape) or auto-refresh cadence. Changing the rule definition re-materialises membership immediately — so the contact count and members are live without waiting for the refresh scheduler — and snapshots the superseded definition so the edit can be rolled back from the definition history.
string
required
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
New display name (1-200 chars).
string
New description (up to 1000 chars).
object
AND/OR filter AST that defines the segment’s membership.
object
Legacy { operator, conditions } rule shape, still accepted for backwards compatibility.
boolean
Whether the scheduler re-materialises membership automatically.
integer
Per-segment refresh cadence in minutes (1-1440).

Update a contact note

PATCH /api/v1/contacts/{id}/notes/{noteId}
Update the text or pinned flag of an existing note on a contact. Send content, pinned, or both — at least one is required. Pinned notes float to the top of the contact’s notes list. Returns the updated note in the standard { data, meta } envelope, or 404 when no note with that id belongs to the contact.
string
required
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
string
New note text (1–10,000 characters).
boolean
Whether the note is pinned to the top of the list.

Delete memory

DELETE /api/v1/contacts/{contactId}/memory
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Delete a contact

DELETE /api/v1/contacts/{id}
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

DELETE /api/v1/contacts/{id}/consent/{channel}
string
required
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Delete all of a contact’s data (GDPR right-to-erasure)

DELETE /api/v1/contacts/{id}/gdpr/delete
Synchronously cascade-delete a contact and everything the platform holds about them — messages, calls, notes, events, engagement/consent rows and long-term agent-memory vectors — for a GDPR Article-17 right-to-erasure. This is the immediate emergency path; for the cancellable 7-day cooling-off workflow use POST /:id/gdpr/erasure-request instead. Requires a fresh re-auth token in X-Reauth-Challenge (mint one via POST /:id/gdpr/delete/challenge) or it returns 401 REAUTH_REQUIRED. The action is irreversible and audit-logged.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content

Delete a contact note

DELETE /api/v1/contacts/{id}/notes/{noteId}
Permanently remove a single note from a contact. Identified by both the contact id and the noteId so a note can only be deleted through its owning contact. Succeeds with 204 No Content and no body; returns 404 when no note with that id belongs to the contact.
string
required
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content

Delete tags

DELETE /api/v1/contacts/{id}/tags/{tag}
string
required
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Delete a contact list

DELETE /api/v1/contacts/lists/{id}
Permanently delete a contact list and its membership rows. The contacts themselves are NOT deleted — only their membership in this list is removed. Returns 204 No Content on success and 404 when the list does not exist for the caller’s tenant.
string
required
Resource identifier
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content

Remove a contact from a list

DELETE /api/v1/contacts/lists/{id}/members/{memberId}
Remove a single contact’s membership from a list. The memberId path segment is the contact id to remove. The contact record itself is unaffected — only the list membership is deleted. Returns 204 No Content on success.
string
required
Contact list identifier.
string
required
Contact id of the member to remove.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content

Re-opt a contact in for a channel

DELETE /api/v1/contacts/optouts/{id}/{channel}
Remove an opt-out so a previously-suppressed contact can be messaged again on the given channel. Identify the contact by its canonical id in the path and the channel to restore. A genuine re-opt-in is audited and fans out the contact.opted_in webhook; re-opting-in an already-opted-in contact is idempotent and fires nothing. Returns the updated contact.
string
required
Canonical contact id.
string
required
Channel to re-enable (sms, email, whatsapp, voice, …).
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Delete a contact segment

DELETE /api/v1/contacts/segments/{id}
Permanently delete a contact segment and its materialised contact_segment_members rows. The underlying contacts are NOT deleted — only their membership in this segment is removed. The deletion is recorded in the tenant audit log. Returns 204 No Content.
string
required
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.
Response: 204 No Content