Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DataTalksClub/datamailer/llms.txt
Use this file to discover all available pages before exploring further.
POST /api/contacts/imports/csv accepts a UTF-8 CSV file and imports each row as a contact upsert. The endpoint uses the same idempotency and partial-error logic as the JSON import: valid rows are committed regardless of which other rows fail, and re-uploading the same file is safe. The CSV must include an email header column; all other supported columns are optional and can be omitted entirely.
Authentication
All requests must include a Bearer token issued for the target client.Request
Method and path:POST /api/contacts/imports/csv
Content-Type: multipart/form-data
Upload the file using the file form field. The audience and client slugs can be provided as additional form fields (or as columns in the CSV itself).
Form Fields
The CSV file to import. Must be UTF-8 or UTF-8 with BOM. The first row must
be a header row containing at least the
email column.Default audience slug applied to all rows that do not have an
audience
column, or whose audience column is empty.Default client slug applied to all rows that do not have a
client column,
or whose client column is empty.Set to
true to validate all rows and return projected counts without
writing any data. Accepts true, 1, yes. Defaults to false.Supported CSV Columns
The following column names are recognized. Columns not listed here are silently ignored during import.| Column | Type | Notes |
|---|---|---|
email | string | Required. Contact email address. |
audience | string | Audience slug. Falls back to the audience form field when blank. |
client | string | Client slug. Falls back to the client form field when blank. |
tags | string | Semicolon-separated tag names, e.g. course-ml-zoomcamp;course-de-zoomcamp. |
subscription_status | string | Subscription status: pending, subscribed, or unsubscribed. Also accepted as status. |
verified | boolean | See boolean values below. |
global_unsubscribed | boolean | Sets global_unsubscribed_at if true. |
hard_bounced | boolean | Sets hard_bounced_at if true. |
complained | boolean | Sets complained_at if true. |
unsubscribed | boolean | When true, overrides subscription_status to unsubscribed. |
email_validation_status | string | One of unknown, valid, invalid_syntax, no_mx, disposable, risky, manually_invalid, externally_validated. |
email_validation_reason | string | Free-text reason stored alongside the validation status. |
email_validated_at | string | ISO 8601 timestamp of the external validation. Set automatically when status or reason changes. |
unsubscribe_reason | string | Stored as the unsubscribe reason when status is unsubscribed. |
Boolean Column Values
Boolean columns accept the following values (case-insensitive):- True:
true,yes,1,y,on - False:
false,no,0,n,off, or empty string
Tags Format
Provide multiple tags as a semicolon-delimited list within a single cell:Deduplication
Within a single uploaded file, the first valid row for a given normalized email wins. Later rows with the same normalized email are skipped and reported as duplicate rows. Emails are normalized by lowercasing before comparison.Response
HTTP200 OK. The response shape is identical to the JSON import response.
Echoes the
dry_run flag.Per-row result entries for all successfully processed rows.
Per-row error entries for rows that failed validation.
Example
CSV File (contacts.csv)
Request
Response
audience and client can be provided either as form fields (shown above) or
as columns within the CSV itself. If a row includes both a CSV column value and
a form field default, the CSV column takes precedence for that row. The
authenticated client slug must always match — rows referencing a different
client return a forbidden validation error.