Exports API

External integration

The exports API generates downloadable tabular files for contacts, organisations, and households. Both CSV and XLSX formats are supported. The export respects a configurable column list and optional filters, making it suitable for integrating with downstream data pipelines or reporting tools.

All export endpoints are under /api/exports and require one of the roles: SYSTEM_ADMIN, TENANT_ADMIN, PARTNER_ADMIN, TENANT_STAFF, or PARTNER_STAFF.

EndpointEntity exported
POST /api/exports/contactsContacts
POST /api/exports/organisationsOrganisations
POST /api/exports/householdsHouseholds

A successful response is a file download with the appropriate Content-Type header (text/csv;charset=UTF-8 for CSV or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for XLSX) and a Content-Disposition: attachment header with the generated filename.

Request structure

All three endpoints share the same request body structure (TabularExportRequest):

{
  "format": "CSV",
  "viewState": {
    "columns": [ ... ],
    "sort": {
      "field": "createdAt",
      "direction": "DESC"
    }
  },
  "locale": "en",
  "timezone": "America/Mexico_City",
  "filters": [ ... ]
}
FieldRequiredNotes
formatYesCSV or XLSX.
viewStateYesMust contain at least one column. The sort object is optional; if omitted the server applies a default sort.
viewState.columnsYesMust not be empty. Controls which columns appear in the export and their order.
localeNoBCP 47 locale tag (e.g. en, es, es-CL). Controls date and number formatting in the output file.
timezoneNoIANA timezone name. Dates and times in the file are adjusted to this timezone.
filtersNoSame FilterCondition format used by v2 list endpoints. Only rows matching all filters are exported.
includeAllCustomFieldsNoWhen true and no custom field columns are specified, all custom fields for the entity are appended to the export.
uiScreenNameNoOptional hint for server-side logging (e.g. CONTACTS_TABLE).

Column configuration

Each entry in viewState.columns describes one column in the output file. The order of the array determines the column order in the export.

[
  {
    "id": "firstName",
    "label": "First Name",
    "custom": false,
    "type": "STRING"
  },
  {
    "id": "paternalLastName",
    "label": "Last Name",
    "custom": false,
    "type": "STRING"
  },
  {
    "id": "preferredEmail",
    "label": "Email",
    "custom": false,
    "type": "STRING"
  },
  {
    "id": "createdAt",
    "label": "Created",
    "custom": false,
    "type": "DATE_TIME"
  }
]
FieldNotes
idThe field key as used in the filter and sort model (e.g. firstName, stage). For custom fields, use the format custom:cf_UUID.
labelThe column header text written to the file. Can be a localized string.
customtrue for custom field columns; false for standard entity fields.
typeData type hint for formatting: STRING, DATE, DATE_TIME, NUMBER, BOOLEAN.
formUuidOptional. UUID of the custom field form, used to disambiguate custom fields with the same name across forms.

Applying filters

The filters array uses the same FilterCondition format as the v2 list and filtering endpoints. Multiple conditions are combined with AND logic.

[
  { "field": "contactType", "operator": "equals", "value": "ACTIVE" },
  { "field": "stage", "operator": "in", "values": ["Prospect", "Client"] }
]

See the Shared Conventions — V2 filtering page for the full list of operators and multi-value syntax.

Examples

Export active contacts to CSV

curl "https://api.altafid.dev.altafid.net/api/exports/contacts" \
  -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-tenant-uuid: YOUR_TENANT_UUID" \
  -H "x-user-email: YOUR_EMAIL" \
  -H "x-user-id: YOUR_USER_ID" \
  -H "x-user-type: TENANT_STAFF" \
  -o contacts_export.csv \
  --data '{
    "format": "CSV",
    "locale": "en",
    "timezone": "America/New_York",
    "viewState": {
      "columns": [
        { "id": "firstName", "label": "First Name", "custom": false, "type": "STRING" },
        { "id": "paternalLastName", "label": "Last Name", "custom": false, "type": "STRING" },
        { "id": "preferredEmail", "label": "Email", "custom": false, "type": "STRING" },
        { "id": "stage", "label": "Stage", "custom": false, "type": "STRING" },
        { "id": "createdAt", "label": "Created", "custom": false, "type": "DATE_TIME" }
      ],
      "sort": { "field": "createdAt", "direction": "DESC" }
    },
    "filters": [
      { "field": "contactType", "operator": "equals", "value": "ACTIVE" }
    ]
  }'

Export all households to XLSX

curl "https://api.altafid.dev.altafid.net/api/exports/households" \
  -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-tenant-uuid: YOUR_TENANT_UUID" \
  -H "x-user-email: YOUR_EMAIL" \
  -H "x-user-id: YOUR_USER_ID" \
  -H "x-user-type: TENANT_STAFF" \
  -o households_export.xlsx \
  --data '{
    "format": "XLSX",
    "locale": "es-CL",
    "timezone": "America/Santiago",
    "viewState": {
      "columns": [
        { "id": "name", "label": "Household", "custom": false, "type": "STRING" },
        { "id": "isActive", "label": "Active", "custom": false, "type": "BOOLEAN" },
        { "id": "createdAt", "label": "Created", "custom": false, "type": "DATE_TIME" }
      ]
    }
  }'

Error handling

On error the API returns a JSON body instead of a file, with an appropriate HTTP status code.

ErrorStatusCause
No rows to export400The filter produces an empty result set.
Row limit exceeded400The result set exceeds the server-enforced row limit. Apply tighter filters to reduce the export size.
Invalid column400A column id does not exist for the requested entity type.
No columns supplied400viewState.columns is empty or missing.
Unauthorized401Missing or expired bearer token.
Forbidden403Authenticated user does not have the required role.
Locale and date formatting: when locale is es-CL, date fields use the Chilean format (day/month/year) and decimal separators follow the Spanish convention. When locale is omitted or set to en, ISO 8601 formatting is used for dates.