API reference
Create shipments, follow them, and settle cash on delivery with a delivery company on ae.delivery. JSON over HTTPS, one bearer key, errors you can show to people.
Base URL https://api.ae.delivery/v1 · Version 2026-09-25 · OpenAPI document
Quick start
Ask the delivery company for a test key, then create your first shipment. With a test key nothing is sent and no rider is involved.
curl https://api.ae.delivery/v1/shipments \
-H "Authorization: Bearer $AED_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-10042-create" \
-H "AE-Version: 2026-09-25" \
-d '{
"merchant_reference": "ORDER-10042",
"service": "next_day",
"payment_type": "cod",
"cod_amount": 24500,
"receiver": { "name": "Test Receiver", "phone": "+971500000000", "language": "ar" },
"address": { "text": "Villa 12, Street 4, Al Nahda", "emirate": "SHJ", "area": "shj-al-nahda" }
}'The response is the shipment, with its tracking number and tracking link. Send the same request again with the same Idempotency-Key and you get the same shipment back, not a second one.
Authentication
Send your key in the Authorization header on every request. Keys are shown once when they are made; store them like passwords.
aed_test_sk_…
- Never sends a message to anyone.
- Never billed.
- Never reaches a real rider.
- Unlocks the simulator to move parcels through their life.
aed_live_sk_…
- Real parcels, real riders, real money.
- Every object carries livemode: true.
- Only issued once the delivery company is live.
Each key has scopes, listed with every endpoint below. A merchant key only ever sees that merchant's parcels.
Errors
Errors follow RFC 9457 (problem+json). Each has a stable code to branch on, a title in English and Arabic you can show to people, and a request id to quote to support.
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
AE-Request-Id: req_4f2a91c07be3d58a6e1f
{
"type": "https://docs.ae.delivery/errors/cancellation_window_closed",
"title": "It is too late to cancel this parcel",
"title_ar": "فات أوان إلغاء هذا الطرد",
"status": 409,
"code": "cancellation_window_closed",
"request_id": "req_4f2a91c07be3d58a6e1f"
}| HTTP | Code | Title (English) | Title (Arabic) |
|---|---|---|---|
| 400 | invalid_request | The request is not valid | الطلب غير صالح |
| 401 | unauthorized | Sign-in required | يلزم تسجيل الدخول |
| 403 | forbidden | You can't do this | لا يمكنك تنفيذ هذا الإجراء |
| 404 | not_found | Not found | غير موجود |
| 409 | conflict | This conflicts with the current state | يتعارض هذا مع الحالة الحالية |
| 409 | cancellation_window_closed | It is too late to cancel this parcel | فات أوان إلغاء هذا الطرد |
| 422 | duplicate_reference | This merchant reference already exists | هذا المرجع موجود مسبقاً |
| 422 | no_rate_card | No agreed rate for this parcel | لا يوجد سعر متفق عليه لهذا الطرد |
| 400 | idempotency_key_required | An Idempotency-Key header is required | يلزم ترويسة Idempotency-Key |
| 422 | idempotency_key_reused | This Idempotency-Key was used for a different request | استُخدم هذا المفتاح لطلب مختلف |
| 403 | test_mode_only | Only available with test keys | متاح فقط بمفاتيح الاختبار |
| 429 | too_many_attempts | Too many attempts, try again later | محاولات كثيرة، حاول لاحقاً |
| 500 | internal | Something went wrong; nothing was lost | حدث خطأ؛ لم يُفقد أي شيء |
Branch on code, never on the title text. Validation errors (422) also list each field that failed in errors.
Idempotency
Send an Idempotency-Key header on POST requests so a retry never creates something twice.
- The same key with the same body returns the stored response, marked with Idempotent-Replayed: true.
- The same key with a different body is refused with idempotency_key_reused.
- The key is required on settlements; the endpoint list says where.
- Your merchant_reference is also unique per merchant, so an order can only become one shipment.
Money is integer fils
Every amount is a whole number of fils, the smallest unit of the dirham. There are no decimals anywhere in the API, and the currency is always AED.
Round in your own system before you send; a fractional amount is refused. Cash collected, fees and settlements all use the same unit, so statements add up to the fils.
Webhooks
Delivery is on
Webhooks are being delivered to registered endpoints.
Webhooks follow Standard Webhooks v1. Each endpoint has its own secret starting whsec_, shown once when you create the endpoint.
- Every request carries webhook-id, webhook-timestamp and webhook-signature headers.
- The signature is HMAC-SHA256 over id, timestamp and the raw body, joined by dots.
- Failed deliveries are retried for about 27.5 hours; an endpoint failing for 5 days is disabled.
- Payloads carry sequence and occurred_at, so you can put events in order and drop duplicates by webhook-id.
- Personal details of the receiver are left out unless the endpoint opts in to include_pii.
// Verify an ae.delivery webhook (Standard Webhooks v1) with Node's built-in crypto.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyWebhook(rawBody, headers, secret /* "whsec_…" */) {
const id = headers["webhook-id"];
const ts = headers["webhook-timestamp"];
const sigs = String(headers["webhook-signature"] ?? "").split(" ");
if (!id || !ts) throw new Error("missing webhook headers");
// Reject anything older or newer than 5 minutes (replay protection).
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) throw new Error("timestamp outside tolerance");
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest();
const ok = sigs.some((s) => {
const [version, value] = s.split(",");
if (version !== "v1" || !value) return false;
const got = Buffer.from(value, "base64");
return got.length === expected.length && timingSafeEqual(got, expected);
});
if (!ok) throw new Error("bad signature");
return JSON.parse(rawBody); // then de-duplicate on webhook-id and order by "sequence"
}Event catalogue (67 events)
- shipment.created
- shipment.confirmed
- shipment.updated
- shipment.status_changed
- shipment.pickup_assigned
- shipment.picked_up
- shipment.pickup_failed
- shipment.received_at_hub
- shipment.out_for_delivery
- shipment.arrived
- shipment.delivery_attempt_failed
- shipment.rescheduled
- shipment.address_changed
- shipment.on_hold
- shipment.released
- shipment.delivered
- shipment.return_initiated
- shipment.returned
- shipment.cancelled
- shipment.corrected
- pickup.created
- pickup.assigned
- pickup.completed
- pickup.failed
- pickup.cancelled
- pod.captured
- label.generated
- shipment.feedback_received
- complaint.created
- cod.collected
- cod.collection_failed
- cod.handed_over
- settlement.created
- settlement.voided
- statement.issued
- import.completed
- import.failed
- carrier.status_unmapped
- carrier.booking_failed
- webhook_endpoint.disabled
- api_key.created
- api_key.revoked
- ping
- eta.updated
- shipment.at_risk
- shipment.pickup_requested
- shipment.pickup_en_route
- shipment.pickup_arrived
- shipment.sorted
- shipment.transfer_departed
- shipment.transfer_arrived
- shipment.handed_to_carrier
- shipment.en_route
- shipment.partially_delivered
- shipment.reattempt_requested
- shipment.return_assigned
- shipment.return_out_for_delivery
- shipment.return_attempt_failed
- shipment.pieces_mismatch
- shipment.issue_reported
- shipment.exception_closed
- shipment.reopened
- shipment.exchange_created
- shipment.reverse_pickup_created
- cod.not_collected
- cod.reversed
- shipment.created_at_pickup
Merchant endpoints never receive company-only events such as cash handovers between riders and the company.
Test mode
With a test key, parcels move only when you move them. Advance a parcel one step, or run a whole scenario:
- happy_path
- Picked up, at the hub, out for delivery, delivered.
- failed_then_delivered
- The first delivery attempt fails with a reason, the second succeeds.
- rto
- Delivery fails and the parcel goes back to the sender.
- cod_short
- Delivered, but the rider collects less cash than asked, so the statement shows the difference.
curl -X POST https://api.ae.delivery/v1/test/shipments/shp_…/simulate \
-H "Authorization: Bearer $AED_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{ "scenario": "failed_then_delivered" }'Scenarios are chosen by the request, never by special phone numbers. The simulator endpoints refuse live keys with test_mode_only.
Status model
A shipment has one status from this fixed set, plus a finer sub-status. The receiver wording is what the tracking page shows. The same list is served at GET /v1/meta/statuses.
| Status | What the receiver sees | Final | Sub-statuses |
|---|---|---|---|
| draft | Not shown to receivers | No | draft |
| ready_for_pickup | Order receivedتم استلام الطلب | No | awaiting_pickup_assignmentpickup_assignedrider_en_route_to_pickuprider_arrived_at_pickuppickup_attempt_failedawaiting_dropoff_at_hub |
| picked_up | Picked upتم الاستلام من المتجر | No | picked_upin_transit_to_hubpicked_up_partialawaiting_details |
| at_hub | At our facilityفي مركز التوزيع | No | received_at_hubsortedin_transferreceived_at_destination_hubawaiting_rider_assignmentassigned_to_riderheld_for_self_collectionscheduled_for_future_date |
| out_for_delivery | On the wayفي الطريق إليك | No | out_for_deliveryrider_en_routearrived_at_dropoff |
| attempt_failed | Delivery attemptedتمت محاولة التوصيل | No | attempt_failedreattempt_scheduledawaiting_merchant_instructionawaiting_receiver_response |
| on_hold | On holdمعلّق | No | held_by_merchantheld_by_tenantaddress_verificationid_verificationpayment_verificationdamaged_under_reviewheld_by_receivermissing_under_investigation |
| returning | Returning to senderقيد الإرجاع | No | return_requestedreturn_at_hubreturn_out_for_deliveryreturn_attempt_failedreturn_assignedreturn_arrived_at_merchant |
| delivered | Deliveredتم التوصيل | Yes | delivered_to_recipientdelivered_to_alternatedelivered_to_safe_placepartially_deliveredcollected_by_recipient |
| returned | Returnedتم الإرجاع | Yes | returned_to_merchantreturned_to_merchant_partial |
| cancelled | Cancelledأُلغي | Yes | cancelled_by_merchantcancelled_by_tenantcancelled_no_service_areacancelled_duplicate |
| closed_exception | Issue with shipmentمشكلة في الشحنة | Yes | lostdamageddisposed_on_requestdisposed_unclaimed |
A final status does not change again, except by a correction, which arrives as shipment.corrected.
Endpoints
Generated from the same route list as the OpenAPI document. Paths are relative to the base URL.
Quotes
- post
/v1/quotesQuote a price, promised date and serviceability
Scopes: quotes:writeRequest body (19 fields)
Request body fields Field Type Notes merchant_id string Required for tenant keys; ignored for merchant keys service enum next_day · same_day · scheduled · express · return_pickup — default "next_day" payment_type enum prepaid · cod · card_on_delivery · pay_by_link — default "prepaid" cod_amount integer Integer fils (AED 1.00 = 100) — default 0 — 0…100000000 pickup_location_id string destination object destination.text string The address exactly as entered, in its original language — length 3…500 destination.emirate enum AUH · DXB · SHJ · AJM · UAQ · RAK · FUJ destination.area string Area/community name (EN or AR) or a gazetteer id like shj-al-nahda — length 0…120 destination.street string length 0…200 destination.building string length 0…120 destination.floor string length 0…20 destination.unit string length 0…40 destination.landmark string length 0…200 destination.lat number 22…27 destination.lng number 51…57 destination.pin_source enum receiver · merchant · geocoder · rider · makani destination.makani string ready_for_pickup_at string date-time * required. Field notes are in English, as in the OpenAPI document.
Shipments
- post
/v1/shipmentsCreate a shipment (or a draft)
Scopes: shipments:writeIdempotency-Key: optionalRequest body (46 fields)
Request body fields Field Type Notes merchant_id string Required for tenant keys; ignored for merchant keys merchant_reference * string Your order id; unique per merchant; echoed everywhere — length 1…64 service enum next_day · same_day · scheduled · express · return_pickup — default "next_day" payment_type * enum prepaid · cod · card_on_delivery · pay_by_link cod_amount integer Integer fils (AED 1.00 = 100) — default 0 — 0…100000000 declared_value integer Integer fils (AED 1.00 = 100) — 0…100000000 quote_id string pickup_location_id string ready_for_pickup_at string date-time requested_delivery_date string Calendar date in Asia/Dubai receiver * object receiver.name * string length 1…120 receiver.phone * string UAE mobile; normalised to E.164 — length 7…20 receiver.alt_phone string length 7…20 receiver.email string email receiver.language enum ar · en — default "ar" address * object address.text * string The address exactly as entered, in its original language — length 3…500 address.emirate enum AUH · DXB · SHJ · AJM · UAQ · RAK · FUJ address.area string Area/community name (EN or AR) or a gazetteer id like shj-al-nahda — length 0…120 address.street string length 0…200 address.building string length 0…120 address.floor string length 0…20 address.unit string length 0…40 address.landmark string length 0…200 address.lat number 22…27 address.lng number 51…57 address.pin_source enum receiver · merchant · geocoder · rider · makani address.makani string parcel object default {"pieces":1,"flags":[]} parcel.description string length 0…300 parcel.pieces integer default 1 — 1…50 parcel.weight_grams integer 1…100000 parcel.size_class enum S · M · L · XL parcel.flags array<enum> default [] notes string length 0…500 consent object consent.channels array<enum> items 1… consent.wording string The exact wording the receiver agreed to; it must name the delivery company — length 10…1000 consent.captured_at string date-time consent.source string length 0…80 metadata map draft boolean default false exchange object Exchange: also collect an item from the receiver at the same stop (creates a linked return pickup) exchange.description string length 0…300 exchange.pieces integer default 1 — 1…50 * required. Field notes are in English, as in the OpenAPI document.
- get
/v1/shipmentsList shipments (cursor pagination)
Scopes: shipments:read - get
/v1/shipments/{id}Retrieve a shipment
Scopes: shipments:read - patch
/v1/shipments/{id}Edit a draft (any field, re-priced); after confirming, notes and metadata only
Scopes: shipments:writeRequest body (31 fields)
Request body fields Field Type Notes merchant_reference string length 1…64 service enum next_day · same_day · scheduled · express · return_pickup payment_type enum prepaid · cod · card_on_delivery · pay_by_link cod_amount integer Integer fils (AED 1.00 = 100) — 0…100000000 requested_delivery_date string Calendar date in Asia/Dubai receiver object receiver.name string length 1…120 receiver.phone string UAE mobile; normalised to E.164 — length 7…20 receiver.alt_phone string length 7…20 receiver.email string email receiver.language enum ar · en — default "ar" address object address.text string The address exactly as entered, in its original language — length 3…500 address.emirate enum AUH · DXB · SHJ · AJM · UAQ · RAK · FUJ address.area string Area/community name (EN or AR) or a gazetteer id like shj-al-nahda — length 0…120 address.street string length 0…200 address.building string length 0…120 address.floor string length 0…20 address.unit string length 0…40 address.landmark string length 0…200 address.lat number 22…27 address.lng number 51…57 address.pin_source enum receiver · merchant · geocoder · rider · makani address.makani string parcel object parcel.description string length 0…300 parcel.weight_grams integer 1…100000 parcel.size_class enum S · M · L · XL parcel.flags array<enum> notes string length 0…500 metadata map * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/confirmConfirm a draft
Scopes: shipments:write - post
/v1/shipments/{id}/cancelCancel (before pickup only; 409 cancellation_window_closed after). Optional {reason, note}
Scopes: shipments:writeRequest body (2 fields)
Request body fields Field Type Notes reason enum merchant_request · customer_changed_mind · duplicate · no_service_area · company_decision note string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/returnRequest return to origin. Optional {reason, note}
Scopes: shipments:writeRequest body (2 fields)
Request body fields Field Type Notes reason enum merchant_request · cancelled_after_pickup · recipient_refused · max_attempts · unclaimed · address_unresolvable · out_of_service_area · damaged · company_decision · partial_delivery_remainder note string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/holdPut a parcel on hold (merchants: reason merchant_request; before pickup or at the hub)
Scopes: shipments:writeRequest body (2 fields)
Request body fields Field Type Notes reason enum Merchants may use merchant_request only — merchant_request · receiver_request · address_check · id_check · payment_check · damaged · missing · company_check — default "merchant_request" note string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/releaseRelease your own hold (back to awaiting pickup, or to the hub queue)
Scopes: shipments:writeRequest body (1 field)
Request body fields Field Type Notes note string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/reattemptAsk for another delivery attempt after a failure (optionally on a day)
Scopes: shipments:writeRequest body (2 fields)
Request body fields Field Type Notes date string Optional new day (GST); omit for the next working day note string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/reverse-pickupBook a return pickup from the receiver of a delivered parcel (linked; priced as return_pickup)
Scopes: shipments:writeRequest body (4 fields)
Request body fields Field Type Notes description string length 0…300 pieces integer default 1 — 1…50 date string Calendar date in Asia/Dubai notes string length 0…500 * required. Field notes are in English, as in the OpenAPI document.
- get
/v1/shipments/{id}/timelineThe stage timeline (stage keys, EN/AR labels, times in GST, who) and the stage stepper
Scopes: shipments:read - post
/v1/shipments/{id}/forget-receiverForget the receiver: replace name, phones, email, address and pin with a pseudonymous token (company keys only; idempotent; body {reason})
Scopes: shipments:write - post
/v1/shipments/{id}/rescheduleReschedule delivery
Scopes: shipments:writeRequest body (2 fields)
Request body fields Field Type Notes date * string Calendar date in Asia/Dubai reason string length 0…300 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/change-requestsRequest a change after pickup
Scopes: shipments:writeRequest body (3 fields)
Request body fields Field Type Notes field * enum address · phone · date · cod value * any reason string length 0…300 * required. Field notes are in English, as in the OpenAPI document.
- post
/v1/shipments/{id}/delivery-detailsAdd the receiver and address to a parcel a rider collected by your own barcode/QR (status picked_up / awaiting_details; it cannot go out until this is done)
Scopes: shipments:writeRequest body (35 fields)
Request body fields Field Type Notes receiver * object receiver.name * string length 1…120 receiver.phone * string UAE mobile; normalised to E.164 — length 7…20 receiver.alt_phone string length 7…20 receiver.email string email receiver.language enum ar · en — default "ar" address * object address.text * string The address exactly as entered, in its original language — length 3…500 address.emirate enum AUH · DXB · SHJ · AJM · UAQ · RAK · FUJ address.area string Area/community name (EN or AR) or a gazetteer id like shj-al-nahda — length 0…120 address.street string length 0…200 address.building string length 0…120 address.floor string length 0…20 address.unit string length 0…40 address.landmark string length 0…200 address.lat number 22…27 address.lng number 51…57 address.pin_source enum receiver · merchant · geocoder · rider · makani address.makani string service enum Defaults to the service the parcel was collected under (next_day) — next_day · same_day · scheduled · express · return_pickup payment_type enum prepaid · cod · card_on_delivery · pay_by_link — default "prepaid" cod_amount integer Integer fils (AED 1.00 = 100) — default 0 — 0…100000000 declared_value integer Integer fils (AED 1.00 = 100) — 0…100000000 requested_delivery_date string Calendar date in Asia/Dubai parcel object parcel.description string length 0…300 parcel.weight_grams integer 1…100000 parcel.size_class enum S · M · L · XL parcel.flags array<enum> default [] notes string length 0…500 consent object consent.channels array<enum> items 1… consent.wording string The exact wording the receiver agreed to; it must name the delivery company — length 10…1000 consent.captured_at string date-time consent.source string length 0…80 * required. Field notes are in English, as in the OpenAPI document.
- get
/v1/shipments/{id}/eventsThe shipment's event history
Scopes: shipments:read
Labels
- get
/v1/shipments/{id}/labelLabel with your default label profile (?profile=<id>; ?format=pdf|png|tspl; png takes ?page=n)
Scopes: labels:read - get
/v1/labelsLabels for many parcels in one file (?ids=a,b,c up to 500; ?profile, ?format=pdf|png, ?page)
Scopes: labels:read
Print stations
- post
/v1/print-station/heartbeatPrint station: report host and printers (print-station keys only)
Scopes: print:station - post
/v1/print-station/claimPrint station: take the next queued job, or 204
Scopes: print:station - get
/v1/print-station/jobs/{id}/documentPrint station: the job's file (?format=pdf|png, ?page)
Scopes: print:station - post
/v1/print-station/jobs/{id}/ackPrint station: report done or failed ({ ok, error?, station_job_ref? })
Scopes: print:station
Pickups
- post
/v1/pickupsRequest a pickup
Scopes: pickups:writeRequest body (7 fields)
Request body fields Field Type Notes merchant_id string pickup_location_id * string date * string Calendar date in Asia/Dubai window_from string window_to string expected_count integer 1…500 shipment_ids array<string> items 0…500 * required. Field notes are in English, as in the OpenAPI document.
- get
/v1/pickupsList pickups
Scopes: pickups:write
Reference
- get
/v1/meta/statusesThe versioned status set with EN/AR labels
Scopes: none (public) - get
/v1/service-areasEmirates and areas served
Scopes: none (public) - post
/v1/addresses/validateResolve an address to an area and a quality score
Scopes: none (public)Request body (12 fields)
Request body fields Field Type Notes text * string The address exactly as entered, in its original language — length 3…500 emirate enum AUH · DXB · SHJ · AJM · UAQ · RAK · FUJ area string Area/community name (EN or AR) or a gazetteer id like shj-al-nahda — length 0…120 street string length 0…200 building string length 0…120 floor string length 0…20 unit string length 0…40 landmark string length 0…200 lat number 22…27 lng number 51…57 pin_source enum receiver · merchant · geocoder · rider · makani makani string * required. Field notes are in English, as in the OpenAPI document.
Tracking
- get
/v1/tracking/{tracking_number}Public tracking (receiver-safe fields only)
Scopes: tracking:read
Webhooks
- get
/v1/webhook-endpointsList webhook endpoints
Scopes: webhooks:manage - post
/v1/webhook-endpointsCreate a webhook endpoint (secret shown once)
Scopes: webhooks:manageRequest body (4 fields)
Request body fields Field Type Notes url * string uri — length 0…2000 description string length 0…200 events * array<string> Event types, or ["*"] — items 1… include_pii boolean default false * required. Field notes are in English, as in the OpenAPI document.
- delete
/v1/webhook-endpoints/{id}Delete a webhook endpoint
Scopes: webhooks:manage - post
/v1/webhook-endpoints/{id}/testSend a ping event
Scopes: webhooks:manage - get
/v1/webhook-endpoints/{id}/deliveriesDelivery log
Scopes: webhooks:manage - post
/v1/webhook-deliveries/{id}/retryResend a delivery
Scopes: webhooks:manage - get
/v1/eventsEvents feed (?after=<cursor>), 30-day retention
Scopes: shipments:read
Finance
- get
/v1/finance/balancesLive balances (COD held, fees due, remittable now)
Scopes: finance:read - get
/v1/statementsStatement for a period (?from&to), from the one builder
Scopes: finance:read - post
/v1/settlementsRecord a settlement (tenant keys; idempotent)
Scopes: finance:writeIdempotency-Key: requiredRequest body (7 fields)
Request body fields Field Type Notes merchant_id * string shipment_ids * array<string> items 1…2000 method * enum bank_transfer · cash · ziina external_reference * string The real-world reference: bank transfer ref, Ziina payment id or cash receipt — length 3…80 value_date * string Calendar date in Asia/Dubai direction enum to_merchant: the company pays the merchant its COD minus fees. from_merchant: fees exceed the COD held, and the merchant pays the difference. — to_merchant · from_merchant — default "to_merchant" expected_transfer_amount * integer The amount that actually moved (always positive); must equal the computed net in the stated direction or the request is refused — 0…100000000 * required. Field notes are in English, as in the OpenAPI document.
- get
/v1/settlementsList settlements
Scopes: finance:read
Test mode
- post
/v1/test/shipments/{id}/advanceTest mode: advance one step
Scopes: shipments:writeTest mode only - post
/v1/test/shipments/{id}/simulateTest mode: run a scenario
Scopes: shipments:writeTest mode onlyRequest body (1 field)
Request body fields Field Type Notes scenario * enum happy_path · failed_then_delivered · rto · cod_short * required. Field notes are in English, as in the OpenAPI document.
ae.delivery API. Examples use fictional data and a test key.