Preview. Part of the Migration API — in active design and not yet generally
available. Endpoints and payloads may change. See the
overview.
{id} is the company.id from
provisioning.
Authentication
Requires anx-api-key header. See Authentication.
Uploading files
You have two options:- Signed upload (any size). Request a signed upload URL,
PUTthe file’s bytes to it, then pass the returned reference asupload_ref. Use this for real customer files. - Inline rows (small sets). Skip the upload and pass tabular data directly as
rows. Convenient for small or already-parsed data.
Signed upload
A two-step handshake. First, ask for a signed URL, declaring the file’s name, type, and size:PUT the raw bytes to upload_url with a Content-Type matching what you
declared, and pass the upload_ref to the import call:
Request body
Files to import. Each entry is
{ "name": "contacts.csv", "upload_ref": "..." },
where upload_ref comes from a signed upload. Provide either files or rows.Inline tabular data for small sets — an array of row objects. An alternative to
files.A key you choose to make this import safe to retry. Re-sending the same key for
the same company returns the existing run instead of starting a second one.
See Errors & idempotency.
Response
201 Created
poll_url until the run reaches a terminal status. See
Poll an import.
How the import behaves
Your plan was authored against a particular file shape, but real customer exports drift — renamed headers, reordered columns, stray formats. The import self-heals through that drift wherever it can, so a frozen plan survives files it didn’t see at authoring time. When rows still fail validation, the run pauses atneeds_attention with a
proposed fix for your approval; approving it produces a new plan version and
re-runs. If you’d rather not gate on review, the surviving invalid cells are
reported in the run’s report so you can download only the valid rows (see
Export CSV) or fix the source data and re-import.
See Poll an import for both paths.
Errors
| Status | Meaning |
|---|---|
400 | Neither files nor rows provided, or the payload is malformed. |
401 | API key missing or invalid. |
404 | No company with that {id} in your account. |
409 | Another import is already running for this company, or an idempotency_key conflict (same key, different payload). Only one import runs at a time per company — wait for the active run to reach a terminal state. |
429 | Rate limit hit — back off and retry. |
500 | Server error. |
Example
Next
- Poll an import — track the run to completion.
- Export CSV — get the validated rows out.