Skip to content

Create & Close Order

API Overview

Creates a shipment order (CN38) from parcels you have already registered, groups them into bags/AKEs/pallets, and closes the order in the same call. Closing triggers generation of the shipment documents, which you then retrieve with Get Order File.

Every parcel referenced here must already exist, belong to your account, and not yet be part of another order.

Request Information

  • Method: POST
  • Path: /api/order/create-order
  • Authentication: Bearer Token

Request Headers

FieldDescription
Content-Typeapplication/json
AuthorizationBearer <token>

Request Parameters

The request body is in JSON format and includes the following fields:

ParameterTypeRequiredDescription
ship_typeintegerYesContainer type: 1 = Bag, 2 = AKE, 3 = Pallet.
ship_routeintegerYesShipping route: 1 = Direct CN, 2 = Master2CN, 3 = Master2CN(T2T), 4 = Master2CN(OA), 5 = Transshipment CN, 6 = Transshipment CN(AF), 7 = Transshipment CN(VP).
is_ddpstringNoClearance mode: Y = DDP, N = DDU. Defaults to N. Must match the clearance mode of every parcel in the order.
destinationstringYesDestination country as a 2-letter code, e.g. SG for Singapore, TH for Thailand. Exactly 2 characters.
departure_portstringYesDeparture port code. Exactly 3 characters.
destination_portstringYesDestination port code. Exactly 3 characters.
outbound_flight_nostringYesOutbound flight number. Maximum 60 characters.
estimated_departure_datetimestringYesEstimated local departure time at origin, as a 10-digit UNIX timestamp in seconds.
estimated_arrival_datetimestringYesEstimated local arrival time at destination, as a 10-digit UNIX timestamp in seconds. Must be later than estimated_departure_datetime.
shipment_servicestringConditionalRequired when shipment services are available for the destination: TP = Tracked Packet, EM = EMS. Ignored for destinations that offer no choice.
ship_type_detailsarrayYesArray of containers. Each element is an array of the WMG tracking numbers packed into that bag/AKE/pallet, and must not be empty.
order_mawbobjectConditionalMAWB details. Required when ship_route is 2, 3 or 4.
order_mawb.mawb_nostringConditionalMAWB number. Maximum 60 characters.
order_mawb.departure_airportstringConditionalDeparture airport code. Exactly 3 characters.
order_mawb.arrival_airportstringConditionalArrival airport code. Exactly 3 characters.
order_mawb.outbound_flight_nostringConditionalFlight number on the MAWB. Maximum 60 characters.
order_mawb.estimated_departure_datetimestringConditionalEstimated departure time, as a 10-digit UNIX timestamp in seconds.
order_mawb.estimated_arrival_datetimestringConditionalEstimated arrival time, as a 10-digit UNIX timestamp in seconds. Must be later than order_mawb.estimated_departure_datetime.

Request Body Example

Direct CN route — no MAWB required, two containers:

json
{
  "ship_type": 1,
  "ship_route": 1,
  "is_ddp": "N",
  "departure_port": "SIN",
  "destination_port": "PHS",
  "outbound_flight_no": "SQ918",
  "estimated_departure_datetime": "1784115300",
  "estimated_arrival_datetime": "1784128800",
  "destination": "PH",
  "shipment_service": "TP",
  "ship_type_details": [
    [
      "TES00123456TP",
      "TES00123457TP"
    ],
    [
      "TES00123458TP"
    ]
  ]
}

Master2CN route — order_mawb is required:

json
{
  "ship_type": 3,
  "ship_route": 2,
  "is_ddp": "Y",
  "departure_port": "SIN",
  "destination_port": "TPE",
  "outbound_flight_no": "SQ876",
  "estimated_departure_datetime": "1784115300",
  "estimated_arrival_datetime": "1784128800",
  "destination": "TW",
  "order_mawb": {
    "mawb_no": "12123224",
    "departure_airport": "SIN",
    "arrival_airport": "TPE",
    "outbound_flight_no": "SQ876",
    "estimated_departure_datetime": "1784115300",
    "estimated_arrival_datetime": "1784128800"
  },
  "ship_type_details": [
    [
      "BX000000014CG",
      "BX000000028CG"
    ]
  ]
}

Authentication

This endpoint uses Bearer token authentication.

Obtain a token from Get Token and send it as Authorization: Bearer <Token>.

Response Information

The response is in JSON format.

Response Format

FieldTypeDescription
Codeinteger0 = success; non-zero = failure
MessagestringHuman-readable result
DataobjectPayload; empty array [] on failure

Success Response

  • Status Code: 200
json
{
    "Code": 0,
    "Message": "Success",
    "Data": {
        "JobNo": "CN38SG24010001"
    }
}
FieldTypeDescription
Data.JobNostringThe job number of the created order. Use it as job_no in Get Order File.

Error Response

  • Status Code: 200 (business logic error) or 4xx/5xx (system error)
json
{
    "Code": 1,
    "Message": "WMG Tracking Num(TES00123456TP) not exists!",
    "Data": []
}

Code Reference

CodeDescription
0Success
1Failure

Example

Bash

bash
BASE_URL="https://api.postal.test.wmgdelivery.com"
TOKEN="your_access_token"

curl -X POST "$BASE_URL/api/order/create-order" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "ship_type": 1,
    "ship_route": 1,
    "is_ddp": "N",
    "departure_port": "SIN",
    "destination_port": "PHS",
    "outbound_flight_no": "SQ918",
    "estimated_departure_datetime": "1784115300",
    "estimated_arrival_datetime": "1784128800",
    "destination": "PH",
    "shipment_service": "TP",
    "ship_type_details": [["TES00123456TP", "TES00123457TP"]]
  }'

Windows PowerShell

powershell
$BASE_URL = "https://api.postal.test.wmgdelivery.com"
$TOKEN    = "your_access_token"

# @(, @(...)) keeps the inner array nested — a single inner array would otherwise flatten
$body = @{
    ship_type                    = 1
    ship_route                   = 1
    is_ddp                       = "N"
    departure_port               = "SIN"
    destination_port             = "PHS"
    outbound_flight_no           = "SQ918"
    estimated_departure_datetime = "1784115300"
    estimated_arrival_datetime   = "1784128800"
    destination                  = "PH"
    shipment_service             = "TP"
    ship_type_details            = @(, @("TES00123456TP", "TES00123457TP"))
} | ConvertTo-Json -Depth 5

$response = Invoke-RestMethod -Uri "$BASE_URL/api/order/create-order" -Method Post `
    -ContentType "application/json" -Body $body -Headers @{Authorization = "Bearer $TOKEN"}
$response.Data.JobNo

Python

python
import requests

BASE_URL = "https://api.postal.test.wmgdelivery.com"
TOKEN    = "your_access_token"

resp = requests.post(f"{BASE_URL}/api/order/create-order", json={
    "ship_type": 1,
    "ship_route": 1,
    "is_ddp": "N",
    "departure_port": "SIN",
    "destination_port": "PHS",
    "outbound_flight_no": "SQ918",
    "estimated_departure_datetime": "1784115300",
    "estimated_arrival_datetime": "1784128800",
    "destination": "PH",
    "shipment_service": "TP",
    # Outer array = containers, inner array = the parcels in that container
    "ship_type_details": [["TES00123456TP", "TES00123457TP"]],
}, headers={"Authorization": f"Bearer {TOKEN}"}, timeout=60)
print(resp.json())

Node.js / TypeScript

typescript
const BASE_URL = "https://api.postal.test.wmgdelivery.com";
const TOKEN = "your_access_token";

const res = await fetch(`${BASE_URL}/api/order/create-order`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${TOKEN}`,
  },
  body: JSON.stringify({
    ship_type: 1,
    ship_route: 1,
    is_ddp: "N",
    departure_port: "SIN",
    destination_port: "PHS",
    outbound_flight_no: "SQ918",
    estimated_departure_datetime: "1784115300",
    estimated_arrival_datetime: "1784128800",
    destination: "PH",
    shipment_service: "TP",
    // Outer array = containers, inner array = the parcels in that container
    ship_type_details: [["TES00123456TP", "TES00123457TP"]],
  }),
});
console.log(await res.json());

PHP

php
<?php
$BASE_URL = 'https://api.postal.test.wmgdelivery.com';
$TOKEN    = 'your_access_token';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $BASE_URL . '/api/order/create-order');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $TOKEN,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'ship_type'                    => 1,
    'ship_route'                   => 1,
    'is_ddp'                       => 'N',
    'departure_port'               => 'SIN',
    'destination_port'             => 'PHS',
    'outbound_flight_no'           => 'SQ918',
    'estimated_departure_datetime' => '1784115300',
    'estimated_arrival_datetime'   => '1784128800',
    'destination'                  => 'PH',
    'shipment_service'             => 'TP',
    // Outer array = containers, inner array = the parcels in that container
    'ship_type_details'            => [['TES00123456TP', 'TES00123457TP']],
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$response = curl_exec($ch);
curl_close($ch);

echo json_encode(json_decode($response, true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
?>

Notes

  • The order is created and closed in a single call. There is no separate close step, and the order cannot be amended through the API afterwards — verify the payload before sending it.
  • Shipment documents are generated after closing, not instantly. Retrieve them with Get Order File, which waits briefly for generation to finish.
  • ship_type_details is an array of arrays: the outer array is the list of containers, each inner array holds the WMG tracking numbers packed into that container. No inner array may be empty.
  • A maximum of 999 parcels may be included across all containers in one order.
  • The same tracking number may not appear twice in ship_type_details, in any container.
  • Every parcel must satisfy all of the following, or the whole request is rejected:
    • it exists and belongs to your account;
    • it is not already part of another order — a re-used parcel is reported with the "scanned before in previous shipments" message and needs a fresh CN23 label;
    • its clearance mode matches the order's is_ddp;
    • its destination matches the order's destination — except on the Transshipment CN and Transshipment CN(AF) routes, where this check is skipped;
    • its carrier matches the order's carrier;
    • its size type matches the order's container size;
    • its dimensions and weight are within the limits for its service and destination.
  • order_mawb is only required on the Master2CN routes (ship_route 2, 3, 4). It is accepted but not required on the others.
  • Timestamps are 10-digit UNIX seconds; the examples send them as strings, which is what existing integrations use.
  • This call performs the full order build, document trigger and close, so it is slower than a lookup — allow a generous client timeout.
  • All parameters are case-sensitive.

Error Codes

codemessageDescription
1ship_type requireship_type is missing or empty.
1ship_type invalidship_type is not 1, 2 or 3.
1ship_route requireship_route is missing or empty.
1Ship Route Invalidship_route is not one of 17.
1is_ddp must be in Y,Nis_ddp is neither Y nor N.
1destination requiredestination is missing or empty.
1size of destination must be 2destination is not exactly 2 characters.
1departure_port requiredeparture_port is missing or empty.
1size of departure_port must be 3departure_port is not exactly 3 characters.
1destination_port requiredestination_port is missing or empty.
1size of destination_port must be 3destination_port is not exactly 3 characters.
1outbound_flight_no requireoutbound_flight_no is missing or empty.
1max size of outbound_flight_no must be 60outbound_flight_no is longer than 60 characters.
1estimated_departure_datetime requireestimated_departure_datetime is missing or empty.
1estimated_departure_datetime must be a timestampestimated_departure_datetime is not a valid UNIX timestamp.
1estimated_arrival_datetime requireestimated_arrival_datetime is missing or empty.
1estimated_arrival_datetime must be a timestampestimated_arrival_datetime is not a valid UNIX timestamp.
1estimated_arrival_datetime must be greater than 'estimated_departure_datetime'Arrival is not later than departure.
1shipment_service must be TP or EMThe destination offers a service choice and shipment_service is neither TP nor EM.
1ship_type_details requireship_type_details is missing or empty.
1ship_type_details must be a arrayship_type_details is not an array.
1ship_type_details must contain non-empty bagsOne of the containers in ship_type_details is empty or not an array.
1bags requireship_type_details resolved to no containers at all.
1bag item(1) must be arrayThe container at that position is not an array. The number is the 1-based container index.
1bag item parcel(1) must be stringThe entry at that position inside a container is not a string. The number is the 1-based entry index.
1WMG Tracking Num(TES00123456TP) Duplicate!The same tracking number appears more than once across all containers.
1The number of items cannot exceed 999More than 999 parcels in one order.
1WMG Tracking Num(TES00123456TP) not exists!No such parcel in your account.
1Order clearance mode(DDP) is inconsistent with the parcel((TES00123456TP)) clearance mode(DDU)The parcel's clearance mode differs from the order's is_ddp.
1Parcel(TES00123456TP) destination(TH) is inconsistent with order destination(PH)The parcel's destination differs from the order's destination.
1Parcel(TES00123456TP) partner is inconsistent with order partnerThe parcel's carrier differs from the order's carrier.
1(TES00123456TP) The package size does not match the size set in the orderThe parcel's size type differs from the order's container size.
1(TES00123456TP)This parcel has been scanned before in previous shipments. Please generate a new CN23 label for this parcel and redo bagging scan.The parcel already belongs to another order. Generate a new CN23 label and re-bag it.
1Parcel(TES00123456TP):The parcel exceeds the dimension, length or weight limit for its service and destination. The text after the colon states which limit.
1Error encountered, please contact tech@wmg-group.com with screenshot of error page for resolution.Unexpected server error.
1003Token errorThe token is missing, expired, or superseded by a newer login. Call Get Token again.

Order build and carrier-matching failures surface their own message text with Code: 1. Treat any unrecognised Message as a rejection of the whole order — nothing is created when the call fails.