Bulk Delivery Order Creations
10 API calls in this section.
Bulk delivery order import via signed-URL upload.
Three-step flow
POST /delivery/bulk-order-creations/upload-url— server issues a one-time signed PUT URL.Client
PUTs the file bytes directly to that URL.POST /delivery/bulk-order-creations— JSON body referencing the uploadedfile_keyplus all job-level fields. Server verifies the file landed in storage, inserts the job row, and kicks off the background worker. Returns 202.
Polling endpoints expose status, signed download URLs for success.csv / failed.csv, the event_timeline, and per-row failure diagnostics.
Notes
delivery_type_idis NOT a field — it is derived server-side fromdelivery_service_id.File limits: ≤ 15 MB; extensions:
csv,xls,xlsx.is_draft=truecreates imported deliveries as Draft while preserving normal payment processing; use Bulk Operationsexecute_draftto release selected Draft orders to Pending.All endpoints (except
_resume) requiremanage:operations:tenantor system admin.
Request Signed Upload URL
/delivery/bulk-order-creations/upload-urlStep 1 of the bulk import flow. Returns a one-time signed PUT URL the client uploads the file to. The returned file_key must be passed back to Create Bulk Order Creation Job.
Validation
Unsupported extension → 400
unsupported_file_extensionFile too large → 413
file_too_large(limit returned in response)
Permissions
manage:operations:tenant or system admin.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
file_nameRequired | string | original file name; extension must be |
file_size_bytesOptional | number | if provided, must be ≤ 15 MB (15728640 bytes). |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/upload-url?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "file_name": "orders_batch_a.csv",6 "file_size_bytes": 5242887}'Response examples
1{2 "success": true,3 "file_key": "imports/<tenant_id>/<uuid>/original.csv",4 "file_kind": "csv",5 "upload_url": "https://<project>.supabase.co/storage/v1/upload/sign/bulk-delivery-imports/...",6 "token": "eyJhbGciOi...",7 "expires_at": "2026-04-30T13:30:00.000Z"8}Upload File To Signed URL (Client Side)
{{upload_url}}Step 2 of the bulk import flow. Client PUTs the file bytes directly to the signed URL returned by Request Signed Upload URL. No tenant headers — the URL is pre-authorized.
Use the matching Content-Type:
text/csvfor.csvapplication/vnd.ms-excelfor.xlsapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetfor.xlsx
Path parameters
| Parameter | Type | Description |
|---|---|---|
upload_urlRequired | string | Variable used inside the request path. |
Headers
| Parameter | Type | Description |
|---|---|---|
Content-Type | string | Example: |
1curl --globoff --request PUT "${UPLOAD_URL}" \2 --header "Content-Type: text/csv" \3 --data-binary '@/path/to/file'Response examples
No saved response example. Use Try it to inspect a staging response.
Create Bulk Order Creation Job
/delivery/bulk-order-creationsStep 3 of the bulk import flow. Creates the job row, verifies the file at file_key exists in storage, then kicks off the background worker. Returns 202 with the job row.
Logical fields (used as mappings values)
Required:
pickup_full_address,pickup_latitude,pickup_longitude,pickup_city,pickup_country,delivery_full_address,delivery_latitude,delivery_longitude,delivery_city,delivery_country,delivery_contact_name,delivery_contact_phoneOptional:
external_reference_id,cod_amount,package_special_instructions,package_items(CSV cell holds a JSON array string)
Row behavior
unit_sizeis calculated from usablepackage_itemsmeasurements. When measurements are absent,general.unit_size.settings.missing_unit_size_fallbackis applied once per row using the job's preloaded effective setting.If
is_draft=true, each created row has deliverystatus=draft; use Bulk Operations actionexecute_draftlater to move selected draft orders to Pending.When tenant setting
delivery_external_reference.unique_per_customer=true(default), anexternal_reference_idalready used by the same customer root order is marked failed withexternal_reference_id_already_present; when false, duplicate values are accepted.
Permissions
manage:operations:tenant or system admin.
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
Content-Type | string | Example: |
Body parameters
| Parameter | Type | Description |
|---|---|---|
nameOptional | string | human-friendly label for the import |
source_viewRequired | string |
|
customer_idRequired | string | (required, UUID): tenant customer the deliveries are billed to / created for |
delivery_service_idRequired | string | (required, UUID): determines |
payer_typeRequired | string |
|
payment_methodRequired | string |
|
is_draftOptional | boolean | (optional, default false): when true, all successfully imported deliveries are created as Draft. Payment processing follows normal delivery creation; driver release waits for Execute. |
mappingsRequired | object | (required, object): maps your CSV header names → worker logical fields |
mappings.Pickup Address | string | — |
mappings.Pickup Lat | string | — |
mappings.Pickup Lng | string | — |
mappings.Pickup City | string | — |
Show 16 more body fields
Additional body parameters
| Parameter | Type | Description |
|---|---|---|
mappings.Pickup Country | string | — |
mappings.Drop Address | string | — |
mappings.Drop Lat | string | — |
mappings.Drop Lng | string | — |
mappings.Drop City | string | — |
mappings.Drop Country | string | — |
mappings.Recipient Name | string | — |
mappings.Recipient Phone | string | — |
mappings.Reference | string | — |
mappings.COD | string | — |
mappings.Notes | string | — |
mappings.Items | string | — |
total_recordsOptional | number | (optional, int): client-side row count for UI; the worker reads the actual count from the file |
file_keyRequired | string | exact value returned by |
file_kindRequired | string |
|
file_size_bytesOptional | number | (optional) |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3 --header "Content-Type: application/json" \4 --data-raw '{5 "name": "Q2 storefront orders – batch A",6 "source_view": "dispatcher",7 "customer_id": "uuid",8 "delivery_service_id": "uuid",9 "payer_type": "sender",10 "payment_method": "wallet",11 "is_draft": false,12 "mappings": {13 "Pickup Address": "pickup_full_address",14 "Pickup Lat": "pickup_latitude",15 "Pickup Lng": "pickup_longitude",16 "Pickup City": "pickup_city",17 "Pickup Country": "pickup_country",18 "Drop Address": "delivery_full_address",19 "Drop Lat": "delivery_latitude",20 "Drop Lng": "delivery_longitude",21 "Drop City": "delivery_city",22 "Drop Country": "delivery_country",23 "Recipient Name": "delivery_contact_name",24 "Recipient Phone": "delivery_contact_phone",25 "Reference": "external_reference_id",26 "COD": "cod_amount",27 "Notes": "package_special_instructions",28 "Items": "package_items"29 },30 "total_records": 50,31 "file_key": "imports/<tenant_id>/<uuid>/original.csv",32 "file_kind": "csv",33 "file_size_bytes": 52428834}'Response examples
1{2 "success": true,3 "data": {4 "id": "uuid",5 "tenant_id": "uuid",6 "created_by": "uuid",7 "name": "Q2 storefront orders – batch A",8 "source_view": "dispatcher",9 "customer_id": "uuid",10 "delivery_service_id": "uuid",11 "payer_type": "sender",12 "payment_method": "wallet",13 "idempotency_key": "client-generated-uuid",14 "original_file_url": "imports/<tenant_id>/<uuid>/original.csv",15 "file_kind": "csv",16 "file_size_bytes": 524288,17 "status": "pending",18 "total_records": 50,19 "success_records": 0,20 "failed_records": 0,21 "progress": 0,22 "event_timeline": [23 {24 "event": "file_accepted",25 "at": "2026-04-30T13:00:00.000Z"26 },27 {28 "event": "mapping_received",29 "at": "2026-04-30T13:00:00.000Z"30 }31 ],32 "created_at": "2026-04-30T13:00:00.000Z",33 "is_draft": false34 }35}List Bulk Order Creations
/delivery/bulk-order-creationsPaginated list of bulk import jobs for the current tenant, newest first.
Permissions
manage:operations:tenant or system admin.
Query parameters
| Parameter | Type | Description |
|---|---|---|
page | string | Page number for pagination Example: |
limit | string | Items per page (max 200) Example: |
status | string | Filter by status (pending | processing | completed | failed) |
search | string | ilike match on name OR |
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations?page=1&limit=20&status=&search=&tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": [4 {5 "id": "uuid",6 "name": "Q2 storefront orders – batch A",7 "status": "completed",8 "total_records": 50,9 "success_records": 48,10 "failed_records": 2,11 "progress": 100,12 "created_at": "2026-04-30T13:00:00.000Z",13 "completed_at": "2026-04-30T13:02:14.000Z"14 }15 ],16 "pagination": {17 "page": 1,18 "limit": 20,19 "total": 1,20 "total_pages": 121 }22}Get Bulk Order Creation
/delivery/bulk-order-creations/:jobIdReturns the full job row plus signed download URLs (original_signed_url, success_signed_url, failed_signed_url), the event_timeline array (milestones: file_accepted, mapping_received, import_started, import_completed / import_failed), and failed_order_logs (per-row diagnostics).
Permissions
manage:operations:tenant or system admin.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/${JOBID}?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "data": {4 "id": "uuid",5 "tenant_id": "uuid",6 "name": "Q2 storefront orders – batch A",7 "status": "completed",8 "total_records": 50,9 "success_records": 48,10 "failed_records": 2,11 "progress": 100,12 "original_file_url": "imports/<tenant_id>/<job_id>/original.csv",13 "success_file_url": "imports/<tenant_id>/<job_id>/success.csv",14 "failed_file_url": "imports/<tenant_id>/<job_id>/failed.csv",15 "event_timeline": [16 {17 "event": "file_accepted",18 "at": "2026-04-30T13:00:00.000Z"19 },20 {21 "event": "mapping_received",22 "at": "2026-04-30T13:00:00.000Z"23 },24 {25 "event": "import_started",26 "at": "2026-04-30T13:00:05.000Z"27 },28 {29 "event": "import_completed",30 "success_records": 48,31 "failed_records": 2,32 "at": "2026-04-30T13:02:14.000Z"33 }34 ],35 "failed_order_logs": [36 {37 "row_number": 7,38 "error_field": "delivery_contact_phone",39 "error_code": "delivery_contact_phone_required"40 },41 {42 "row_number": 23,43 "error_field": "pickup_latitude",44 "error_code": "pickup_latitude_invalid"45 }46 ],47 "original_signed_url": "https://...signed...",48 "success_signed_url": "https://...signed...",49 "failed_signed_url": "https://...signed..."50 }51}Download Success CSV
/delivery/bulk-order-creations/:jobId/success-csv302 redirect to a signed URL for success.csv. Each CSV row carries the original CSV columns plus a delivery_id column. Returns 404 csv_not_ready if the worker has not yet generated the file.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/${JOBID}/success-csv?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
This response has no body.
Download Failed CSV
/delivery/bulk-order-creations/:jobId/failed-csv302 redirect to a signed URL for failed.csv. Each CSV row carries the original CSV columns plus row_number, error_field, error_code columns. Returns 404 csv_not_ready if the worker has not yet generated the file.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_idOptional | string | Tenant ID (optional if in auth token) |
language | string | Preferred language for response messages Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/${JOBID}/failed-csv?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
This response has no body.
Resume Job (Internal Cron)
/delivery/bulk-order-creations/:jobId/_resumeInternal cron-only hook invoked by the watchdog when a processing job's lease has expired. Re-triggers the worker, which re-runs all rows from the start; rows that already produced a delivery for the same bulk job are counted as success on recovery, while external-reference collisions with other deliveries remain row failures.
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. The unauthorized message is localized using the request language.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID 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/delivery/bulk-order-creations/${JOBID}/_resume" \2 --header "Content-Type: application/json" \3 --header "apikey: ${SUPABASE_SECRET_KEY}"Internal backend endpoint. Run from a trusted server; keep backend secret keys out of the browser.
Response examples
1{2 "success": true,3 "resumed": "uuid"4}Abort Job
/delivery/bulk-order-creations/:jobId/abortMarks a pending or processing job as cancelled and stops the worker from processing remaining rows. The job's worker_lease_id is cleared — any in-flight worker invocation will fail its next refreshLease call and exit cleanly.
Already-created deliveries are kept (not deleted automatically). Use DELETE /:id/deliveries if you want to remove them.
Errors
job_not_found404 — unknown ID or wrong tenantjob_already_terminal409 — job status is alreadycompleted,failed, orcancelledinsufficient_permissions403
Permissions
manage:operations:tenant or system admin.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Tenant ID |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/${JOBID}/abort?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "job_aborted",4 "data": {5 "id": "uuid",6 "status": "cancelled",7 "completed_at": "2026-05-19T12:00:00.000Z"8 }9}Delete Job Deliveries
/delivery/bulk-order-creations/:jobId/deliveriesSoft-deletes all delivery records (deleted_at set to now) that were created by this bulk import job. Only allowed when the job is in a terminal state (cancelled, completed, or failed). If the job is still pending or processing, abort it first.
Returns
deleted_count — number of deliveries that were soft-deleted.
Errors
job_not_found404job_still_running409 — job is still active; abort firstinsufficient_permissions403
Permissions
manage:operations:tenant or system admin.
Path parameters
| Parameter | Type | Description |
|---|---|---|
jobIdRequired | string | Bulk order creation job ID Example: |
Query parameters
| Parameter | Type | Description |
|---|---|---|
tenant_id | string | Tenant ID |
language | string | Example: |
Headers
| Parameter | Type | Description |
|---|---|---|
Authorization | string | Example: |
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/delivery/bulk-order-creations/${JOBID}/deliveries?tenant_id=&language=en" \2 --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"Response examples
1{2 "success": true,3 "message": "deliveries_deleted",4 "deleted_count": 135}