Skip to content

Export & Import

The export/import endpoints back the CSV Export and Import actions in the Contacts screen. They are generic: a small set of server-defined tables are exportable and importable, each with an allow-listed set of columns. Only two resources are supported today:

Table Export permission Import permission
contacts contacts:export contacts:import
tags tags:export tags:import

Export rows of a table as a CSV file. The response is a CSV file download (not a JSON envelope), with Content-Type: text/csv and a Content-Disposition: attachment header naming the file <table>_export_<timestamp>.csv.

Terminal window
POST /api/export
{
"table": "contacts",
"columns": ["phone_number", "profile_name", "tags"],
"filters": {
"search": "john",
"tags": "vip,lead"
},
"format": "csv"
}
Field Type Required Description
table string Yes Table to export: contacts or tags.
columns array No Columns to include. Must be a subset of the table’s allowed columns. Defaults to the table’s default columns when omitted or empty.
filters object No Map of filter name → value (see below).
format string No Output format. Only csv is produced.
Filter Applies to Description
search contacts, tags Case-insensitive match. Contacts match on phone number or name; tags match on name or description.
tags contacts Comma-separated tag list; returns contacts having any of the tags.
Column Default Label
phone_number Yes Phone Number
profile_name Yes Name
tags Yes Tags
whats_app_account No WhatsApp Account
assigned_user_id No Assigned User ID
last_message_at No Last Message At
created_at No Created At
updated_at No Updated At
Column Default Label
name Yes Name
color Yes Color
description Yes Description
created_at No Created At

A CSV payload. The first row is the header (using the human labels above), followed by one row per record:

Phone Number,Name,Tags
14155550123,John Doe,"vip,lead"

Import rows from a CSV file via multipart/form-data. Duplicates are detected on the table’s unique column.

Terminal window
POST /api/import
Field Type Required Description
table text Yes Table to import into: contacts or tags.
file file Yes The CSV file (max 10 MB, max 10,000 data rows).
column_mapping text (JSON) No JSON object mapping a CSV header → target column, e.g. {"Mobile":"phone_number"}. Unmapped headers are matched by (lower-cased) name or label.
update_on_duplicate text No "true" to update existing rows on a unique-column match; otherwise duplicates are skipped.
Table Required Optional Unique column
contacts phone_number profile_name, whats_app_account, tags, assigned_user_id phone_number
tags name color, description name

Contact tags are automatically registered for the organization, so you do not need to create them in Settings first. Names are trimmed and deduplicated, and case-insensitive matches reuse the existing tag’s spelling and color. New tags use gray, the tag UI’s default color. Each tag name must be at most 50 characters; an oversized name rejects that row without saving the contact or creating tags. Only contacts:import is needed for labeling imported contacts, not tags:write. Skipped duplicate rows do not create tags.

{
"status": "success",
"data": {
"created": 42,
"updated": 3,
"skipped": 5,
"errors": 1,
"messages": [
"Row 12: phone_number - phone number is required"
]
}
}
Field Type Description
created integer New rows inserted.
updated integer Existing rows updated (only when update_on_duplicate is true).
skipped integer Duplicate rows left unchanged.
errors integer Rows that failed validation or insertion.
messages array Human-readable per-row error messages.

Describe the exportable columns for a table — used by the UI to build the column picker.

Terminal window
GET /api/export/{table}/config

Requires the table’s export permission (e.g. contacts:export).

{
"status": "success",
"data": {
"table": "contacts",
"columns": [
{ "key": "phone_number", "label": "Phone Number" },
{ "key": "profile_name", "label": "Name" },
{ "key": "tags", "label": "Tags" }
],
"default_columns": ["phone_number", "profile_name", "tags"]
}
}

Describe the importable columns for a table — used by the UI to build the column-mapping step.

Terminal window
GET /api/import/{table}/config

Requires the table’s import permission (e.g. contacts:import).

{
"status": "success",
"data": {
"table": "contacts",
"required_columns": [
{ "key": "phone_number", "label": "Phone Number" }
],
"optional_columns": [
{ "key": "profile_name", "label": "Name" },
{ "key": "whats_app_account", "label": "WhatsApp Account" },
{ "key": "tags", "label": "Tags" },
{ "key": "assigned_user_id", "label": "Assigned User ID" }
],
"unique_column": "phone_number"
}
}
  • Contacts API - Manage contacts individually
  • Roles - import/export permission actions