Skip to main content
POST
Enqueue an asynchronous contact import

Authorizations

Authorization
string
header
required

Dashboard JWT token from Clerk

Headers

Idempotency-Key
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.

Required string length: 1 - 255
X-Test-Mode
enum<string>

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.

Available options:
true,
false

Body

application/json
rows
object[]
required

Already field-mapped rows keyed by contact field (phone, email, first_name, …).

Required array length: 1 - 1000000 elements
file_name
string

Original upload filename shown in the imports history.

Required string length: 1 - 255
merge_strategy
enum<string>

How to treat a row whose phone/email matches an existing contact: skip (default) leaves the existing contact untouched; merge updates it.

Available options:
skip,
merge

Response

Import queued. Poll GET /contacts/imports/{job_id} for progress — /imports/{job_id} single-segment GET, not /import-jobs/{id} (that route carries only the skipped-rows CSV).

Import queued. Poll GET /contacts/imports/{job_id} for progress — /imports/{job_id} single-segment GET, not /import-jobs/{id} (that route carries only the skipped-rows CSV).

data
object
meta
object