Imports
Create Import
Creates a bulk import operation for one of the supported resources: contact, group, item, asset, or location. The data can be supplied either as a JSON array of objects or as a base64-encoded CSV/XLSX/JSON file. Only upload_mode: "sync" is currently supported.
Actions per Resource
The action you may use depends on the resource:
merge: Updates and/or creates the rows in the upload.overwrite: Creates and/or updates the rows in the upload, and deletes/detaches all other existing rows of that resource. See the location_id and overwrite section below for how the deletion scope works. Only valid forcontactandgroup.delete: Deletes the rows in the upload. A valididis required for each row. Only valid forcontactandgroup.
Using an action that a resource does not support returns a 400 error, for example: 'delete' cannot be used with Imports API for 'items'.
location_id and overwrite
This section eliminates a common misunderstanding. Read it fully before using overwrite with a location_id.
1. location_id is only permitted with action: "overwrite". Providing location_id with any other action returns a 400 error: 'location_id' can only be used with Imports API in 'overwrite' mode. Because overwrite is only valid for contact and group, location_id is only meaningful for contact and group imports.
2. location_id exists for ONE purpose: to scope the overwrite deletion to a single location. It answers the question "when I overwrite, should the existing resources be removed across my entire organization, or only at this one location?"
- Without
location_id, anoverwritedeletes every existing contact/group of that resource that is NOT present in the upload, organization-wide. - With
location_id, the overwrite only removes the resource's association with THAT location for rows not present in the upload. For contacts, a contact is deleted entirely only if it is left with no locations at all afterward.
3. location_id does NOT associate the imported rows to that location. Providing location_id does not link, tag, or place the newly imported or updated rows at that location. It is purely the deletion scope. If you want an imported row to belong to a location, you MUST specify that location explicitly in the row's own data (its CSV column or JSON field). To repeat, because this is the exact ambiguity to avoid: location_id controls what gets deleted, never what the imported rows get associated to.
4. How a row explicitly associates itself to a location (per resource):
Example A - Overwrite contacts at a location AND associate them to it
Here each contact row sets the locations field, so the uploaded contacts are associated to loc_wework01 because the data says so. The location_id scopes the overwrite so that only contacts currently at loc_wework01 and not present in this upload are removed from that location.
Outcome: Leia and Han are created/updated and associated to WeWork 01 (because their rows list it under locations). Any other contact previously associated to WeWork 01 that is not in this upload is removed from that location - and deleted entirely only if it has no remaining locations.
Example B - The trap: overwrite with location_id but no locations in the data
This is the same action: "overwrite" and location_id, but the rows do NOT set locations. This is the mistake to avoid.
Outcome: existing contacts at WeWork 01 that are not in this upload are still removed from that location (the deletion scope applies). But Leia and Han are created/updated WITHOUT being associated to WeWork 01, because their rows never specified a locations value. If you expected them to end up at WeWork 01, this is wrong - location_id alone will not do that. Set locations on each row (as in Example A) instead.
The base64 CSV equivalent works the same way: the CSV must contain a locations column with the location for each row. Because base64 hides the row contents, the readable JSON arrays above are preferred when a location association matters.
Examples
Import Contacts (base64 CSV)
Import Contacts (JSON data)
Import Groups (JSON data)
The resource column on each group row is required and is either contact or location. For location-type groups the children are locations.
Import Items (JSON data)
Stock levels use the positional levels[].* columns; multiple levels are joined by :::. Items only support the merge action.
Import Assets (JSON data)
An asset associates to a single location via location_name. Assets only support the merge action.
Import Locations (JSON data)
Locations only support the merge action. A row targets an existing location when it includes an id or a matching external_id; otherwise a new location is created (dedup priority: id > external_id > name).
Delete Contacts
delete requires a valid id per row and is only valid for contact and group.
Request Model
This request model represents the payload structure required to create an import operation.
Request Body
upload_mode sync|async
Determines whether the import runs synchronously (sync) with data or asynchronously (async) without immediate data. Only sync is currently supported - async returns a 400 error.
- If
sync, thedatafield is required. - If
async, thedatafield must benull.
data array<object> | base64 | null
The data to be imported, which can be:
- An array of objects, where each object is one row.
- A base64-encoded file (CSV, XLSX, or JSON) that resolves to an array of objects.
nullwhenupload_modeisasync.
Show Details
location_id string | null (optional)
Scopes an overwrite deletion to a single location. Only permitted with action: "overwrite" (otherwise returns a 400). It does NOT associate imported rows to the location - see the location_id and overwrite section above.
action merge|overwrite|delete
The action to perform. Valid values depend on resource (see the Actions per Resource table above):
merge: Updates and/or creates the rows in the upload.overwrite: Creates/updates the rows in the upload and deletes/detaches all other rows (scoped bylocation_idif provided). Only forcontactandgroup.delete: Deletes the rows in the upload; a valididis required per row. Only forcontactandgroup.
Note: item, asset, and location support merge only.
duplicate_handling ignore_all|use_first (optional, default: ignore_all)
Defines how duplicate records are handled. With use_first, the first instance of a duplicate is processed and the rest are ignored. With ignore_all, all duplicates are ignored.
save_upload boolean (default: true)
Whether the uploaded payload is stored so it can be downloaded later via the retrieve endpoint. If false, requesting the upload file on retrieve returns a 400.
resource contact|group|item|asset|location
The type of resource being imported.
name string (optional, 3-127 characters)
A human-readable name for the import. Values shorter than 3 or longer than 127 characters return a 400.
column_mapping object (optional)
A mapping of resource field names to the custom column headers used in your uploaded file. This lets you import files whose headers do not match the expected field names. Keys are the resource field names and values are the corresponding header strings. Each non-null header value must be unique - duplicate values return a 400: Headers must be unique for each column. Set a value to null to skip mapping that column.