Preview a CSV import
Step 1 of the CSV import. Upload the file as multipart/form-data (field file). The response
has the headers, the first 10 rows, a proposed column mapping, validation stats and the file’s
SHA-256 fileHash. Nothing is stored. Review or adjust the mapping, then send the same file
with it to POST /api/campaigns/{campaignId}/contacts/upload-confirm.
File rules. The name must end in .csv and the part’s MIME type must be text/csv,
application/csv or text/plain. Maximum 10 MB, comma-separated, first row = headers. Encoding
UTF-8 (a BOM is fine) or UTF-16 with BOM; other encodings are refused, so use “CSV UTF-8” when
saving from Excel. XLSX, XLS, PDF and other binary files are refused. Each field is limited to
1 MB and each row to 500 columns. Blank lines are ignored.
Detected mapping. Headers are matched case-insensitively. Columns containing whatsapp/wa
map to whatsappNumber, phone/tel/mobile/celular/telefono/numero to phoneNumber,
email/correo/mail to email, and name/nombre/contact to name. Otherwise the sample
values decide (mostly phone-shaped, or mostly containing @). Each field is claimed by the
first matching column; later matches and everything else become metadata.
Stats cover only the first 1,000 rows. Phone and WhatsApp cells are checked with the same
rules as confirm, including completing local numbers with the workspace country, so a row counted
valid here is not rejected there for its number. errors holds up to 100 entries. Preview cells starting with =, +, - or @ are
prefixed with ' so they cannot run as spreadsheet formulas; stored values are not changed.
The campaign itself is not looked up here: an unknown campaignId still gets a preview.
Idempotency. Safe to retry: nothing is written, and the same file always returns the same
fileHash.
Access
- Required scope:
write(orfull). - Rate limit: Contacts import — 5 requests/min per workspace, shared only by
/bulk,/upload-previewand/upload-confirm, on top of the general API limit. See Rate limits. - Plan: Refused with 403
BILLING_ERRORwhen the workspace contact cap is already reached (Starter 500, Growth 2,000, Business 20,000).
Authentication
Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the
dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once,
at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.
Operations restricted to admins or owners reject keys without the full scope with 403, and say so in
their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret —
that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds.
See Authentication.
Path parameters
UUID of the campaign the file is meant for. Only its format is checked here (400 if not a UUID); it is not looked up.
Request
The CSV file (form field file, .csv, max 10 MB).
Response
Always true on 200.

