The Only API docs
Bulk Import

Start a bulk import

Create an import job and start working through the rows in the background. Returns 202 immediately with the job and its per-status counts.

POST
/import/jobs

Create an import job and start working through the rows in the background. Returns 202 immediately with the job and its per-status counts.

Progress streams over GET /events/stream as import.progress (coalesced to at most one per second) and finishes with import.complete. The job row is the source of truth — if you miss an event, GET /import/jobs/{job_id} still has the current state.

Rows that hit a 2FA prompt do not fail: they park as needs_2fa holding the challenge, and wait for a code via POST /import/jobs/{job_id}/rows/{row_id}/otp. Parked rows expire after 10 minutes (retry them for a fresh login) and their stored credential is destroyed after 24 hours regardless.

Invalid rows are reported but never attempted. If no row is valid the request fails with 400 and the per-row reasons rather than creating a job that is 100% failures.

X-API-Key<token>

Your CRM panel API key

In: header

Header Parameters

X-User-Email?string

Optional label recorded as the job's requested_by, for panels where several operators share a key.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/import/jobs" \  -H "Content-Type: application/json" \  -d '{    "text": "string"  }'
{  "columns": [],  "counts": null,  "delimiter": "string",  "format": "string",  "has_header": true,  "invalid_count": 0,  "job": null,  "lanes": null,  "limits": {},  "platforms": null,  "success": true,  "total": 0,  "valid_count": 0,  "warning": "string"}