Authenticated — all requests require Authorization: Bearer mk_test_…Learn more
API ReferenceShipmentsCreate a shipment
Create a shipment
POST/api/v1/shipments idempotent
Re-quotes the selected service tier server-side, deducts the wallet in live mode (test mode skips), dispatches to the carrier, and returns the full shipment record with pricing snapshot + dispatch result. In live mode, dispatch.waybill_number is the carrier's waybill (e.g. Yun Express YT…) and dispatch.label_pdf_url its label PDF; with an mk_test_* key dispatch is skipped and dispatch is null — the example response shows a live-mode create. Requires Idempotency-Key. service_tier_id takes a Service Code (e.g. HKASTDGGSTCM) — list yours via GET /v1/service_tiers. Optional selected_surcharges opts into SIGNATURE / INSURANCE where eligible (check opt_in_availability on POST /v1/rates; eligibility is gated per destination and carrier product). Optional ioss_number (IM + 10 digits) overrides the account-level IOSS default for this shipment; EU destinations only.
Parameters
declared_currency
enum (HKD | USD)body
Declared-value currency for the whole shipment (items carry no currency of their own). "HKD": unit_price and unit_price_hkd are both HKD amounts; the server converts each item's HKD unit price to USD at the rate frozen when the order is placed and stores the shipment in USD (declared_currency reads back as "USD"), while billing still uses the HKD figures you sent (see declared_fx); if no rate can be resolved the whole shipment falls back to being stored in HKD and the order is never rejected for this reason. "USD": every item must use unit_price (not unit_price_hkd); in this mode an unresolvable rate returns 503 (FX_RATE_UNAVAILABLE). Omitted (changed in v1.20; previously always handled as "HKD"): decided by the price field the items use. If any item carries unit_price, the shipment is read as USD: unit_price is a USD amount, an item with no unit price is declared at 0, and an unresolvable rate returns 503. If no item carries unit_price (items use unit_price_hkd, or carry no unit price), the shipment is handled exactly as "HKD". Mixing unit_price and unit_price_hkd across items while declared_currency is omitted is rejected with 400 INVALID_FIELD. We recommend always sending declared_currency.
expected_discount_rule_id
stringbody
Discount rule_id returned by the selected /v1/rates option, or null when that option had no discount. When supplied, create rejects if the final quote differs.
expected_total_hkd
numberbody
total_hkd returned by the selected /v1/rates option. When supplied, create rejects if the final quote differs.
goods_category
stringbody
insured_amount
numberbody
Custom insured amount, in the shipment's declared currency — the same currency as unit_price (see declared_currency). Replaces the standard insurance pricing basis (0.7% × (freight + declared value), min HKD 9) with 0.7% × this amount converted to HKD at the frozen declared_fx rate (same minimum). Available only to accounts enrolled for custom insured amount, and only when the selected option's opt_in_availability INSURANCE entry (see POST /v1/rates) carries custom_insured_amount — today that means the cosmetics lane only. Requires "INSURANCE" in selected_surcharges (case-insensitive), else 400 INVALID_FIELD. Must be > 0 with at most 2 decimal places and at most USD 2500 (an HKD amount is converted at the frozen rate first) — any other value, or supplying it when the selected option does not support it, returns 400 INVALID_FIELD. On an HKD shipment for which no USD/HKD rate can be resolved, supplying it returns 503 FX_RATE_UNAVAILABLE.
ioss_number
stringbody
EU IOSS number (IM + 10 digits). Overrides the account-level default for this shipment; EU destinations only. With IOSS, EU VAT prepay is not charged and the number is forwarded to the carrier. The number must belong to your account — your own saved IOSS or a marketplace platform IOSS registered to you (contact support to add one); anything else returns 400 IOSS_NOT_OWNED.
items*
array<object>body
Required — at least one item (max 100). Every shipment must declare its contents; a request with no items is rejected with 400 before any order is created. unit_price / unit_price_hkd rules are unchanged (see each field).
metadata
objectbody
parcels*
array<object>body
payment_type
enum (prepaid | cod)body
Payment type. Only "prepaid" is currently available — "cod" (cash on delivery) returns 400 COD_NOT_AVAILABLE (1500034), with no quote, hold or shipment created.
recipient*
objectbody
reference_no
stringbody
Optional order reference of your own (e.g. your shop's order number, max 64 chars). Stored with the shipment, echoed in the create response, returned on list/detail reads, and usable as a list filter (GET /v1/shipments?reference_no=). Not required to be unique. Also printed on the carrier label when it is 6–50 characters of letters, digits and # & ( ) * + . : ; < = > ? [ ] ^ _ ` { | } - (not starting with = or +) and no other order already uses it; otherwise the label shows the iMile tracking number.
sales_platform_name
stringbody
Sales platform name (free text), required when recipient.country_code is JP — the carrier rejects Japan shipments without it. Optional for other destinations; when supplied it is still forwarded to the carrier. 1–50 characters.
selected_surcharges
array<string>body
Opt-in surcharge codes, e.g. ["SIGNATURE","INSURANCE"]. Eligibility is gated per destination and carrier product — check opt_in_availability on POST /v1/rates first; it is the authoritative source for which codes a given option accepts. Including "INSURANCE" when the final selected option's opt_in_availability marks it not selectable returns 400 INSURANCE_UNSUPPORTED — insurance is never silently dropped from an order.
sender
objectbody
service_tier_id*
stringbody
Service Code to book (e.g. HKASTDGGSTCM) — list the codes your account can use via GET /v1/service_tiers. The wire name service_tier_id is historical and kept for backwards compatibility.
tags
array<string>body
tax_number
stringbody
Destination tax registration number (e.g. Norway's VOEC number, or the recipient's RUT for Chile). Required for shipments to Norway (NO) unless voec_prepay is true, otherwise returns 400 TAX_NUMBER_REQUIRED. Required for shipments to Chile (CL) — the recipient's RUT — otherwise returns 400 CL_TAX_NUMBER_REQUIRED. Mutually exclusive with voec_prepay — sending both returns 400 VOEC_PREPAY_CONFLICT. 1–100 characters after trimming.
vat_prepay
booleanbody
Set true to have the carrier prepay destination VAT on your behalf (EU destinations only) instead of using an IOSS number. Mutually exclusive with ioss_number — sending both returns 400 IOSS_AND_PREPAY_CONFLICT. When true, the EU VAT prepay fee (declared value × destination VAT rate + 2% handling) is charged on the quote.
voec_prepay
booleanbody
Set true to have the carrier prepay Norway's VOEC VAT on your behalf, skipping tax_number entirely. Norway (NO) destinations only, on the standard-goods lane (service_tier_id HKASTDGGSTCM) or the cosmetics lane (HKASTDCSSTCM) — other lanes return 400 VOEC_PREPAY_UNSUPPORTED. Mutually exclusive with tax_number, ioss_number and vat_prepay — sending voec_prepay with any of them returns 400 VOEC_PREPAY_CONFLICT. Equivalent to including "NO_VOEC_PREPAY" in selected_surcharges (case-insensitive) — either form is honoured. When true, the fee is declared value × 27% on the standard-goods lane (plus HKD 3/shipment, and the carrier product silently switches to HK-ASS-PF) or declared value × 27% on the cosmetics lane (no switch, no per-shipment fee), charged on the quote.