Skip to main content

Bulk Delivery Order Creations

10 API calls in this section.

Bulk delivery order import via signed-URL upload.

Three-step flow

  1. POST /delivery/bulk-order-creations/upload-url — server issues a one-time signed PUT URL.

  2. Client PUTs the file bytes directly to that URL.

  3. POST /delivery/bulk-order-creations — JSON body referencing the uploaded file_key plus 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_id is NOT a field — it is derived server-side from delivery_service_id.

  • File limits: ≤ 15 MB; extensions: csv, xls, xlsx.

  • is_draft=true creates imported deliveries as Draft while preserving normal payment processing; use Bulk Operations execute_draft to release selected Draft orders to Pending.

  • All endpoints (except _resume) require manage:operations:tenant or system admin.

Request Signed Upload URL​

Delivery & Last-Mile / Bulk Delivery Order Creations
POST/delivery/bulk-order-creations/upload-url

Step 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_extension

  • File too large → 413 file_too_large (limit returned in response)

Permissions

manage:operations:tenant or system admin.

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
file_nameRequiredstring

original file name; extension must be csv, xls, or xlsx.

file_size_bytesOptionalnumber

if provided, must be ≤ 15 MB (15728640 bytes).

Staging
Request
curl
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

200OK
Response body
json
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)​

Delivery & Last-Mile / Bulk Delivery Order Creations
PUT{{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/csv for .csv

  • application/vnd.ms-excel for .xls

  • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for .xlsx

Path parameters

ParameterTypeDescription
upload_urlRequiredstring

Variable used inside the request path.

Headers

ParameterTypeDescription
Content-Typestring

Example: text/csv

Staging
Request
curl
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 & Last-Mile / Bulk Delivery Order Creations
POST/delivery/bulk-order-creations

Step 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_phone

  • Optional: external_reference_id, cod_amount, package_special_instructions, package_items (CSV cell holds a JSON array string)

Row behavior

  • unit_size is calculated from usable package_items measurements. When measurements are absent, general.unit_size.settings.missing_unit_size_fallback is applied once per row using the job's preloaded effective setting.

  • If is_draft=true, each created row has delivery status=draft; use Bulk Operations action execute_draft later to move selected draft orders to Pending.

  • When tenant setting delivery_external_reference.unique_per_customer=true (default), an external_reference_id already used by the same customer root order is marked failed with external_reference_id_already_present; when false, duplicate values are accepted.

Permissions

manage:operations:tenant or system admin.

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
nameOptionalstring

human-friendly label for the import

source_viewRequiredstring

dispatcher | admin

customer_idRequiredstring

(required, UUID): tenant customer the deliveries are billed to / created for

delivery_service_idRequiredstring

(required, UUID): determines delivery_type_id server-side; do NOT send delivery_type_id

payer_typeRequiredstring

sender | receiver

payment_methodRequiredstring

wallet | cod | card | etc.

is_draftOptionalboolean

(optional, default false): when true, all successfully imported deliveries are created as Draft. Payment processing follows normal delivery creation; driver release waits for Execute.

mappingsRequiredobject

(required, object): maps your CSV header names → worker logical fields

mappings.Pickup Addressstring—
mappings.Pickup Latstring—
mappings.Pickup Lngstring—
mappings.Pickup Citystring—
Show 16 more body fields

Additional body parameters

ParameterTypeDescription
mappings.Pickup Countrystring—
mappings.Drop Addressstring—
mappings.Drop Latstring—
mappings.Drop Lngstring—
mappings.Drop Citystring—
mappings.Drop Countrystring—
mappings.Recipient Namestring—
mappings.Recipient Phonestring—
mappings.Referencestring—
mappings.CODstring—
mappings.Notesstring—
mappings.Itemsstring—
total_recordsOptionalnumber

(optional, int): client-side row count for UI; the worker reads the actual count from the file

file_keyRequiredstring

exact value returned by upload-url — the server uses the full storage key as the idempotency token (same file_key returns the existing job)

file_kindRequiredstring

csv | xls | xlsx

file_size_bytesOptionalnumber

(optional)

Staging
Request
curl
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

202Accepted
Response body
json
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 & Last-Mile / Bulk Delivery Order Creations
GET/delivery/bulk-order-creations

Paginated list of bulk import jobs for the current tenant, newest first.

Permissions

manage:operations:tenant or system admin.

Query parameters

ParameterTypeDescription
pagestring

Page number for pagination

Example: 1

limitstring

Items per page (max 200)

Example: 20

statusstring

Filter by status (pending | processing | completed | failed)

searchstring

ilike match on name OR idempotency_key

tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

200OK
Response body
json
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 & Last-Mile / Bulk Delivery Order Creations
GET/delivery/bulk-order-creations/:jobId

Returns 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

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

200OK
Response body
json
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 & Last-Mile / Bulk Delivery Order Creations
GET/delivery/bulk-order-creations/:jobId/success-csv

302 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

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

302Found

This response has no body.

Download Failed CSV​

Delivery & Last-Mile / Bulk Delivery Order Creations
GET/delivery/bulk-order-creations/:jobId/failed-csv

302 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

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

languagestring

Preferred language for response messages

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

302Found

This response has no body.

Resume Job (Internal Cron)​

Delivery & Last-Mile / Bulk Delivery Order Creations
POST/delivery/bulk-order-creations/:jobId/_resume

Internal 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

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Headers

ParameterTypeDescription
Content-Typestring

Example: application/json

apikeystring

Default managed Supabase secret key; backend only.

Example: {{supabase_secret_key}}

Staging
Request
curl
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

200OK
Response body
json
1{2  "success": true,3  "resumed": "uuid"4}

Abort Job​

Delivery & Last-Mile / Bulk Delivery Order Creations
POST/delivery/bulk-order-creations/:jobId/abort

Marks 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_found 404 — unknown ID or wrong tenant

  • job_already_terminal 409 — job status is already completed, failed, or cancelled

  • insufficient_permissions 403

Permissions

manage:operations:tenant or system admin.

Path parameters

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idstring

Tenant ID

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

200OK
Response body
json
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 & Last-Mile / Bulk Delivery Order Creations
DELETE/delivery/bulk-order-creations/:jobId/deliveries

Soft-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_found 404

  • job_still_running 409 — job is still active; abort first

  • insufficient_permissions 403

Permissions

manage:operations:tenant or system admin.

Path parameters

ParameterTypeDescription
jobIdRequiredstring

Bulk order creation job ID

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idstring

Tenant ID

languagestring

Example: en

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
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

200OK
Response body
json
1{2  "success": true,3  "message": "deliveries_deleted",4  "deleted_count": 135}