Skip to main content

Endpoints

Imports run asynchronously: start a session (upload a CSV or send rows inline), optionally preview the detected column mappings, execute, then poll the run until it completes. Every row gets an individually reported outcome.
For small synchronous batches (up to 100 records), use POST /v1/contacts/upsert instead. Imports shine for large files, dedupe control, and auditable per-row results.

Start an Import

Two mutually exclusive modes, selected by source:

Upload mode

Returns an import_session_id plus a presigned S3 upload_url (valid for 1 hour) — PUT your CSV bytes directly to it, then continue to preview/execute.

Inline rows mode

Request bodies are capped at 5 MB. Larger datasets should use upload mode.

Preview an Import

Parses the header plus sample rows and returns auto-detected mappings (source header → target field), per-column sample validation issues, the org’s available_fields, and field_creation_candidates for unmapped columns. Optional for headless runs — you can pass mappings straight to execute.

Execute an Import

Rows matching an existing contact (normalized email or phone) follow duplicate_strategy; per-column overwrite_behavior (overwrite | skip_if_filled) controls whether filled values are replaced. Returns 202 with an import_run_id.

Poll a Run

status moves queued → running → completed | failed, with created_count, updated_count, skipped_count, error_count, and chunk-level progress.

Per-Row Results

Paginated outcomes (limit ≤ 250), filterable by status (created | updated | skipped | failed); failed rows include field_issues with error codes. Row numbers count the header as line 1.
Streams a CSV of skipped and failed rows with reasons (Content-Disposition: attachment). Use the paginated results endpoint for full result sets.

Common Errors