Envíos

Create, pay, cancel, intercept, list, and fetch international outbound shipments (/v1/fulfillment/shipments/*).

Lifecycle {#lifecycle}

Public status codes: PENDINGWAIT_PAYMENTWAIT_SHIPSHIPPEDSIGNED. Cancel → CANCELLED.

Create / pay still return a summary total (freight / services / discount / payment). List is lightweight; detail is the full view (split boxes, packing media, first/last-mile relabel, charge lines, warehouse timeline). Scan events stay on International tracking. Field reference: response models.

Retired: POST /v1/fulfillment/shipments/preview, POST /v1/fulfillment/shipments/logistics/trace, POST /v1/fulfillment/shipments/cancel, POST /v1/fulfillment/shipments/detail. Use {id}/tracking, {id}/cancel, and GET {id} instead. Exact freight is returned on create.

POST /v1/fulfillment/shipments/create {#create}

Required: tracking_numbers[], receiver, shipping_channel_code. Optional:

  • external_shipment_id — idempotency key
  • remark

total.payment is the amount charged on pay:

"total": {
  "freight": { "amount": 8900, "currency": "CNY" },
  "services": { "amount": 1500, "currency": "CNY" },
  "discount": { "amount": 200, "currency": "CNY" },
  "payment": { "amount": 10200, "currency": "CNY" }
}

Returns id, order_sn, and status (typically PENDING). Public id is the warehouse numeric PK as a string (e.g. "115"); order_sn is the warehouse order number (e.g. JIYUNRI1349). Subsequent pay / cancel / detail / tracking paths use this id.

Create errors (live warehouse → 4xx error object):

HTTPerror.codeWarehouse upstream_codeTypical message
404PARCEL_NOT_FOUNDSHIPMENT_PACKAGE_NOT_FOUND部分包裹不存在
400SHIPMENT_CREATE_EXCEPTIONSHIPMENT_CREATE_EXCEPTION请先更新包裹…物品属性信息 / 有包裹不是已入库,下单失败
409EXTERNAL_ORDER_ID_ALREADY_EXISTSEXTERNAL_ORDER_ID_ALREADY_EXISTS外部订单号已存在

POST /v1/fulfillment/shipments/{shipment_id}/pay {#pay}

POST /v1/fulfillment/shipments/115/pay
Authorization: Bearer <API_KEY>

Path {shipment_id} is create/detail id (live warehouse numeric PK as a string, e.g. "115"). Warehouse also accepts order_sn. Sandbox uses sbs_* / sb_shp_*. Body may be empty. Warehouse upstream: POST /api/gateway-worker/v1/shipments/pay with { "shipment_id" } only — not external_shipment_id.

Charges fulfillment wallet. Successful pay → WAIT_SHIP.

Pay errors:

HTTPerror.codeWarehouse upstream_codeTypical message
404NOT_FOUNDSHIPMENT_NOT_EXISTS订单不存在
409SHIPMENT_ALREADY_PAIDSHIPMENT_ALREADY_PAID订单已支付
402INSUFFICIENT_BALANCEINSUFFICIENT_BALANCE余额不足

Sandbox sb_shp_pay_insufficient may still return 200 + success: false + error_code. Live warehouse uses the 4xx error object. See Errors.

POST /v1/fulfillment/shipments/{shipment_id}/cancel {#cancel}

cancel_reason is required. Warehouse upstream: POST /api/gateway-worker/v1/shipments/cancel with { shipment_id, cancel_reason }.

{
  "cancel_reason": "buyer_request"
}

Cancellable while PENDING or WAIT_PAYMENT. Success → CANCELLED.

POST /v1/fulfillment/shipments/{shipment_id}/intercept {#intercept}

v1 requests a hold after outbound has started. This does not change shipment lifecycle status. Warehouse upstream: POST /api/gateway-worker/v1/shipments/set-exceptional with { shipment_id, reason, remark }.

{
  "reason": "CUSTOMER_REQUEST",
  "remark": "Customer requested to stop the shipment before dispatch."
}

reason is a fixed CODE: CUSTOMER_REQUEST / ADDRESS_ISSUE / ORDER_CHANGE / PAYMENT_ISSUE / COMPLIANCE_ISSUE / PACKAGE_ISSUE / OTHER. remark is required when reason is OTHER.

Success:

{
  "shipment_id": "107",
  "interception": {
    "status": "REQUESTED",
    "reason": "ADDRESS_ISSUE",
    "remark": "Customer address needs to be corrected.",
    "requested_at": "2026-08-20T12:30:00Z"
  }
}

interception.status: REQUESTEDPROCESSINGINTERCEPTED / FAILED. Detail can show status: "SHIPPED" with interception.status: "REQUESTED".

Mock allows WAIT_SHIP and SHIPPED. PENDING / WAIT_PAYMENT / SIGNED / CANCELLEDSHIPMENT_NOT_INTERCEPTABLE. Use cancel before outbound.

HTTPerror.code
404SHIPMENT_NOT_FOUND
409SHIPMENT_NOT_INTERCEPTABLE
409SHIPMENT_INTERCEPTION_ALREADY_REQUESTED
422INVALID_INTERCEPTION_REASON
422INTERCEPTION_REMARK_REQUIRED

Sandbox: sb_shp_shipped can request intercept; sb_shp_unpaid / sb_shp_signed cannot; sb_shp_intercepted is already INTERCEPTED. Live warehouse SHIPMENT_NOT_EXISTS maps to SHIPMENT_NOT_FOUND.

GET /v1/fulfillment/shipments {#list}

GET /v1/fulfillment/shipments?status=WAIT_SHIP&created_from=2026-08-01&page=1&page_size=20
Authorization: Bearer <API_KEY>

Lightweight rows. Split boxes, packing files, legs, charge lines, timeline, and interception stay on detail. Warehouse upstream: POST /api/gateway-worker/v1/shipments/index.

QueryNotes
statusComma-separated or repeated. PENDING / WAIT_PAYMENT / WAIT_SHIP / SHIPPED / SIGNED / CANCELLED
created_fromLower bound (YYYY-MM-DD or datetime)
created_toUpper bound
pageDefault 1
page_sizeDefault 20, max 100

Each row has id (warehouse numeric PK as a string), order_sn, external_shipment_id, status, international_tracking, receiver, shipping_channel, services, total, payment_status, and times. Empty warehouse strings become null. Amounts are fen.

International tracking lives only on international_tracking — there is no top-level tracking_number. List times omit updated_at / packing_started_at (those stay on detail).

Sandbox includes fixtures (sb_shp_unpaid, sb_shp_shipped, sb_shp_signed, sb_shp_intercepted, …) plus dynamic sbs_* from create.

{
  "data": [
    {
      "id": "107",
      "order_sn": "JIYUNRI1338",
      "status": "WAIT_SHIP",
      "external_shipment_id": "MY-INTL-ORDER-001",
      "international_tracking": {
        "tracking_number": null,
        "carrier": null
      },
      "receiver": {
        "name": "John Doe",
        "mobile": "+12025550123",
        "email": "john@example.com",
        "country_code": "US",
        "province": "California",
        "city": "Los Angeles",
        "district": null,
        "postal_code": "90001",
        "address_line1": "123 Main St",
        "address_line2": "Apt 4B"
      },
      "shipping_channel": {
        "code": "PUHUO",
        "name": "General Cargo Air Line"
      },
      "services": [
        {
          "id": "2",
          "service_code": "2",
          "name": "Package Reinforcement",
          "quantity": 1,
          "status": "PENDING"
        }
      ],
      "total": {
        "charges": {
          "amount": 2000,
          "currency": "CNY"
        },
        "discount": {
          "amount": 0,
          "currency": "CNY"
        },
        "payable": {
          "amount": 2000,
          "currency": "CNY"
        },
        "paid": {
          "amount": 0,
          "currency": "CNY"
        },
        "outstanding": {
          "amount": 2000,
          "currency": "CNY"
        }
      },
      "payment_status": "UNPAID",
      "times": {
        "created_at": "2026-08-20T09:41:36Z",
        "packed_at": "2026-08-20T10:20:00Z",
        "paid_at": null,
        "shipped_at": null,
        "delivered_at": null,
        "cancelled_at": null
      }
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 20,
    "total": 1,
    "total_pages": 1
  },
  "monetary_unit": "CNY_minor",
  "request_id": "req_xxx"
}

GET /v1/fulfillment/shipments/{shipment_id} {#detail}

GET /v1/fulfillment/shipments/107?language=en
Authorization: Bearer <API_KEY>

Path {shipment_id} is detail id (live: warehouse numeric PK as a string, e.g. "107"; sandbox: sbs_* / sb_shp_*). Optional language is for display names (shipping_channel.name, services[].name, charges[].name). Do not expect status_name.

Warehouse upstream: POST /api/gateway-worker/v1/shipments/detail with { "shipment_id" } only. Public id is the warehouse numeric PK as a string (e.g. "107"); order_sn is the warehouse order number.

This shape covers warehouse facts create/pay cannot express:

ProblemWhere to look
Split outbound cartonsboxes[]; multi_box: true when more than one carton
International tracking numberinternational_tracking; per carton boxes[].tracking
Warehouse business eventstimeline[] (created / packed / paid). Not scan events
Packing photos / videofiles[]: PACKING_IMAGE / PACKING_VIDEO
Relabel (first mile ≠ last mile)shipping_legs[] when the warehouse sends first/last-mile numbers
BlockMeaning
source_packagesInbound domestic packages before consolidation (pkg_* + China tracking number)
boxesPacked outbound cartons; empty [] until packed
international_trackingShipment-level last-mile { tracking_number, carrier }; both null before outbound
timelineWarehouse business events. code may be null if warehouse sends ""
shipping_legsLine-haul vs destination last mile after relabel; [] until numbers exist
filesPacking media (not inbound VAS photos on the package)
chargesLine items. Discount rows are negative
totalcharges / discount (positive) / payable / paid / outstanding
payment_statusUNPAID / PAID / PARTIAL
timesTimestamps; unused nodes are null
interceptionIntercept handling, or null. Independent of shipment status

Amounts are fen (monetary_unit: CNY_minor). Empty arrays are [], not omitted.

Sandbox: GET /v1/fulfillment/shipments/sb_shp_shipped includes split boxes, both legs, and packing files. After create → pay, a dynamic sbs_* detail is WAIT_SHIP with source_packages filled and boxes still empty.

{
  "id": "107",
  "order_sn": "JIYUNRI1338",
  "status": "SHIPPED",
  "external_shipment_id": "MY-INTL-ORDER-001",
  "source_packages": [
    {
      "id": "pkg_01K2ABC001",
      "tracking_number": "SF2026082001"
    },
    {
      "id": "pkg_01K2ABC002",
      "tracking_number": "YT2026082002"
    }
  ],
  "receiver": {
    "name": "John Doe",
    "mobile": "+12025550123",
    "email": "john@example.com",
    "country_code": "US",
    "province": "California",
    "city": "Los Angeles",
    "district": null,
    "postal_code": "90001",
    "address_line1": "123 Main St",
    "address_line2": "Apt 4B"
  },
  "shipping_channel": {
    "code": "PUHUO",
    "name": "General Cargo Air Line"
  },
  "multi_box": true,
  "international_tracking": {
    "tracking_number": "1Z999999999",
    "carrier": "UPS"
  },
  "timeline": [
    {
      "code": "CREATED",
      "title": "Shipment created",
      "occurred_at": "2026-08-20T09:41:36Z"
    },
    {
      "code": "PACKED",
      "title": "Packed",
      "occurred_at": "2026-08-20T10:20:00Z"
    },
    {
      "code": "PAID",
      "title": "Paid",
      "occurred_at": "2026-08-20T10:30:00Z"
    }
  ],
  "boxes": [
    {
      "id": "box_01K2BOX001",
      "box_no": "JIYUNRI1338-1",
      "status": "SHIPPED",
      "source_package_ids": [
        "pkg_01K2ABC001",
        "pkg_01K2ABC002"
      ],
      "weight": {
        "value": 4.25,
        "unit": "kg"
      },
      "dimensions": {
        "length": 45,
        "width": 35,
        "height": 30,
        "unit": "cm"
      },
      "chargeable_weight": {
        "value": 4.73,
        "unit": "kg"
      },
      "tracking": {
        "tracking_number": "1Z999999001",
        "carrier": "UPS"
      }
    }
  ],
  "shipping_legs": [
    {
      "type": "FIRST_MILE",
      "carrier": "HioBuy Linehaul",
      "tracking_number": "HB202608200001",
      "origin_country": "CN",
      "destination_country": "US",
      "status": "DELIVERED",
      "shipped_at": "2026-08-20T12:00:00Z",
      "delivered_at": "2026-08-22T04:30:00Z"
    },
    {
      "type": "LAST_MILE",
      "carrier": "UPS",
      "tracking_number": "1Z999999999",
      "origin_country": "US",
      "destination_country": "US",
      "status": "IN_TRANSIT",
      "shipped_at": "2026-08-22T08:00:00Z",
      "delivered_at": null
    }
  ],
  "files": [
    {
      "id": "file_01K2ABC001",
      "type": "PACKING_IMAGE",
      "url": "https://cdn.hiobuy.com/shipments/JIYUNRI1338/packing-01.jpg",
      "created_at": "2026-08-20T10:20:00Z"
    }
  ],
  "charges": [
    {
      "type": "FREIGHT",
      "code": "FREIGHT",
      "name": "Shipping Fee",
      "amount": {
        "amount": 3200,
        "currency": "CNY"
      }
    },
    {
      "type": "COUPON_DISCOUNT",
      "code": "COUPON",
      "name": "Coupon Discount",
      "amount": {
        "amount": -300,
        "currency": "CNY"
      }
    }
  ],
  "total": {
    "charges": {
      "amount": 3200,
      "currency": "CNY"
    },
    "discount": {
      "amount": 300,
      "currency": "CNY"
    },
    "payable": {
      "amount": 2900,
      "currency": "CNY"
    },
    "paid": {
      "amount": 2900,
      "currency": "CNY"
    },
    "outstanding": {
      "amount": 0,
      "currency": "CNY"
    }
  },
  "payment_status": "PAID",
  "times": {
    "created_at": "2026-08-20T09:41:36Z",
    "updated_at": "2026-08-22T08:10:00Z",
    "packing_started_at": "2026-08-20T10:00:00Z",
    "packed_at": "2026-08-20T10:20:00Z",
    "paid_at": "2026-08-20T10:30:00Z",
    "shipped_at": "2026-08-20T12:00:00Z",
    "delivered_at": null,
    "cancelled_at": null
  },
  "interception": null,
  "monetary_unit": "CNY_minor",
  "request_id": "req_xxx"
}

See response models for charge type values.

Get Support

Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days

Email support