Get API key
Authenticated — all requests require Authorization: Bearer mk_test_…Learn more
API ReferencePickupsArrange a pickup

Arrange a pickup

POST/api/v1/pickups idempotent

Arrange a pickup for shipments returned by GET /v1/pickups/eligible-shipments. Send the same selection as the preview plus the preview_token it returned (valid 5 minutes). Requires Idempotency-Key and scope pickups:write. The first pickup arranged through the API switches the account to multiple pickup addresses (irreversible) and, when address is sent, saves that address. Fees belong to the whole address group of the day (or, for an arrangement made before the account switched, to the whole manifest): pickups arranged together share one fee, count it once per address_group_id / manifest_id, not per pickup. fee.state is the current state and the value to trust: for a new arrangement (fee.scope address_group) it is provisional until the day's last cut-off settles it and final afterwards; an older fee follows its own rule (manifest: final once its cut-off has locked or settled it; request: final from the start). Retries: the same Idempotency-Key with the same body returns the first response unchanged for 24 hours (including idempotent_replay: false). idempotent_replay: true appears when the same preview_token is sent again with a new Idempotency-Key and the booking already exists; that replay changes nothing and reports the current state, and it works after the 5-minute preview_token has expired. One exception: if the address sent inline was changed on file after the first booking, the retry is refused with 409 PICKUP_PREVIEW_STALE (1500107); that does not mean the booking failed, so keep the booking IDs from the first response and read the existing pickups with GET /v1/pickups/{pickup_id} instead of arranging again. pickup_slot is not part of the preview_token: it is checked again when the pickup is arranged, and a slot that is not open on the final date is rejected with PICKUP_INVALID_DATE_OR_SLOT instead of being replaced by another slot. After a new preview use a new Idempotency-Key.

Parameters

address
objectbody
A Hong Kong address to use directly. An address equal to one already on file is reused; otherwise it is saved.
address_id
stringbody
An existing pickup address. Send together with address_resolved_version; mutually exclusive with address.
address_resolved_version
stringbody
mode*
enum (fastest | specific_date)body
parcel_declarations
objectbody
Per destination box count and weight per box.
pickup_date
stringbody
A real calendar date, YYYY-MM-DD (Hong Kong). Required for specific_date, forbidden for fastest.
pickup_slot
enum (morning | afternoon | evening)body
preview_token*
stringbody
preview_token from POST /v1/pickups/preview (valid for 5 minutes).
shipment_ids*
array<string>body
shipment_id values from GET /v1/pickups/eligible-shipments.
simulation
objectbody
Test keys only: steers the sandbox simulator. outcome success (default) walks the pickup through submitted, driver_dispatched, picked_up and arrived_at_warehouse within about four minutes; failure makes the submission fail, so the pickup ends as failed. A failed test pickup keeps holding its shipments until it is cancelled, so cancel it within one hour of arranging it: after that it can no longer be cancelled and its test shipment stays held (create a new test shipment instead). Rejected with 400 for live keys.

Responses

Success body
{
  "status": 201,
  "message": "OK",
  "data": {
    "booking_intent_id": "3b9f0c1e-7a52-4d86-9c3e-0f4a1d2b6e75",
    "idempotent_replay": false,
    "manifest_id": null,
    "address_group_id": "6710a1b2c3d4e5f607182951",
    "address": {
      "address_id": "6710a1b2c3d4e5f607182940",
      "created": true
    },
    "multi_pickup_enabled_now": false,
    "livemode": false,
    "pickups": [
      {
        "id": "6710a1b2c3d4e5f607182960",
        "livemode": false,
        "simulated": true,
        "manifest_id": null,
        "address_group_id": "6710a1b2c3d4e5f607182951",
        "status": "requested",
        "destination": "yunexpress",
        "parcel_carriers": [
          "yunexpress"
        ],
        "shipment_ids": [
          "6710a1b2c3d4e5f607182931"
        ],
        "tracking_numbers": [
          "IM2610190000000001"
        ],
        "pickup_date": "2026-10-21",
        "scheduled_pickup_date": "2026-10-21",
        "pickup_window": {
          "start": "13:00",
          "end": "17:00",
          "timezone": "Asia/Hong_Kong"
        },
        "pickup_address": {
          "name": "Chan Tai Man",
          "phone": "+852 91234567",
          "email": "ops@example.com",
          "address_line": "Unit 1203, 12/F, Tower 2, Kowloon Commerce Centre, 51 Kwai Cheong Road, Kwai Chung"
        },
        "carrier_tracking_number": null,
        "pickup_courier": null,
        "failure_reason": null,
        "fee": {
          "scope": "address_group",
          "state": "provisional",
          "estimated_hkd": 45,
          "charged_hkd": 0,
          "refunded_hkd": 0
        },
        "cancellation": {
          "allowed": true,
          "deadline": "2026-10-19T04:12:40.123Z",
          "reason_code": null
        },
        "created_at": "2026-10-19T03:12:40.123Z",
        "updated_at": "2026-10-19T03:12:40.123Z"
      }
    ],
    "fee": {
      "state": "provisional",
      "free": false,
      "group_estimated_hkd": 45,
      "free_threshold_parcels": 5,
      "manifest_total_parcel_count": 1,
      "manifest_total_estimated_hkd": 45,
      "quota_conflicts": []
    }
  }
}

Returned object

FieldTypeSample
statusnumber201
messagestringOK
dataobject{9 keys}