Factuarea APIDevelopers

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:

ParameterValuesMeaning
formatSUMMARY (default) · ITEMSContent layout. SUMMARY is one row per invoice; ITEMS is one row per invoice line (header columns repeated on each line).
file_formatxlsx (default) · csvFile container.

Pick the invoices to export in either of two ways:

  • By id — pass invoice_ids with the UUID v7 ids of specific invoices.
  • By filter — omit invoice_ids and narrow the set with status, date_from, date_to, client_id, series_id and search. date_from and date_to filter the issue date (inclusive); client_id and series_id take 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.xlsx

The 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 / codeMeaningWhat to do
413 export_document_cap_exceededThe requested artifact covers too many documents.Split by date, series or id batches.
413 export_byte_cap_exceededThe 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_exceededThe 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.

On this page

Need a hand?Contact support