API reference
Create an order
Hand one or more packages to Starmile in a single order. The order is your grouping (order_id); each parcel is a hub package with its own Starmile tracking number, and each parcel lists its products. Creating the order starts a logistics flow per parcel; the 201 returns the order with its parcels, and later status changes appear in your status pool.
Authentication is required (see Authentication). The order is created for the partner the credential belongs to, in the warehouse the credential is bound to — you never send those in the body.
Every order names a service_id — the id of a Service returned by GET /api/v1/services (read from your services & rates). The Service carries everything the order needs: the underlying flow, the corridor (origin & destination), and the delivery type— so you don’t send origin/destination.
You do not send a rate. Starmile resolves the applicable rate automatically and raises the invoice when the parcel reaches the status that rate is configured to bill on.
The delivery destination is bound to the service’s type: a Home Delivery service expects a parent_region + region, a Pudo Delivery service a pudo_id; Clearance and Cross Docking need no end-customer destination. A missing or invalid destination is rejected 422 with a message.
For Home Delivery you address the destination by your own reference: your parent region id/code in parent_region (e.g. "1") plus your leaf region id/code in region (e.g. "2"). Starmile maps that pair, per partner, to one of its regions — so your ids never need to match ours, and a leaf name that repeats across parents is disambiguated by the parent. The resolved region carries the delivery’s pricing tier.
If your reference is not mapped yet, the order is still accepted — it is not rejected. The response carries region_status: "mapped" when the region resolved, or "pending_mapping" when it did not. A pending_mapping order is queued for an operator to map your region in Starmile; once mapped, the waiting order is resolved automatically — you do not resend it. For a PUDO / locker / clearance service (no home region) region_status is "not_applicable".
Each entry in parcels[] is a physical package handled in the hub. item_id is your per-package reference — optional; when sent it is echoed back on the parcel as partner_tracking, and when omitted partner_tracking is left empty. merchant_trackingis the code on the sticker (also optional — set it later via the update endpoint, or omit it and Starmile fills it with the parcel’s own tracking number). Weights and dimensions are records-only; the hub re-measures (DWS) on arrival.
Your own references must be unique — your order_id, each parcel’s item_id, and each merchant_tracking. Reusing one that already exists (or repeating an item_id / merchant_tracking across parcels in the same order) is rejected 422 with a message, so re-sending an order never creates a duplicate.
One Starmile tracking per parcel
order_id on create — and each parcel gets its own internally. You address a parcel by your own merchant_tracking (barcode); operators scan by that or the Starmile tracking.Create an order
/api/v1/ordersBody — order
service_idintegerrequired- The id of a Service from GET /api/v1/services (the Service entity — the flow is resolved from it). Must be published for your partner in this warehouse.
order_idstringrequired- Your reference for the order (max 255).
gov_idstringoptional- Recipient government ID — the AZ FIN or a foreign passport number — used for the customs declaration.
customer_namestringoptional- Recipient name (max 255).
customer_phonestringoptional- Recipient phone (max 64).
customer_emailstringoptional- Recipient email.
pudo_idintegeroptional- Required for a pudo-channel service: the id of a PUDO point in the destination country. The delivery channel (home / pudo / locker) is a property of the chosen service, not a field you send.
parent_regionstringoptional- Required for a Home Delivery service: YOUR own parent region id/code (e.g. "1"). With region, it forms the per-partner mapping key an operator maps to one of Starmile's regions; the parent disambiguates a leaf that repeats across parents.
regionstringoptional- Required for a Home Delivery service: YOUR own leaf region id/code (e.g. "2"). Resolved map-only, per partner, to one of Starmile's regions (no name/id fallback). An unmapped reference does NOT reject the order — it is accepted with region_status "pending_mapping" and resolved once an operator maps it. The resolved region carries the delivery's pricing tier.
address_firststringoptional- Address line 1 (home delivery).
address_secondstringoptional- Address line 2 (home delivery).
zipstringoptional- Postal / zip code (max 32).
notesstringoptional- Delivery notes for the courier (max 1000).
shipping_costnumberoptional- Optional. What you charge to ship this order, in the declared-value currency; it becomes the customs transport cost. Range 0–1,000,000. A zero (or omitted) shipping cost is treated as none — the order stores no value and customs sends a minimum at declaration time.
consolidation_requiredbooleanoptional- Optional. Ask to consolidate the order's parcels. The chosen service must enable consolidation — otherwise the order is rejected 422 ("Consolidation is not enabled for this service.").
Body — parcels[]
parcels[].item_idstringrequired- Your per-package reference (max 255). Unique within the order. Echoed back on the parcel as partner_tracking.
parcels[].merchant_trackingstringoptional- The code on the physical sticker (optional; settable later).
parcels[].package_typestringoptional- One of: fragile, breakable, liquid.
parcels[].weight_gramsintegeroptional- Declared gross weight (records-only; DWS re-measures).
parcels[].length_mm / width_mm / height_mmintegeroptional- Declared dimensions in mm (records-only).
Body — parcels[].products[]
products[].namestringrequired- Product name (max 255).
products[].hs_codestringoptional- Harmonised System code (max 32).
products[].declared_valuenumberoptional- Declared customs value of the product.
products[].currencystringoptional- ISO-4217 currency code (3 letters).
products[].quantityintegeroptional- Quantity (default 1).
products[].weight_gramsintegeroptional- Product weight in grams.
Response (201)
data.order_idstringoptional- The created order's Starmile tracking number. Use it as the order_id on the status and management endpoints.
data.region_statusstringoptional- Home Delivery region resolution: "mapped" (resolved), "pending_mapping" (accepted, awaiting an operator mapping — resolves automatically, do not resend), or "not_applicable" (PUDO / locker / clearance — no home region).
data.items[]arrayoptional- One entry per parcel: your item_id (as sent, or null if omitted) and parcel_id — our parcel's Starmile tracking number.
curl -X POST https://api.starmile.io/api/v1/orders \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{
"service_id": 4,
"order_id": "PO-10294",
"gov_id": "5AB12C3",
"customer_name": "Aysel M.",
"customer_phone": "+994500000000",
"parent_region": "1",
"region": "2",
"address_first": "Nizami 10",
"address_second": "Apt 4",
"zip": "AZ1000",
"notes": "Ring twice",
"shipping_cost": 9.50,
"parcels": [
{
"item_id": "PKG-1",
"merchant_tracking": "CN773300012345",
"package_type": "fragile",
"weight_grams": 1400,
"products": [
{ "name": "Sneakers", "hs_code": "640411", "declared_value": 120.00, "currency": "USD", "quantity": 1 }
]
}
]
}'Update a parcel
Change a parcel’s details while the order is still at its flow’s first step — most often to set the merchant_tracking (sticker code) once you have it. Partial: only the fields you send change; products, when sent, replaces the whole list. Once the order has moved past its first step (for example the parcel has been received at the hub) the update is rejected 409. Requires the orders:update scope. The path uses your own references: order_idthen the parcel’s item_id.
Update a parcel
/api/v1/orders/{order_id}/parcels/{item_id}Body (all optional; partial update)
merchant_trackingstringoptional- The physical sticker code.
package_typestringoptional- One of: fragile, breakable, liquid.
weight_gramsintegeroptional- Declared gross weight (records-only).
length_mm / width_mm / height_mmintegeroptional- Declared dimensions in mm.
productsarrayoptional- Replaces the parcel's full product list (same shape as create).
curl -X PATCH https://api.starmile.io/api/v1/orders/PO-10294/parcels/PKG-1 \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{
"merchant_tracking": "CN773300099999",
"package_type": "liquid",
"products": [
{ "name": "Olive oil 1L", "hs_code": "150910", "declared_value": 18.0, "currency": "USD", "quantity": 2 }
]
}'Cancel an order
Cancel an order while it is still at its flow’s first step — before any of its packages have moved past it (e.g. been received or handed to a carrier). Once any parcel has advanced past the first step the cancel is rejected 409. Idempotent for an already-cancelled order. Requires the orders:cancel scope.
Cancel an order
/api/v1/orders/{order_id}/cancelBody
reasonstringoptional- Optional free-text cancellation reason.
curl -X POST https://api.starmile.io/api/v1/orders/PO-10294/cancel \
-H 'Authorization: Bearer <access_token>' \
-H 'Content-Type: application/json' \
-d '{ "reason": "customer changed their mind" }'