Exports

Retrieve the results of a completed bulk as downloadable CSV files, notified by webhook.

Overview

An export packages the results of a completed bulk into downloadable CSV files — one file per entity — so you can retrieve thousands of results in a single flow instead of reading each identifier through the API.

  • Asynchronous: POST /exports returns 202 Accepted immediately. Generation runs in the background.
  • You are notified through the export.completed webhook event when the files are ready.
  • Download links are returned by GET /exports/{export_id} and remain available for 7 days after the export completes.

Requesting an export

Call POST /exports with the bulk_id of a completed verification bulk and the entities you want:

curl --request POST \
     --url https://api.burodeingresos.com/exports \
     --header 'X-API-Key: YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "bulk_id": "136d551e-5293-438e-ad79-5831c43a71b1",
  "entities": ["profile", "invoices"]
}
'

Successful response (202 Accepted):

{
  "export_id": "7f2c8a90-1b2c-4d3e-9f4a-5b6c7d8e9f0a",
  "bulk_id": "136d551e-5293-438e-ad79-5831c43a71b1",
  "status": "queued",
  "requested_at": "2026-09-18T14:44:23Z",
  "files": []
}
FieldDescription
bulk_idA verification bulk that belongs to your account and has finished processing.
entitiesOne or more of profile, invoices. One CSV file is generated per entity. Order and duplicates are ignored.

The export is always scoped to your own account: the company is taken from your API key, never from the request body.

🔁

Requests are idempotent

Requesting the same bulk_id with the same entities again returns 202 with the same export_id instead of generating a duplicate. This makes retries safe. A failed or expired export can be requested again and produces a new one.

Error responses:

StatusCodeWhen
409bulk_not_readyThe bulk is still processing. Wait for metrics.in_progress to reach 0 and request again.
404bulk_not_foundThe bulk_id does not exist on your account.
400validation_errorMissing bulk_id or empty entities.

Getting notified: export.completed

When the files are ready, we send the export.completed event to your active webhook:

{
  "event": "export.completed",
  "export_id": "7f2c8a90-1b2c-4d3e-9f4a-5b6c7d8e9f0a",
  "bulk_id": "136d551e-5293-438e-ad79-5831c43a71b1",
  "status": "completed",
  "files": [
    { "name": "invoices.csv", "rows": 812000, "bytes": 410000000 },
    { "name": "profiles.csv", "rows": 3950, "bytes": 4100000 }
  ],
  "timestamp": "2026-09-18T14:44:24Z"
}

The event deliberately contains no download links, so it can be stored and forwarded without carrying a credential. Fetch the links with GET /exports/{export_id}.

⚠️

Webhooks created before this feature launched are not subscribed to export.completed automatically. Add the event to your existing webhook with PATCH /webhooks/{webhook_id}, including "export.completed" in the events array. Webhooks created from now on are subscribed by default.

Only successful completion is notified. If an export fails, you will see it through polling: GET /exports/{export_id} returns status: "failed" with an error_code.


Downloading the files

GET /exports/{export_id} returns the current state and, once completed, one download link per file:

curl --request GET \
     --url https://api.burodeingresos.com/exports/7f2c8a90-1b2c-4d3e-9f4a-5b6c7d8e9f0a \
     --header 'X-API-Key: YOUR_API_KEY'
{
  "export_id": "7f2c8a90-1b2c-4d3e-9f4a-5b6c7d8e9f0a",
  "bulk_id": "136d551e-5293-438e-ad79-5831c43a71b1",
  "status": "completed",
  "requested_at": "2026-09-18T14:44:23Z",
  "finished_at": "2026-09-18T14:44:24Z",
  "expires_at": "2026-09-25T14:44:24Z",
  "files": [
    {
      "name": "invoices.csv",
      "rows": 812000,
      "bytes": 410000000,
      "url": "https://…",
      "expires_at": "2026-09-18T15:44:41Z"
    },
    {
      "name": "profiles.csv",
      "rows": 3950,
      "bytes": 4100000,
      "url": "https://…",
      "expires_at": "2026-09-18T15:44:41Z"
    }
  ]
}
  • Each url is a signed link valid for about 1 hour. Every read of GET /exports/{export_id} issues fresh links, so if a link expires, just call the endpoint again.
  • The export itself is available for 7 days after completion (expires_at at the top level). After that it is purged and files comes back empty; request a new export if you still need the data.
  • rows and bytes describe the exact file, so you can verify your download.

File contents

One row per record of the file's entity. Identifiers that have no data for an entity are simply not present in that file.

profiles.csv — one row per identifier:

identifier, updated_at, first_name, last_name, curp, nss, rfc, phone, email, tax_regime, street, neighborhood, municipality, state, zip_code, employment_status, estimated_monthly_income, tenure

invoices.csv — one row per invoice (an identifier appears once per invoice):

identifier, folio_fiscal, type, invoice_status, issue_date, rfc_issuer, issuer_name, rfc_receiver, receiver_name, zip_code_receiver, amount, currency, payment_method, payment_type, payroll_type, payment_periodicity, job_risk, job_role, job_department, incomes, deductions, line_items, invoice_relations, updated_at

The incomes, deductions, line_items and invoice_relations columns contain JSON arrays — the same objects the invoices API returns — so an invoice's nested collections are delivered complete inside its row.


Did this page help you?