Skip to main content

Delivery Services

5 API calls in this section.

Delivery services may use tenant defaults, an active fulfillment policy profile, or custom policy_overrides. allow_returns controls whether the service can be selected for a return delivery and defaults to false. Under custom mode, policy_overrides.payment_policies.refund_delivery_fee_on_cancel and refund_delivery_fee_on_return are optional booleans. Missing fields inherit from the lower policy layer; effective defaults are Cancel = refund and Return = no refund.

List Delivery Services​

Delivery & Last-Mile / Delivery Services
GET/delivery/services

List delivery services with direct filters, AdvancedDataGrid column_filters, server-side sorting, pagination, customer-access scoping, and tenant-scoped KPI stats. Each service includes allow_returns and allowed_delivery_attempts.

Frontend integration contract

every operational G2G service dropdown calls this endpoint with context=g2g&active=true&include_stats=false. The Transfer Manifest Settings multi-select calls it without context=g2g so administrators can choose from all active tenant services.

Query parameters

ParameterTypeDescription
pageOptionalstring

Page number for pagination (default: 1)

Example: 1

limitOptionalstring

Number of items per page (default: 10, max: 100)

Example: 10

service_levelOptionalstring

Filter by service level (economy, standard, express, same_day, next_day, scheduled) economy|standard|express|same_day|next_day|scheduled

activeOptionalstring

Filter by active status (true/false)

Example: true

allow_returnsOptionalstring

Filter by return availability (true/false)

delivery_typeOptionalstring

Filter by delivery_type_id (UUID)

delivery_type_codeOptionalstring

Filter by delivery_type.code

searchOptionalstring

Search by name or code (ilike) ilike on name/code

price_orderOptionalstring

Order by default_price (asc/desc) legacy asc/desc sort on default_price

column_filtersOptionalstring

JSON object for grid column filters. Supports text, exact, boolean, numeric range, and created_at date-range filters. JSON string with keys name, code, description, service_level, delivery_type_code, active, allow_returns, default_price, unit_min, unit_max, estimated_delivery_time_min, estimated_delivery_time_max, signature_required, insurance_available, created_at

Example: {"service_level":"express","active":"true","default_price":{"min":100,"max":5000},"signature_required":"true"}

sort_byOptionalstring

Sort field. Allowed: name, code, default_price, unit_min, unit_max, service_level, estimated_delivery_time_min, estimated_delivery_time_max, priority, created_at, updated_at

Example: created_at

sort_orderOptionalstring

Sort direction (asc|desc). Defaults to desc. asc or desc (defaults to desc when sort_by is provided)

Example: desc

tenant_idOptionalstring

Tenant ID (defaults to authenticated user's tenant)

customer_idOptionalstring

Filter by customer (user) ID to see available services for that customer. If the authenticated user is a customer/no-role business user, this is applied automatically. user_id of customer; auto-applied when caller is a business customer

contextOptionalstring

Use g2g in every G2G service picker. A non-empty transfer_manifest.available_delivery_service_ids setting is applied before pagination; an empty list adds no limitation. only g2g is supported. It intersects the configured G2G allow-list with existing access scopes before pagination. Empty/missing available_delivery_service_ids means unrestricted.

include_statsOptionalstring

Set false for combobox requests to skip KPI queries. defaults to true; use false for repeated picker requests.

Example: true

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/services?page=1&limit=10&service_level=&active=true&allow_returns=&delivery_type=&delivery_type_code=&search=&price_order=&column_filters=%7B%22service_level%22%3A%22express%22%2C%22active%22%3A%22true%22%2C%22default_price%22%3A%7B%22min%22%3A100%2C%22max%22%3A5000%7D%2C%22signature_required%22%3A%22true%22%7D&sort_by=created_at&sort_order=desc&tenant_id=&customer_id=&context=&include_stats=true" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Delivery services retrieved successfully",4  "deliveryServices": [5    {6      "id": "8999fbc8-594e-4636-a88c-e8cc93609d9e",7      "name": "DCT",8      "code": "HJ888",9      "description": "test",10      "name_translations": {11        "en": "DCT",12        "ar": "...",13        "ku": "..."14      },15      "description_translations": {16        "en": "test",17        "ar": "...",18        "ku": "..."19      },20      "image_url": "https://cdn.example.com/service-icon.png",21      "priority": 10,22      "service_level": "economy",23      "default_price": 10,24      "estimated_delivery_time_min": 0,25      "estimated_delivery_time_max": 0,26      "allowed_delivery_attempts": 2,27      "service_options": {28        "signature_required": false,29        "insurance_available": false30      },31      "unit_min": 1,32      "unit_max": 5000,33      "delivery_type": {34        "id": "6e4b331f-0cff-44f4-a3c4-c4e8b3bd78fb",35        "code": "pickup_and_delivery",36        "name": "Pickup and Delivery"37      },38      "active": true,39      "allow_returns": true40    }41  ],42  "stats": {43    "totalServices": 42,44    "activeServices": 30,45    "deliveryTypesCount": 4,46    "recentlyAdded": []47  },48  "page": 1,49  "limit": 10,50  "total": 4251}

Create Delivery Service​

Delivery & Last-Mile / Delivery Services
POST/delivery/services

Create a new delivery service. Requires manage:operations:tenant permission.

  • Requires valid authentication token with manage:operations:tenant permission

    • When zone_selector_type=zone: zone_ids required if zone_access_mode is select_zones or exclude_zones

    • When zone_selector_type=tag: zone_tag_ids required if zone_access_mode is select_zones or exclude_zones

Errors

  • 404 delivery_type_not_found

  • 409 service_code_already_exists

  • 400 customer_ids_required_for_selected_access_mode

  • 400 zone_ids_required_for_selected_zone_mode

  • 400 invalid_zone_ids

  • 400 zone_tag_ids_required_for_tag_selector

  • 400 invalid_zone_tag_ids

  • 400 allowed_delivery_attempts_must_be_positive_integer

  • 500 internal_server_error

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
nameRequiredobject

(string OR localized object {en, ar, ku})

name.enstring—
name.arstring—
name.kustring—
codeRequiredstring—
descriptionOptionalobject

(string OR localized object)

description.enstring—
description.arstring—
description.kustring—
image_urlOptionalstring—
priorityOptionalinteger—
service_levelRequiredstring—
Show 18 more body fields

Additional body parameters

ParameterTypeDescription
default_priceOptionalnumber—
estimated_delivery_time_minOptionalnumber—
estimated_delivery_time_maxOptionalnumber—
allowed_delivery_attemptsOptionalnumber

(positive integer, default 1): customer-delivery attempts allowed before retry requires a dispatcher override reason; return-to-sender deliveries do not count

unit_minRequirednumber—
unit_maxRequirednumber—
service_optionsOptionalobject—
service_options.trackingboolean—
service_options.signature_requiredboolean—
service_options.insurance_availableboolean—
delivery_type_idRequiredstring—
activeOptionalboolean—
allow_returnsboolean—
access_modeOptionalstring

(all_users|select_users|exclude_users)

user_idsarray<string>

(required if access_mode is select_users or exclude_users)

zone_access_modeOptionalstring

(all_zones|select_zones|exclude_zones)

zone_selector_typeOptionalstring

(zone|tag, default: zone)

zone_tag_idsarray<string>—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/delivery/services?tenant_id=" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "name": {6    "en": "Express 24-Hour Delivery",7    "ar": "خدمة التوصيل السريع خلال 24 ساعة",8    "ku": "گەیاندنی خێرا 24 کاتژمێر"9  },10  "code": "EXP24",11  "description": {12    "en": "Premium express delivery service",13    "ar": "خدمة توصيل سريع مميزة",14    "ku": "خزمەتگوزاری گەیاندنی خێرای پریمیوم"15  },16  "image_url": "https://cdn.example.com/tenants/tenant_123/delivery-services/service-icon.png",17  "priority": 10,18  "service_level": "express",19  "default_price": 25.99,20  "estimated_delivery_time_min": 12,21  "estimated_delivery_time_max": 24,22  "allowed_delivery_attempts": 2,23  "unit_min": 1,24  "unit_max": 10,25  "service_options": {26    "tracking": true,27    "signature_required": true,28    "insurance_available": true29  },30  "delivery_type_id": "uuid",31  "active": true,32  "allow_returns": true,33  "access_mode": "select_users",34  "user_ids": [35    "user_uuid_1",36    "user_uuid_2"37  ],38  "zone_access_mode": "select_zones",39  "zone_selector_type": "tag",40  "zone_tag_ids": [41    "tag_uuid_1",42    "tag_uuid_2"43  ]44}'

Response examples

201201 Created
Response body
json
1{2  "success": true,3  "message": "service_created_successfully",4  "id": "uuid"5}

Update Delivery Service​

Delivery & Last-Mile / Delivery Services
PUT/delivery/services/:serviceId

Update an existing delivery service. Requires manage:operations:tenant permission.

  • Requires valid authentication token with manage:operations:tenant permission

  • code, service_level, delivery_type_id, default_price, estimated_delivery_time_min/max, allowed_delivery_attempts, unit_min/unit_max, service_options, active

  • allowed_delivery_attempts must be a positive integer. It controls customer-delivery retry warnings and excludes operational return attempts.

Errors

  • 404 service_not_found

  • 404 delivery_type_not_found

  • 409 service_code_already_exists

  • 400 invalid_customer_ids

  • 400 customer_ids_required_for_selected_access_mode

  • 400 invalid_zone_ids

  • 400 invalid_zone_tag_ids

  • 400 allowed_delivery_attempts_must_be_positive_integer

  • 500 internal_server_error

Path parameters

ParameterTypeDescription
serviceIdRequiredstring

ID of the delivery service to update

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token) Tenant ID (defaults to authenticated user's tenant)

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
nameOptionalobject

(string OR localized object)

name.enstring—
name.arstring—
name.kustring—
descriptionOptionalobject

(string OR localized object)

description.enstring—
description.arstring—
description.kustring—
image_urlOptionalstring—
priorityOptionalinteger—
default_pricenumber—
estimated_delivery_time_minnumber—
Show 15 more body fields

Additional body parameters

ParameterTypeDescription
estimated_delivery_time_maxnumber—
allowed_delivery_attemptsnumber—
unit_minnumber—
unit_maxnumber—
service_optionsobject—
service_options.trackingboolean—
service_options.signature_requiredboolean—
service_options.insurance_availableboolean—
activeboolean—
allow_returnsboolean—
access_modeOptionalstring

(all_users|select_users|exclude_users)

user_idsOptionalarray<string>—
zone_access_modeOptionalstring

(all_zones|select_zones|exclude_zones)

zone_selector_typestring

(zone|tag): zone_ids required when zone, zone_tag_ids required when tag

zone_idsarray<string>—
Staging
Request
curl
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/delivery/services/${SERVICEID}?tenant_id=" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "name": {6    "en": "Premium Express 24-Hour Delivery",7    "ar": "...",8    "ku": "..."9  },10  "description": {11    "en": "Updated premium express delivery",12    "ar": "...",13    "ku": "..."14  },15  "image_url": "https://cdn.example.com/tenants/tenant_123/delivery-services/new-icon.png",16  "priority": 5,17  "default_price": 29.99,18  "estimated_delivery_time_min": 10,19  "estimated_delivery_time_max": 24,20  "allowed_delivery_attempts": 2,21  "unit_min": 1,22  "unit_max": 10,23  "service_options": {24    "tracking": true,25    "signature_required": true,26    "insurance_available": true27  },28  "active": true,29  "allow_returns": true,30  "access_mode": "exclude_users",31  "user_ids": [32    "user_uuid_3"33  ],34  "zone_access_mode": "select_zones",35  "zone_selector_type": "zone",36  "zone_ids": [37    "zone_uuid_1"38  ]39}'

Response examples

409Conflict
Response body
json
1{2  "success": false,3  "code": "delivery_service_type_change_blocked_by_settings",4  "message": "The service type cannot be changed because this delivery service is used in system settings",5  "setting_references": [6    {7      "source": "tenant_settings",8      "setting_key": "return_requests"9    }10  ]11}

Get Delivery Service​

Delivery & Last-Mile / Delivery Services
GET/delivery/services/:serviceId

Get a delivery service by ID.

token required.

Response (full) includes

  • name / description (strings, localized to Accept-Language if translations available)

  • name_translations / description_translations (full JSONB objects for admin edit forms)

  • image_url (string, nullable)

  • priority (integer, nullable)

  • allowed_delivery_attempts (positive integer used for customer-delivery retry limits)

  • zone_access_mode (all_zones|select_zones|exclude_zones)

  • zone_selector_type (zone|tag)

  • zone_ids (array, populated when zone_selector_type=zone)

  • zones (array of {id, name}, populated when zone_selector_type=zone)

  • zone_tag_ids (array, populated when zone_selector_type=tag)

  • zone_tags (array of {id, name}, populated when zone_selector_type=tag)

  • teams, all_teams (team assignment info)

  • effective_policy (resolved fulfillment policy)

  • vehicle_ids, vehicles (vehicle restrictions)

Response (basic) includes only the core service record with delivery_type.

Responses

  • 200 service_retrieved_successfully

  • 404 service_not_found

  • 500 internal_server_error

Path parameters

ParameterTypeDescription
serviceIdRequiredstring

ID of the delivery service

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

response_typeOptionalstring

Response detail level: 'basic' (core fields + delivery_type only) or 'full' (includes users, zones, teams, policy, vehicles). Defaults to 'full'. basic or full (default: full). Use basic for fast lookups that only need core service fields.

Example: full

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/delivery/services/${SERVICEID}?tenant_id=&response_type=full" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

No saved response example. Use Try it to inspect a staging response.

Delete Delivery Service​

Delivery & Last-Mile / Delivery Services
DELETE/delivery/services/:serviceId

Delete (permanently) a delivery service. Requires manage:operations:tenant permission.

Responses

  • 200 service_deactivated_successfully

  • 404 service_not_found

  • 403 insufficient_permissions

  • 500 internal_server_error

Path parameters

ParameterTypeDescription
serviceIdRequiredstring

ID of the delivery service

Example: uuid

Query parameters

ParameterTypeDescription
tenant_idOptionalstring

Tenant ID (optional if in auth token)

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Staging
Request
curl
1curl --globoff --request DELETE "https://staging-api.ondi.io/functions/v1/delivery/services/${SERVICEID}?tenant_id=" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}"

Response examples

No saved response example. Use Try it to inspect a staging response.