Reports

Report export webhooks

This page documents webhook events related to report exports. These events notify you when a report export starts and when the report file has been generated successfully.

For the common webhook envelope fields (id, attemptId, livemode, created, event), see Webhook structure.


Report exports

Emitted when a report export is processed.

Trigger Event name When
Export job begins processing report.export.started After the worker confirms the message will not be re-queued due to record-count splitting; immediately before reading report data
Report file generation succeeds report.export.completed After the CSV is generated and uploaded to S3; before optional email delivery. Does not indicate that an email was sent or received

Behavior notes

  • report.export.completed is emitted only when report generation and S3 upload succeed. If processing fails after report.export.started, report.export.completed is not emitted.
  • If the export is split into multiple parts (large reports), report.export.started is not emitted for the invocation that triggers the split; each resulting part emits report.export.started when it is individually processed.
  • report.export.completed indicates successful report generation, not successful email delivery. Email is sent after this webhook when deliveryMethod is Email.
  • For standard (non-custom) reports, several fields in data may be undefined: reportTypeName, customReportId, bucket, filters, reportTypeId, deliveryMethod.
  • reportId and reportTypeName are resolved by Betterez when the export is requested; they are not necessarily provided by the original caller.
  • columns contains only column IDs. Entries without an id are omitted.
  • createdAt in data is the UTC timestamp when the webhook is emitted (BzDate: value and offset), not a report date filter.
  • Sensitive fields such as API keys are not included in data.

Payload example – started

The data object for report.export.started contains export context from the export request (subset of fields).

{
  "attemptId": "d42c1225-9917-410c-950e-0383162d416b",
  "created": 1779974953,
  "data": {
    "accountId": "52a377ec430c7d4e220001fc",
    "reportId": "transaction-report-list",
    "reportTypeName": "transactions",
    "customReportId": "6a0ded79deaedd05c5fa32b6",
    "bucket": {},
    "filters": {
      "status": "paid",
      "agencyId": "all",
      "stationId": "all",
      "providerIds": null
    },
    "columns": [
      "transactionNumber",
      "customerNumber",
      "customerName",
      "status",
      "total"
    ],
    "reportTypeId": "5af353ef8d4d7e8551000001",
    "emails": ["test@example.com"],
    "format": "csv",
    "deliveryMethod": "Email",
    "createdAt": {
      "value": "2026-05-20T17:24:50.130Z",
      "offset": 0
    },
    "createdBy": "62179884ebb34d07f9a14cdc"
  },
  "event": "report.export.started",
  "id": "7ec09d11-974e-4828-8373-c09fc9f9e738",
  "livemode": true
}

Payload example – completed

The data object for report.export.completed has the same shape as report.export.started, plus fileName (generated CSV file name).

{
  "attemptId": "ca8dfe73-029c-4c74-b43c-2706aae4d92a",
  "created": 1779975021,
  "data": {
    "accountId": "52a377ec430c7d4e220001fc",
    "reportId": "transaction-report-list",
    "reportTypeName": "transactions",
    "customReportId": "6a0ded79deaedd05c5fa32b6",
    "bucket": {},
    "filters": {
      "status": "paid",
      "agencyId": "all",
      "stationId": "all",
      "providerIds": null
    },
    "columns": [
      "transactionNumber",
      "customerNumber",
      "customerName",
      "status",
      "total"
    ],
    "reportTypeId": "5af353ef8d4d7e8551000001",
    "emails": ["test@example.com"],
    "format": "csv",
    "deliveryMethod": "Email",
    "createdAt": {
      "value": "2026-05-20T17:25:12.456Z",
      "offset": 0
    },
    "createdBy": "62179884ebb34d07f9a14cdc",
    "fileName": "a1b2c3d4-e5f6-7890-abcd-ef1234567890.csv"
  },
  "event": "report.export.completed",
  "id": "c1945aa8-2982-4974-9494-9f37db44244e",
  "livemode": true
}

fileName is {prefixForFile}{uuid}.csv, where prefixForFile comes from the queue message (slashes removed) and uuid is a version-1 UUID.


Field descriptions – data

Field Type Description
accountId string The account id for the export.
reportId string The report identifier. Resolved from reportTypeId when filters are used.
reportTypeName string The report type name. Resolved by Betterez from reportTypeId when the export is requested.
customReportId string The custom report id. Present for custom report exports.
bucket object S3 bucket configuration when delivery uses S3. Empty object {} for Email delivery.
filters object The filters applied to the report data.
columns array of string Column ids included in the export.
reportTypeId string The database id of the report type.
emails array of string Recipient email addresses for the export.
format string Output file format (for example, csv).
deliveryMethod string How the report is delivered: Email or S3.
createdAt object UTC date when the webhook was emitted (BzDate: value, offset).
createdBy string User id of the person who triggered the export.
fileName string Generated CSV file name. Present only on report.export.completed. Format: {prefixForFile}{uuid}.csv.