Campaigns
Import Campaign Contacts
Accept a CSV upload and queue it for asynchronous processing.
Previously this endpoint parsed and inserted contacts inline, which on a
10k-row CSV would block the FastAPI worker for 30+ seconds and time out
most reverse proxies. Now the route persists the upload as a
CampaignDataImport row, dispatches a Celery task, and returns 202.
The client polls GET /campaigns/{id}/imports/{import_id} for status.
POST
Bulk import contacts from a CSV file into a campaign. The endpoint validates phone numbers, detects duplicates, and maps columns to contact fields.
Path Parameters
campaign_id(integer, required): The unique identifier of the campaign
Request
This endpoint acceptsmultipart/form-data with the following fields:
CSV Format Requirements
- Required column: Phone number (auto-detected or mapped)
- Recommended: Header row with column names
- Encoding: UTF-8
- Delimiter: Comma (,)
Phone Number Validation
Phone numbers are automatically normalized to E.164 format:Column Mapping
The system auto-detects common column names:
For custom mappings, provide a JSON object:
Example CSV
Response
Response
Response Fields
Example Code
cURL
Python
JavaScript
Behavior
- Existing contacts with same phone number are skipped (not duplicated)
- Pending/skipped contacts from previous imports are deleted before new import
- Completed/failed contacts are preserved for history
- All custom columns become template variables
Error Responses
Best Practices
- Validate data before importing - check phone number formats
- Use consistent column names across imports
- Include name column for better personalization
- Remove duplicates in your source data
- Test with small file before large imports