Report Exports (Async)
9 API calls in this section.
Generic report export framework. Catalogs describe what can be exported; jobs run async and the file is downloaded via a signed URL.
Catalogs - List for module
/report/catalogs/:moduleReturns all registered catalogs for a module
category, columns (with relationOptions), filterable statuses, scope definitions, multiSelectFilters, and supported formats. Each multiSelectFilters entry contains key, label, valueType, and valueSource for building a searchable picker. Requires view:reports; the tenant_admin role receives this permission directly. Each scope/filter valueSource includes itemsField, which tells the FE which top-level array key to read from the endpoint response. Zone Pricing declares origin_zone_ids, origin_tag_ids, destination_zone_ids, destination_tag_ids, and service_ids. Warehouse exports include receiving-orders, picking-orders, inventory-transactions, inventory-stock, warehouses, and inventory-items.
Delivery Orders exposes optional string columns sender_name, sender_phone, receiver_name, receiver_phone. Sender values come from pickup_location.contact_info.full_name/phone; receiver values come from delivery_location.contact_info.full_name/phone. Missing contacts export as empty cells. The frontend should render these from catalog metadata and submit selected keys unchanged. No extra list API calls are required.
Path parameters
| Parameter | Type | Description |
|---|---|---|
moduleRequired | string | Module name ( Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/report/catalogs/${MODULE}?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "module": "delivery",4 "catalogs": [5 {6 "key": "delivery-orders",7 "category": "operational",8 "label": "Delivery Orders",9 "description": "All delivery orders with customer, driver, zone and payment fields.",10 "supportedFormats": [11 "csv",12 "xlsx"13 ],14 "dateField": {15 "key": "created_at",16 "label": "Created at"17 },18 "statuses": [19 {20 "value": "pending",21 "label": "pending"22 },23 {24 "value": "delivered",25 "label": "delivered"26 }27 ],28 "scopes": [29 {30 "type": "zone",31 "label": "Zone",32 "multi": true,33 "valueSource": {34 "endpoint": "/delivery/zones",35 "itemsField": "zones",36 "valueField": "id",37 "labelField": "name",38 "searchParam": "search"39 }40 },41 {42 "type": "service",43 "label": "Service",44 "multi": true,45 "valueSource": {46 "endpoint": "/delivery/services",47 "itemsField": "deliveryServices",48 "valueField": "id",49 "labelField": "name",50 "searchParam": "search"51 }52 },53 {54 "type": "driver",55 "label": "Driver",56 "multi": true,57 "valueSource": {58 "endpoint": "/delivery/drivers",59 "itemsField": "drivers",60 "valueField": "id",61 "labelField": "user.full_name",62 "searchParam": "search"63 }64 },65 {66 "type": "customer",67 "label": "Customer",68 "multi": true,69 "valueSource": {70 "endpoint": "/users/customers",71 "itemsField": "users",72 "valueField": "id",73 "labelField": "full_name",74 "searchParam": "search"75 }76 }77 ],78 "columns": [79 {80 "key": "delivery_code",81 "label": "Delivery Code",82 "type": "string",83 "defaultSelected": true,84 "relationOptions": []85 },86 {87 "key": "driver",88 "label": "Driver",89 "type": "json",90 "defaultSelected": false,91 "relationOptions": []92 },93 {94 "key": "sender_name",95 "label": "Sender Name",96 "type": "string",97 "defaultSelected": false,98 "relationOptions": []99 },100 {101 "key": "sender_phone",102 "label": "Sender Phone",103 "type": "string",104 "defaultSelected": false,105 "relationOptions": []106 },107 {108 "key": "receiver_name",109 "label": "Receiver Name",110 "type": "string",111 "defaultSelected": false,112 "relationOptions": []113 },114 {115 "key": "receiver_phone",116 "label": "Receiver Phone",117 "type": "string",118 "defaultSelected": false,119 "relationOptions": []120 }121 ]122 },123 {124 "key": "receiving-orders",125 "category": "operational",126 "label": "Receiving Orders",127 "description": "Inbound receiving orders with supplier, warehouse, status and arrival dates.",128 "supportedFormats": [129 "csv",130 "xlsx"131 ],132 "dateField": {133 "key": "expected_arrival_date",134 "label": "Expected arrival date"135 },136 "statuses": [137 {138 "value": "pending",139 "label": "pending"140 },141 {142 "value": "received",143 "label": "received"144 }145 ],146 "scopes": [147 {148 "type": "warehouse",149 "label": "Warehouse",150 "multi": true,151 "valueSource": {152 "endpoint": "/warehousing/warehouses",153 "itemsField": "warehouses",154 "valueField": "id",155 "labelField": "name",156 "searchParam": "search"157 }158 }159 ],160 "columns": [161 {162 "key": "reference_number",163 "label": "Reference Number",164 "type": "string",165 "defaultSelected": true,166 "relationOptions": []167 },168 {169 "key": "warehouse_id",170 "label": "Warehouse",171 "type": "uuid",172 "defaultSelected": true,173 "relationOptions": [174 {175 "output": "id",176 "label": "Warehouse ID"177 },178 {179 "output": "reference_value",180 "label": "Warehouse name",181 "table": "warehouses",182 "referenceField": "name"183 }184 ]185 }186 ]187 },188 {189 "key": "inventory-items",190 "category": "master-data",191 "label": "Inventory Items",192 "description": "Inventory item master data. Kept intentionally simple for now with warehouse scope only.",193 "supportedFormats": [194 "csv",195 "xlsx"196 ],197 "dateField": {198 "key": "updated_at",199 "label": "Updated at"200 },201 "scopes": [202 {203 "type": "warehouse",204 "label": "Warehouse",205 "multi": true,206 "valueSource": {207 "endpoint": "/warehousing/warehouses",208 "itemsField": "warehouses",209 "valueField": "id",210 "labelField": "name",211 "searchParam": "search"212 }213 }214 ],215 "columns": [216 {217 "key": "name",218 "label": "Name",219 "type": "string",220 "defaultSelected": true,221 "relationOptions": []222 },223 {224 "key": "sku",225 "label": "SKU",226 "type": "string",227 "defaultSelected": true,228 "relationOptions": []229 },230 {231 "key": "categories",232 "label": "Categories",233 "type": "string",234 "defaultSelected": false,235 "relationOptions": []236 }237 ]238 }239 ]240}Exports - Preview
/report/exports/previewReturns the first preview page for the configured export without creating a job. Uses the same validation and relation-resolution rules as the real export pipeline. Requires view:reports.
For module=delivery and catalog=delivery-orders, columns may include sender_name, sender_phone, receiver_name, receiver_phone. Both CSV and XLSX support these strings, including service-scoped exports. Omitted or null contacts produce empty cells.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
module | string | — |
catalog | string | — |
format | string | — |
dateRange | object | — |
dateRange.from | string | — |
dateRange.to | string | — |
statuses | array<string> | — |
scope | object | — |
scope.type | string | — |
scope.values | array<string> | — |
columns | array<string> | — |
relationFields | array<object> | — |
Show 4 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
relationFields.field | string | — |
relationFields.output | string | — |
relationFields.table | string | — |
relationFields.referenceField | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/report/exports/preview?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "module": "delivery",6 "catalog": "driver-assignments",7 "format": "csv",8 "dateRange": {9 "from": "2026-05-01",10 "to": "2026-05-07"11 },12 "statuses": [13 "pending",14 "accepted"15 ],16 "scope": {17 "type": "driver",18 "values": [19 "<driver-uuid>"20 ]21 },22 "columns": [23 "assignment_time",24 "driver_id",25 "delivery_id",26 "status"27 ],28 "relationFields": [29 {30 "field": "driver_id",31 "output": "reference_value",32 "table": "drivers",33 "referenceField": "user.full_name"34 },35 {36 "field": "delivery_id",37 "output": "reference_value",38 "table": "deliveries",39 "referenceField": "delivery_code"40 }41 ]42}'Response examples
1{2 "success": true,3 "data": {4 "module": "delivery",5 "catalog": "driver-assignments",6 "category": "operational",7 "format": "csv",8 "previewLimit": 10,9 "totalRows": 24,10 "done": false,11 "columns": [12 {13 "key": "assignment_time",14 "label": "Assignment Time",15 "type": "datetime",16 "relationOutput": null17 },18 {19 "key": "driver_id",20 "label": "Driver",21 "type": "uuid",22 "relationOutput": "reference_value"23 },24 {25 "key": "delivery_id",26 "label": "Delivery",27 "type": "uuid",28 "relationOutput": "reference_value"29 },30 {31 "key": "status",32 "label": "Status",33 "type": "enum",34 "relationOutput": null35 }36 ],37 "rows": [38 {39 "assignment_time": "2026-05-07T10:30:00Z",40 "driver_id": "John Driver",41 "delivery_id": "DEL-1001",42 "status": "accepted"43 }44 ]45 }46}Exports - Create Zone Pricing
/report/exportsQueues an XLSX or CSV export of filtered Zone Pricing rules for the authenticated tenant. Each rule produces one row. Origins, destinations and services are ordered readable strings; inactive historical relationship rows are excluded. Optional filters supports UUID arrays for origin_zone_ids, origin_tag_ids, destination_zone_ids, destination_tag_ids, and service_ids. Semantics: (origin zones OR origin tags) AND (destination zones OR destination tags) AND (services), then AND with optional statuses and updated_at dateRange. Empty arrays are ignored. Unknown filter keys, non-array values, and invalid UUIDs return 400 invalid_request. Requires export:reports.
For module=delivery and catalog=delivery-orders, columns may include sender_name, sender_phone, receiver_name, receiver_phone. Both CSV and XLSX support these strings, including service-scoped exports. Omitted or null contacts produce empty cells.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
module | string | — |
catalog | string | — |
format | string | — |
statuses | array<string> | — |
dateRange | object | — |
dateRange.from | string | — |
dateRange.to | string | — |
filters | object | — |
filters.origin_zone_ids | array<string> | — |
filters.origin_tag_ids | array | — |
filters.destination_zone_ids | array<string> | — |
filters.destination_tag_ids | array | — |
Show 2 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
filters.service_ids | array<string> | — |
columns | array<string> | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/report/exports?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "module": "delivery",6 "catalog": "zone-pricing",7 "format": "xlsx",8 "statuses": [9 "active"10 ],11 "dateRange": {12 "from": "2026-08-01",13 "to": "2026-08-31T23:59:59Z"14 },15 "filters": {16 "origin_zone_ids": [17 "11111111-1111-4111-8111-111111111111"18 ],19 "origin_tag_ids": [],20 "destination_zone_ids": [21 "22222222-2222-4222-8222-222222222222"22 ],23 "destination_tag_ids": [],24 "service_ids": [25 "33333333-3333-4333-8333-333333333333"26 ]27 },28 "columns": [29 "origin_selector_type",30 "origins",31 "origin_count",32 "destination_selector_type",33 "destinations",34 "destination_count",35 "services",36 "base_price",37 "per_unit_price",38 "carrier_price",39 "effective_from",40 "effective_to",41 "status",42 "updated_at"43 ]44}'Response examples
1{2 "success": true,3 "data": {4 "id": "export-job-uuid",5 "module": "delivery",6 "catalog": "zone-pricing",7 "category": "pricing",8 "format": "xlsx",9 "status": "pending"10 }11}Exports - Create
/report/exportsCreates and queues an async export job. Returns immediately with id + status:"pending". Subscribe to realtime on report_export_jobs filtered by tenant_id to track progress. Requires export:reports.
relationFields is an array of { field, output, table?, referenceField? }:
field: column key fromcolumns(must be an ID column withrelationOptionsin the catalog).output:"id"keeps the raw UUID;"reference_value"resolves to a label.table+referenceFieldare required whenoutput === "reference_value"and must match a whitelistedrelationOptiondeclared on the column.referenceFieldsupports one nested level (e.g.user.full_namefordrivers→users).
Use GET /report/catalogs/:module to discover the allowed relationOptions per column.
For module=delivery and catalog=delivery-orders, columns may include sender_name, sender_phone, receiver_name, receiver_phone. Both CSV and XLSX support these strings, including service-scoped exports. Omitted or null contacts produce empty cells.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
module | string | — |
catalog | string | — |
format | string | — |
dateRange | object | — |
dateRange.from | string | — |
dateRange.to | string | — |
statuses | array<string> | — |
scope | object | — |
scope.type | string | — |
scope.values | array<string> | — |
columns | array<string> | — |
relationFields | array<object> | — |
Show 4 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
relationFields.field | string | — |
relationFields.output | string | — |
relationFields.table | string | — |
relationFields.referenceField | string | — |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/report/exports?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "module": "delivery",6 "catalog": "delivery-orders",7 "format": "csv",8 "dateRange": {9 "from": "2026-05-01",10 "to": "2026-05-07"11 },12 "statuses": [13 "assigned",14 "in_transit"15 ],16 "scope": {17 "type": "zone",18 "values": [19 "<zone-uuid-1>",20 "<zone-uuid-2>"21 ]22 },23 "columns": [24 "delivery_code",25 "customer_id",26 "status",27 "driver_id"28 ],29 "relationFields": [30 {31 "field": "customer_id",32 "output": "reference_value",33 "table": "users",34 "referenceField": "full_name"35 },36 {37 "field": "driver_id",38 "output": "reference_value",39 "table": "drivers",40 "referenceField": "user.full_name"41 }42 ]43}'Response examples
1{2 "success": true,3 "data": {4 "id": "00000000-0000-0000-0000-000000000010",5 "module": "delivery",6 "catalog": "delivery-orders",7 "category": "operational",8 "format": "csv",9 "status": "pending",10 "fileName": null,11 "fileSizeBytes": null,12 "rowCount": null,13 "progress": {14 "total": null,15 "done": 016 },17 "downloadUrl": null,18 "requestedAt": "2025-01-15T12:00:00Z",19 "startedAt": null,20 "completedAt": null,21 "errorSummary": null,22 "metadata": null23 }24}Exports - List
/report/exportsPaginated history of export jobs for the tenant. Filters by module/catalog/status. Requires view:reports.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
module | string | Example: |
catalogOptional | string | Example: |
status | string | Example: |
page | string | Example: |
limit | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/report/exports?tenant_id=${TENANT_ID}&language=en&module=delivery&status=ready&page=1&limit=20" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": [4 {5 "id": "00000000-0000-0000-0000-000000000010",6 "module": "delivery",7 "catalog": "delivery-orders",8 "category": "operational",9 "format": "csv",10 "status": "ready",11 "fileName": "delivery-orders-2025-01-15.csv",12 "fileSizeBytes": 52431,13 "rowCount": 1240,14 "progress": {15 "total": 1240,16 "done": 124017 },18 "downloadUrl": null,19 "requestedAt": "2025-01-15T12:00:00Z",20 "startedAt": "2025-01-15T12:00:01Z",21 "completedAt": "2025-01-15T12:00:09Z",22 "errorSummary": null,23 "metadata": null24 }25 ],26 "page": 1,27 "limit": 20,28 "total": 129}Exports - Get one
/report/exports/:idSingle job. Use this for polling fallback when realtime is unavailable.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/report/exports/${ID}?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": {4 "id": "00000000-0000-0000-0000-000000000010",5 "module": "delivery",6 "catalog": "delivery-orders",7 "category": "operational",8 "format": "csv",9 "status": "processing",10 "fileName": null,11 "fileSizeBytes": null,12 "rowCount": null,13 "progress": {14 "total": 1240,15 "done": 50016 },17 "downloadUrl": null,18 "requestedAt": "2025-01-15T12:00:00Z",19 "startedAt": "2025-01-15T12:00:01Z",20 "completedAt": null,21 "errorSummary": null,22 "metadata": null23 }24}Exports - Download (signed URL)
/report/exports/:id/downloadReturns a short-lived (5 min) signed URL for the generated file. Job must be in ready status.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/report/exports/${ID}/download?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": {4 "id": "00000000-0000-0000-0000-000000000010",5 "module": "delivery",6 "catalog": "delivery-orders",7 "category": "operational",8 "format": "csv",9 "status": "ready",10 "fileName": "delivery-orders-2025-01-15.csv",11 "fileSizeBytes": 52431,12 "rowCount": 1240,13 "progress": {14 "total": 1240,15 "done": 124016 },17 "downloadUrl": "https://<project>.supabase.co/storage/v1/object/sign/report-exports/exports/<tenant>/<job>/delivery-orders-2025-01-15.csv?token=...",18 "requestedAt": "2025-01-15T12:00:00Z",19 "startedAt": "2025-01-15T12:00:01Z",20 "completedAt": "2025-01-15T12:00:09Z",21 "errorSummary": null,22 "metadata": null23 }24}Exports - Cancel
/report/exports/:id/cancelCancels a pending or processing job. Requires export:reports. Returns 409 if the job is already in a terminal state.
For module=delivery and catalog=delivery-orders, columns may include sender_name, sender_phone, receiver_name, receiver_phone. Both CSV and XLSX support these strings, including service-scoped exports. Omitted or null contacts produce empty cells.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Example: |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/report/exports/${ID}/cancel?tenant_id=${TENANT_ID}&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": {4 "id": "00000000-0000-0000-0000-000000000010",5 "status": "cancelled",6 "completedAt": "2025-01-15T12:00:30Z"7 }8}Exports - Resume (Internal Cron)
/report/exports/:id/_resumeRe-dispatches an existing report-export job after its worker lease expires. The worker claims only pending jobs or jobs with an expired lease, preserving idempotency. id is the export-job UUID. HTTP 200 acknowledges dispatch, not completed file generation. Unauthorized messages are localized using the request language.
Internal backend/cron only. Send apikey: {{supabase_secret_key}} with the default managed Supabase secret key (SUPABASE_SECRET_KEYS.default). Never put this value in a frontend or mobile application. Missing, invalid, publishable, legacy anon, and legacy service-role bearer credentials return HTTP 401 before work is dispatched. Authorization: Bearer ... alone is not accepted. Frontend handoff: none; application clients must not call this internal endpoint.
Path parameters
| Parameter | Type | Description |
|---|---|---|
idRequired | string | Existing report-export job UUID. Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Content-Type | string | Example: |
apikey | string | Default managed Supabase secret key; backend only. Example: |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/report/exports/${ID}/_resume" \2 --header "Content-Type: application/json" \3 --header "apikey: ${SUPABASE_SECRET_KEY}" \4 --data-raw '{}'Internal backend endpoint. Run from a trusted server; keep backend secret keys out of the browser.
Response examples
1{2 "success": true,3 "dispatched": true4}