Data Import
Import records from CSV files with column mapping, duplicate handling, and progress tracking.
Import Flow
Section titled “Import Flow”- Request upload URL — get a signed URL for your CSV file
- Upload file — PUT your CSV to the signed URL
- Complete upload — trigger processing and get a preview
- Confirm import — provide column mapping and start the import
- Monitor progress — poll the import job status
Step 1: Request Upload
Section titled “Step 1: Request Upload”Endpoint: imports-request-upload
| Field | Type | Required | Description |
|---|---|---|---|
model_type | string | Yes | contacts, companies, or sources |
file_name | string | Yes | Original filename |
content_type | string | Yes | MIME type (e.g., text/csv) |
curl -X POST https://api.driftwoodapp.com/api/imports-request-upload \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "model_type": "contacts", "file_name": "leads.csv", "content_type": "text/csv" }'Response:
{ "ok": true, "result": { "job_id": "990e8400-...", "signed_url": "https://storage.googleapis.com/..." }}Step 2: Upload File
Section titled “Step 2: Upload File”Upload your CSV directly to the signed URL using a PUT request:
curl -X PUT "SIGNED_URL_FROM_STEP_1" \ -H "Content-Type: text/csv" \ --data-binary @leads.csvStep 3: Complete Upload
Section titled “Step 3: Complete Upload”Endpoint: imports-complete-upload
| Field | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | Job ID from step 1 |
Response includes a preview:
{ "ok": true, "result": { "job": { "id": "...", "status": "uploaded" }, "preview": { "headers": ["Name", "Email", "Phone", "Company"], "sample_rows": [ ["Jane Smith", "jane@example.com", "+1-555-0100", "Acme Corp"] ], "total_rows": 1500, "suggested_mapping": { "Name": "first_name", "Email": "email", "Phone": "phone", "Company": "company_name" }, "available_fields": [ {"value": "first_name", "label": "First Name"}, {"value": "last_name", "label": "Last Name"}, {"value": "email", "label": "Email"} ] } }}Step 4: Confirm Import
Section titled “Step 4: Confirm Import”Endpoint: imports-confirm
| Field | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | Job ID |
column_mapping | object | Yes | Map CSV columns to fields |
duplicate_strategy | string | No | skip, merge, or overwrite (default: skip) |
tag_delimiter | string | No | Delimiter for tag columns (e.g., , or ;) |
curl -X POST https://api.driftwoodapp.com/api/imports-confirm \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "id": "990e8400-...", "column_mapping": { "Name": "first_name", "Email": "email", "Phone": "phone" }, "duplicate_strategy": "merge" }'Step 5: Monitor Progress
Section titled “Step 5: Monitor Progress”Endpoint: imports-get
| Field | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | Job ID |
Response:
{ "ok": true, "result": { "id": "990e8400-...", "status": "processing", "total_rows": 1500, "processed_rows": 750, "created_count": 600, "updated_count": 100, "skipped_count": 45, "failed_count": 5 }}Import Statuses
Section titled “Import Statuses”| Status | Description |
|---|---|
pending | Job created, file not yet uploaded |
uploaded | File uploaded, awaiting confirmation |
processing | Import in progress |
completed | Import finished |
failed | Import failed |
View Import Errors
Section titled “View Import Errors”Endpoint: imports-errors
| Field | Type | Required | Description |
|---|---|---|---|
id | uuid | Yes | Job ID |
cursor | string | No | Pagination cursor |
limit | integer | No | Results per page |
List All Import Jobs
Section titled “List All Import Jobs”Endpoint: imports-list
curl -X POST https://api.driftwoodapp.com/api/imports-list \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{}'Duplicate Strategies
Section titled “Duplicate Strategies”| Strategy | Behavior |
|---|---|
skip | Skip rows that match an existing record |
merge | Update existing records with non-empty imported values |
overwrite | Replace existing records entirely with imported data |