Audience
Contact imports
Upload a CSV and follow its background import through the API.
Upload a CSV
Use create contact import with a full-access credential. Save this as contacts.csv:
email,first_name
you@example.net,Adacurl "$OPENSEND_BASE_URL/contacts/imports" \
-H "Authorization: Bearer $OPENSEND_API_KEY" \
-H 'Idempotency-Key: contacts-september' \
-F 'file=@contacts.csv;type=text/csv' \
--form-string 'on_conflict=upsert'The response is 201 with object: "contact_import" and id. Send multipart form data; URLs and inline JSON contact arrays are not accepted. Idempotency compares sorted decoded fields and CSV contents, so a new multipart boundary does not create another job.
Map fields and preferences
Without column_map, standard column names are recognized. To map different headings, send a JSON-encoded object such as {"email":"Email","first_name":"First Name"}. Custom properties use properties: {plan: {column: "Plan", type: "string"}}. Only string and number properties are supported; missing mapped definitions are created with the job.
on_conflict defaults to upsert; use skip to leave existing contacts unchanged. Optional JSON-encoded segments entries use {id}; topics entries use {id, subscription: "opt_in"} or opt_out. All references must belong to your team.
Follow progress
Retrieve the import or list imports with a status filter. Jobs enter in_progress immediately, then finish as completed or failed. The list also accepts queued for compatibility, which never matches because jobs start at once, plus standard ID cursors and limits of 1–100.
counts includes total, created, updated, skipped, and failed. Total means rows processed so far. Invalid rows count as failed; existing contacts with skip enabled count as skipped. The completion time is null while processing. Older jobs may lack a completion timestamp or separate failure count. CSV contents and private diagnostic text are not returned.
Limits and retention
Split files above 500 rows or 500 KB of parsed job data. The multipart request limit is 1 MiB, with at most 1,000 segment and 100 topic references. Malformed CSV/maps return 422; malformed multipart returns 400. List scans are bounded and may return fewer rows than requested, so follow has_more.
Imports use the dashboard’s durable CSV processing and suppress contact webhooks, including topic preference changes. Completed and failed jobs expire after seven days.