Export and import
Export invoices to XLSX or CSV and import unified contacts with explicit roles, field mapping and a preview.
Export invoices to a spreadsheet and import contacts with cumulative customer, supplier and lead roles. Each file operation uses its own response contract; inspect the preview before writing.
Export invoices to a spreadsheet
POST /v1/invoices/export/excel (scope invoices:read) builds an XLSX or CSV
spreadsheet of your invoices and streams the binary file back. It is a read
operation at domain level: nothing is created or modified. The POST still
requires Idempotency-Key because it consumes file-generation resources.
Two orthogonal axes control the output:
| Parameter | Values | Meaning |
|---|---|---|
format | SUMMARY (default) · ITEMS | Content layout. SUMMARY is one row per invoice; ITEMS is one row per invoice line (header columns repeated on each line). |
file_format | xlsx (default) · csv | File container. |
Pick the invoices to export in either of two ways:
- By id — pass
invoice_idswith the UUID v7 ids of specific invoices. - By filter — omit
invoice_idsand narrow the set withstatus,date_from,date_to,client_id,series_idandsearch.date_fromanddate_tofilter the issue date (inclusive);client_idandseries_idtake the public UUID v7 of the client/series.
curl -s -X POST https://api.factuarea.com/v1/invoices/export/excel \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"format": "ITEMS",
"file_format": "xlsx",
"status": "paid",
"date_from": "2026-01-01",
"date_to": "2026-03-31"
}' \
-o invoices-q1.xlsxThe 5000-invoice limit
The selected set is capped at 5000 invoices. If your filters match more
than that, the API does not truncate silently — it returns 422 with the
export_limit_exceeded error code:
{
"error": {
"type": "invalid_request_error",
"code": "export_limit_exceeded",
"message": "La exportación supera el máximo de 5000 facturas."
}
}Narrow the date range, the status or the client, or split the export into several calls, so each request stays under the limit.
Packaging caps and budget
Exports can also fail before a file is served:
| Status / code | Meaning | What to do |
|---|---|---|
413 export_document_cap_exceeded | The requested artifact covers too many documents. | Split by date, series or id batches. |
413 export_byte_cap_exceeded | The estimated or actual archive exceeds its byte cap. subcode is before_writing or while_writing; a partial file is never served. | Request fewer documents per call. |
429 export_budget_exceeded | The company's hourly packaging budget ran out. subcode identifies the document or artifact axis. | Respect Retry-After; changing API keys does not bypass a company budget. |
A cap rejection, an empty period and an aborted package do not consume export budget. Re-downloading an already materialized artifact does not consume it either.
client_id, series_id and the invoice_ids entries are matched inside
your company. A UUID that does not exist or belongs to another company is
simply dropped from the selection — it never leaks cross-tenant data and never
returns a global 404.
Import contacts from a file
Use POST /v1/contacts/import/preview before POST /v1/contacts/import. Both require contacts:write, Idempotency-Key and multipart/form-data. The importer accepts CSV, TXT, XLSX or XLS files up to 10 MB.
Mapping and roles
mapping maps destination field → source column header, for example mapping[name]=Name. Omit it when the headers already use canonical field names. Unknown destinations are rejected; they are not silently discarded. Include name, a valid fiscal identity and at least one role, supplied in the file or through target_roles.
The preview also returns source_headers, the original column names read from CSV, TXT, XLSX or XLS. To discover the columns before building a mapping, send the file to the same preview endpoint with mapping omitted. Use source_headers to build the destination-to-column mapping, then preview again. Rows may be marked invalid until the required fields are mapped; discovering columns never writes contacts.
curl -X POST https://api.factuarea.com/v1/contacts/import/preview \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@contacts.csv" \
-F "mapping[name]=Name" \
-F "mapping[tax_id]=VAT number" \
-F "mapping[external_id]=Id" \
-F "target_roles[]=customer" \
-F "conflict_strategy=reject"Preview, then import
The preview classifies each row as create, update, add_role, merge_candidate, conflict or invalid. Inspect errors, warnings and target_uuid; resolve ambiguous identities before importing. The response includes total, counts by action, dry_run and queued, rather than the legacy client import envelope.
Send the reviewed file and the same mapping to /v1/contacts/import, with a new idempotency key. dry_run=true also validates without writing. The default conflict_strategy=reject protects existing data; select update or merge deliberately after reviewing the preview. Large imports may return 202 with queued=true: acceptance is not proof that every row has completed.
Supported contact data
The canonical importer supports external_id, kind, roles, tags, address fields (address_line_1, country_code), alternative fiscal identity, billing_emails, bank_accounts, metadata, DIR3 codes and directional defaults (customer_*, supplier_*). Map only columns you intend to write. Keep both roles on a contact that buys and sells; never split its fiscal identity into duplicate records.
Download formats and public scope
Download the canonical CSV template with GET /v1/contacts/import/template, then map its columns explicitly when previewing and importing. This binary download is available through REST and has no MCP tool. FacturaE returns XML, while CSV/PDF/XLSX/ZIP downloads return bytes. Responses 204 and 304 have no body. Use only operations listed in the current API Reference.