Skip to main content

External & Carrier Integrations

3 API calls in this section.

Global JSON response contract for every /external/* endpoint:

  • success is always a boolean.

  • error is null for success and a stable snake_case code for failure.

  • message is always a readable message localized from the request language.

  • Existing endpoint-specific data fields remain unchanged at the top level.

  • Existing HTTP status codes remain unchanged.

  • POST /external/deliveries/shipment-labels keeps its successful application/pdf binary response so existing downloads continue to work; every JSON error from that endpoint follows this contract.

Frontend integration

branch on HTTP status and error; display message; continue reading existing endpoint-specific payload fields exactly as before.

Global JSON response contract for every /external/* endpoint
{
  "success": true,
  "error": null,
  "message": "Localized readable message"
}

Get Shipment Labels​

External & Carrier Integrations / External & Carrier Integrations
POST/external/deliveries/shipment-labels

Returns an application/pdf response containing canonical shipment labels for one or multiple deliveries. Use one delivery_codes value for a single shipment and multiple values for a combined PDF.

Authentication and authorization

Requires X-API-Key authentication. Tenant scope comes from the authenticated context. Customer callers may request only their own deliveries; privileged tenant callers may request any delivery in that tenant.

Request

delivery_codes is required and accepts 1-50 non-empty delivery-code strings. Duplicates are removed in first-seen order.

Current-label behavior

Missing, stale, or unreadable labels use guarded generation; unstarted queued jobs can be claimed immediately, while running generation is awaited through the shared single-label lifecycle. Receiver data comes from the delivery's current delivery_location. Each successful generation has a new numeric file version and audit history; older PDF files remain available. A failed reprint preserves the previous URL.

Response

Success is PDF binary with Content-Disposition; errors are localized JSON. Combined PDFs use the private content-addressed cache and do not reuse the previous cache key after a canonical label changes.

Errors

400 invalid body/code or over 50 unique codes; 403 ownership/permission; 404 delivery/tenant not found; 413 byte limit; 422 invalid PDF; 500 lookup/cache/signing/upload errors; 502 label generation/download failure. No partial PDF is returned.

Concurrent printing

Successful labels with a URL are reused. Missing or needs_reprint labels use an atomic shared claim. A queued creation job can be claimed immediately by either foreground printing or its background worker. The atomic delivery-row lock permits only one generator; an unexpired active generator is joined instead of superseded, and delayed background jobs reuse completed labels. Generation and batch polling share a 90-second budget per request, leaving time for PDF merge/upload. Polls fetch pending IDs together. If the budget expires, HTTP 503 with code label_generation_in_progress asks the caller to retry; no partial PDF is returned. A later request may recover an abandoned active claim after 120 seconds; unstarted queued jobs have no grace-period delay. Version checks fence off superseded results. Unreadable-PDF repair explicitly replaces the observed version, and concurrent repairs reuse its replacement. Creation and reprint triggers are unchanged. The external error envelope retains its stable error field; successful responses remain PDF binary.

Headers

ParameterTypeDescription
X-API-Keystring

Authenticated external API key.

Example: {{api_key}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
delivery_codesarray<string>—
Staging
Request
curl
1curl --globoff --request POST "https://staging-api.ondi.io/functions/v1/external/deliveries/shipment-labels" \2  --header "X-API-Key: ${ONDI_TENANT_API_KEY}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "delivery_codes": [6    "2501",7    "2502"8  ]9}'

Response examples

200OK
Response body
text
1<binary PDF response>

Calculate Delivery Price​

External & Carrier Integrations / External & Carrier Integrations
GET/external/delivery/price

Calculate delivery price based on pickup and dropoff coordinates. This endpoint is designed for external integrations and accepts latitude/longitude coordinates directly instead of address IDs.

  • Requires X-API-Key authentication.

  • Public endpoint accessible to external systems

Pricing Logic

  • Determines the pickup and dropoff delivery zones from the coordinates

  • Looks up the applicable zone-pricing rule for the resolved origin/destination pair, including same-zone pairs

  • Uses the service default price only when no zone rule matches and the effective pricing policy allows fallback

  • If warehouse_id provided, uses warehouse address as pickup location

  • Supplied units affect the per-unit portion of zone pricing and are no longer replaced by the service maximum

  • Units must remain within the delivery service unit_min and unit_max range

  • Currency is resolved from tenant currency settings, then system currency settings, and falls back to IQD.

  • Returns error if locations are outside configured delivery zones

Frontend integration contract

  • Send the intended positive units value when quoting a known shipment size; the backend now honors it exactly.

  • Omit units only when pricing should use the configured missing-unit fallback. Read unit_size and unit_size_source from the success response.

  • Read currency_code for the OnDi currency code.

  • Handle HTTP 400 invalid_units_parameter for zero, negative, non-numeric, or unresolved template values.

  • Handle HTTP 400 can_not_use_this_delivery_for_this_unit_size by displaying the localized message; use calculated_unit_size, allowed_unit_min, allowed_unit_max, and violation for context.

Query parameters

ParameterTypeDescription
delivery_service_idRequiredstring

ID of the delivery service to calculate price for (Required) UUID of the delivery service

Example: {{delivery_service_id}}

pickup_latstring

Latitude of pickup location (Optional if warehouse_id provided, decimal format) (conditional): Latitude of pickup location (decimal format, e.g., 40.7128) - Required if warehouse_id not provided

Example: {{pickup_lat}}

pickup_lngstring

Longitude of pickup location (Optional if warehouse_id provided, decimal format) (conditional): Longitude of pickup location (decimal format, e.g., -74.0060) - Required if warehouse_id not provided

Example: {{pickup_lng}}

dropoff_latRequiredstring

Latitude of dropoff location (Required, decimal format) Latitude of dropoff location (decimal format, e.g., 40.7589)

Example: {{dropoff_lat}}

dropoff_lngRequiredstring

Longitude of dropoff location (Required, decimal format) Longitude of dropoff location (decimal format, e.g., -73.9851)

Example: {{dropoff_lng}}

warehouse_idOptionalstring

ID of the warehouse for pickup location (Optional, alternative to pickup_lat/lng) UUID of warehouse for pickup location (alternative to pickup_lat/lng)

Example: {{warehouse_id}}

unitsOptionalstring

Number of units for pricing calculation. When provided, this exact positive value is used. When omitted, the configured missing-unit fallback is used (Optional) Positive number of units for pricing. When provided, the API uses that exact value. When omitted, general.unit_size.settings.missing_unit_size_fallback selects service minimum, half of service maximum, service maximum, or returns HTTP 400 unit_size_or_dimensions_required.

Example: {{units}}

tenant_idRequiredstring

UUID of the tenant

Headers

ParameterTypeDescription
X-API-Keystring

Example: {{api_key}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/external/delivery/price?delivery_service_id=${DELIVERY_SERVICE_ID}&pickup_lat=${PICKUP_LAT}&pickup_lng=${PICKUP_LNG}&dropoff_lat=${DROPOFF_LAT}&dropoff_lng=${DROPOFF_LNG}&warehouse_id=${WAREHOUSE_ID}&units=${UNITS}" \2  --header "X-API-Key: ${ONDI_TENANT_API_KEY}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "error": null,4  "message": "Price calculated successfully",5  "price": 15.5,6  "currency_code": "IQD"7}

Get Zone by Coordinates​

External & Carrier Integrations / External & Carrier Integrations
GET/external/zone

Get the delivery zone that contains the given coordinates. This endpoint uses the get_zone_by_point database function to find which zone contains the specified latitude and longitude.

  • Requires X-API-Key authentication.

  • Public endpoint accessible to external systems

Query parameters

ParameterTypeDescription
latRequiredstring

Latitude of the location (Required, decimal format) Latitude of the location (decimal format, e.g., 40.7128)

Example: {{latitude}}

lngRequiredstring

Longitude of the location (Required, decimal format) Longitude of the location (decimal format, e.g., -74.0060)

Example: {{longitude}}

tenant_idRequiredstring

UUID of the tenant

Headers

ParameterTypeDescription
X-API-Keystring

Example: {{api_key}}

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/external/zone?lat=${LATITUDE}&lng=${LONGITUDE}" \2  --header "X-API-Key: ${ONDI_TENANT_API_KEY}"

Response examples

200OK
Response body
json
1{2  "success": true,3  "error": null,4  "message": "Zone found successfully",5  "zone": {6    "id": "123e4567-e89b-12d3-a456-426614174000",7    "name": "Downtown Zone",8    "boundaries": {9      "type": "Polygon",10      "coordinates": [11        [12          [13            40.7128,14            -74.00615          ],16          [17            40.72,18            -74.0119          ]20        ]21      ]22    },23    "is_active": true24  }25}