Create Single Parcel
API Overview
Registers one parcel and returns the WMG tracking number assigned to it. This is the entry point of the integration: create the parcel here, then fetch its label with Get Shipping Label PDF and, when the shipment is ready, include it in an order via Create & Close Order.
The parcel is created synchronously, so the returned tracking number can be used immediately.
Request Information
- Method: POST
- Path:
/api/parcel/create-order - Authentication: Bearer Token
Request Headers
| Field | Description |
|---|---|
| Content-Type | application/json |
| Authorization | Bearer <token> |
Request Parameters
The request body is in JSON format and includes the following fields. All fields sit at the top level except the items, which go in the ItemListing array.
Shipment
| Parameter | Type | Required | Description |
|---|---|---|---|
| OwnerId | number | No | Your company identifier, echoed back unchanged in the response. |
| ServiceCode | string | No | The service to ship under, as advised by your account manager. Omit it and your account's first configured service code is used. Must be one of the service codes enabled on your account. |
| TrackingNumber | string | Yes | Your own tracking number for this parcel, as printed on the item. Maximum 50 characters. Must be unique within your account. |
| Origin | string | Yes | Origin country as a 2-letter code, e.g. SG. Exactly 2 characters. |
| Destination | string | Yes | Destination country as a 2-letter code, e.g. TH. Exactly 2 characters. Must be a destination enabled for your account. |
| Dep_Iata | string | Yes | Departure airport IATA code. Exactly 3 characters. |
| Arr_Iata | string | Yes | Arrival airport IATA code. Exactly 3 characters. |
| Commodity | string | Yes | Brief description of the parcel contents. |
| DeclaredCurrency | string | Yes | Currency of the declared value, e.g. SGD. Exactly 3 characters. Must be a currency accepted for the destination. |
| DeclaredValue | number | Yes | Declared value of the parcel. Must be 0 or greater. |
| Qty | number | Yes | Number of pieces under this tracking number. Must be greater than 0. |
| Weight | number | Yes | Declared weight. Must be 0 or greater. Stored with up to 3 decimal places. |
| Length | number | No | Length of the parcel. Must be 0 or greater. Stored with up to 2 decimal places. |
| Width | number | No | Width of the parcel. Must be 0 or greater. Stored with up to 2 decimal places. |
| Height | number | No | Height of the parcel. Must be 0 or greater. Stored with up to 2 decimal places. |
| IsDDP | string | No | Clearance mode: Y = DDP, N = DDU. Defaults to N. |
| MAWBNumber | string | No | Air waybill number. Maximum 30 characters. |
| SendingAgentID | string | No | Customer or manufacturer reference. Maximum 50 characters. |
| OrderNumber | string | No | Your internal order reference. Maximum 50 characters. |
| Remark | string | No | Delivery instruction. Maximum 50 characters. |
| ETD | string | No | Estimated departure at origin, formatted YYYY-MM-DD HH:MM:SS. |
| ETA | string | No | Estimated arrival at destination, formatted YYYY-MM-DD HH:MM:SS. Must be later than ETD. |
| PickUpDate | string | No | Pickup time at the sender's location, formatted YYYY-MM-DD HH:MM:SS. |
| DeliveryDate | string | No | Intended delivery time, formatted YYYY-MM-DD HH:MM:SS. |
Cash on delivery
| Parameter | Type | Required | Description |
|---|---|---|---|
| IsCOD | string | No | Y = collect on delivery, N = not COD. |
| CODType | integer | No | Expected payment type: 0 = unspecified (default), 1 = Cash, 2 = Cheque. |
| CODCurrency | string | No | Currency to collect. Exactly 3 characters. |
| CODAmount | number | No | Amount to collect. Must be 0 or greater. |
Singapore GST — required when Destination is SG, optional otherwise
| Parameter | Type | Required | Description |
|---|---|---|---|
| SupplierName | string | Conditional | Supplier name. Maximum 100 characters. |
| GSTRegNo | string | Conditional | Supplier GST registration number. Maximum 50 characters. |
| GSTAmount | number | Conditional | GST amount paid. Must be 0 or greater. |
| GSTCurrency | string | Conditional | Currency of the GST amount. Exactly 3 characters. |
| GSTStatus | string | Conditional | GST status. Maximum 5 characters. |
Sender
| Parameter | Type | Required | Description |
|---|---|---|---|
| SenderName | string | Yes | Sender name. Maximum 60 characters. |
| SenderCompany | string | No | Sender company. Maximum 80 characters. |
| SenderAddress1 | string | Yes | Sender address line 1. Maximum 160 characters. |
| SenderAddress2 | string | No | Sender address line 2. Maximum 100 characters. |
| SenderCity | string | No | Sender city. Maximum 50 characters. |
| SenderState | string | No | Sender state. Maximum 50 characters. |
| SenderCountry | string | Yes | Sender country name. Maximum 60 characters. |
| SenderPostalCode | string | Yes | Sender postal code. Maximum 20 characters. Send an empty string for countries without postal codes. |
| SenderContactNo | string | No | Sender contact number. Maximum 20 characters. |
| SenderEmail | string | No | Sender email. Maximum 100 characters. |
Recipient
| Parameter | Type | Required | Description |
|---|---|---|---|
| RecipientName | string | Yes | Consignee name. Maximum 60 characters. |
| RecipientCompany | string | No | Consignee company. Maximum 80 characters. |
| RecipientAddress1 | string | Yes | Consignee address line 1. Maximum 160 characters. |
| RecipientAddress2 | string | No | Consignee address line 2. Maximum 160 characters. |
| RecipientAddress3 | string | No | Consignee address line 3. Maximum 100 characters. |
| RecipientCity | string | Yes | Consignee city. Maximum 50 characters. |
| RecipientState | string | Yes | Consignee state. Maximum 50 characters. |
| RecipientCountry | string | Yes | Consignee country name. Maximum 60 characters. |
| RecipientPostalCode | string | Yes | Consignee postal code. Maximum 20 characters. Validated against the destination's postal-code format where one applies. |
| RecipientContactNo | string | Yes | Consignee contact number. Maximum 20 characters. |
| RecipientEmail | string | No | Consignee email. Maximum 100 characters. |
ItemListing — array, at least one item required
| Parameter | Type | Required | Description |
|---|---|---|---|
| ItemListing[].SKU | string | No | Your SKU for the item. Maximum 60 characters. |
| ItemListing[].ItemDescription | string | Yes | Description of the item. Maximum 300 characters. |
| ItemListing[].ItemWeight | number | Yes | Weight of the item. Must be 0 or greater. |
| ItemListing[].NoOfPcs | number | Yes | Number of pieces of this item. Must be 0 or greater. |
| ItemListing[].ItemValue | number | Yes | Value of the item. Must be 0 or greater. |
| ItemListing[].ItemCurrency | string | Yes | Currency of the item value. Maximum 3 characters. Must be accepted for the destination. |
| ItemListing[].ItemOrigin | string | Yes | Item origin country as a 2-letter code. Maximum 2 characters. |
| ItemListing[].ItemDestination | string | Yes | Item destination country as a 2-letter code. Maximum 2 characters. |
| ItemListing[].HSCode | string | Yes | HS code of the item. Maximum 50 characters. |
Request Body Example
{
"OwnerId": 111,
"ServiceCode": "A0000",
"TrackingNumber": "CUST0001234567",
"Origin": "SG",
"Destination": "TH",
"Dep_Iata": "SIN",
"Arr_Iata": "BKK",
"Commodity": "Cotton T-shirts",
"DeclaredCurrency": "SGD",
"DeclaredValue": 45.50,
"Qty": 1,
"Weight": 1.250,
"Length": 30.00,
"Width": 20.00,
"Height": 10.00,
"IsDDP": "N",
"OrderNumber": "SO-2026-000123",
"ETD": "2026-07-30 14:25:00",
"ETA": "2026-07-31 09:15:00",
"SenderName": "Jane Tan",
"SenderCompany": "Example Trading Pte Ltd",
"SenderAddress1": "10 Anson Road #12-01",
"SenderCity": "Singapore",
"SenderCountry": "Singapore",
"SenderPostalCode": "079903",
"SenderContactNo": "+6561234567",
"SenderEmail": "jane.tan@example.com",
"RecipientName": "Somchai Preecha",
"RecipientAddress1": "99 Sukhumvit Road",
"RecipientAddress2": "Khlong Toei",
"RecipientCity": "Bangkok",
"RecipientState": "Bangkok",
"RecipientCountry": "Thailand",
"RecipientPostalCode": "10110",
"RecipientContactNo": "+66812345678",
"RecipientEmail": "somchai@example.com",
"ItemListing": [
{
"SKU": "TS-BLK-M",
"ItemDescription": "Cotton T-shirt, black, size M",
"ItemWeight": 0.250,
"NoOfPcs": 2,
"ItemValue": 15.00,
"ItemCurrency": "SGD",
"ItemOrigin": "SG",
"ItemDestination": "TH",
"HSCode": "610910"
},
{
"SKU": "TS-WHT-L",
"ItemDescription": "Cotton T-shirt, white, size L",
"ItemWeight": 0.750,
"NoOfPcs": 1,
"ItemValue": 15.50,
"ItemCurrency": "SGD",
"ItemOrigin": "SG",
"ItemDestination": "TH",
"HSCode": "610910"
}
]
}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
| Field | Type | Description |
|---|---|---|
| Code | integer | 0 = success; non-zero = failure |
| Message | string | Human-readable result |
| Data | object | Payload; empty array [] on failure |
Success Response
- Status Code: 200
{
"Code": 0,
"Message": "Success",
"Data": {
"OwnerId": 111,
"TrackingNo": "CUST0001234567",
"WmgTrackingNo": "CY180000999SG",
"DeliveryId": "",
"DateTime": "2026-07-30 15:43:48",
"Status": "",
"Error": []
}
}| Field | Type | Description |
|---|---|---|
| Data.OwnerId | number | The OwnerId you sent, echoed back. Empty string if you did not send one. |
| Data.TrackingNo | string | Your tracking number, exactly as you sent it. |
| Data.WmgTrackingNo | string | The WMG tracking number assigned to the parcel. Use it for labels, tracking and orders. |
| Data.DeliveryId | string | Reserved. Always returned as an empty string. |
| Data.DateTime | string | Server time when the parcel was created, formatted YYYY-MM-DD HH:MM:SS. |
| Data.Status | string | Reserved. Always returned as an empty string. |
| Data.Error | array | Reserved. Always returned as an empty array — failures come back with Code: 1 instead. |
Error Response
- Status Code: 200 (business logic error) or 4xx/5xx (system error)
{
"Code": 1,
"Message": "Tracking Number already exist",
"Data": []
}Code Reference
| Code | Description |
|---|---|
| 0 | Success |
| 1 | Failure |
Example
Bash
BASE_URL="https://api.postal.test.wmgdelivery.com"
TOKEN="your_access_token"
curl -X POST "$BASE_URL/api/parcel/create-order" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d @parcel.jsonWindows PowerShell
$BASE_URL = "https://api.postal.test.wmgdelivery.com"
$TOKEN = "your_access_token"
$body = @{
ServiceCode = "A0000"
TrackingNumber = "CUST0001234567"
Origin = "SG"
Destination = "TH"
Dep_Iata = "SIN"
Arr_Iata = "BKK"
Commodity = "Cotton T-shirts"
DeclaredCurrency = "SGD"
DeclaredValue = 45.50
Qty = 1
Weight = 1.250
SenderName = "Jane Tan"
SenderAddress1 = "10 Anson Road #12-01"
SenderCountry = "Singapore"
SenderPostalCode = "079903"
RecipientName = "Somchai Preecha"
RecipientAddress1 = "99 Sukhumvit Road"
RecipientCity = "Bangkok"
RecipientState = "Bangkok"
RecipientCountry = "Thailand"
RecipientPostalCode = "10110"
RecipientContactNo = "+66812345678"
ItemListing = @(
@{
ItemDescription = "Cotton T-shirt, black, size M"
ItemWeight = 0.250
NoOfPcs = 2
ItemValue = 15.00
ItemCurrency = "SGD"
ItemOrigin = "SG"
ItemDestination = "TH"
HSCode = "610910"
}
)
} | ConvertTo-Json -Depth 5
$response = Invoke-RestMethod -Uri "$BASE_URL/api/parcel/create-order" -Method Post `
-ContentType "application/json" -Body $body -Headers @{Authorization = "Bearer $TOKEN"}
$response.Data.WmgTrackingNoPython
import requests
BASE_URL = "https://api.postal.test.wmgdelivery.com"
TOKEN = "your_access_token"
parcel = {
"ServiceCode": "A0000",
"TrackingNumber": "CUST0001234567",
"Origin": "SG",
"Destination": "TH",
"Dep_Iata": "SIN",
"Arr_Iata": "BKK",
"Commodity": "Cotton T-shirts",
"DeclaredCurrency": "SGD",
"DeclaredValue": 45.50,
"Qty": 1,
"Weight": 1.250,
"SenderName": "Jane Tan",
"SenderAddress1": "10 Anson Road #12-01",
"SenderCountry": "Singapore",
"SenderPostalCode": "079903",
"RecipientName": "Somchai Preecha",
"RecipientAddress1": "99 Sukhumvit Road",
"RecipientCity": "Bangkok",
"RecipientState": "Bangkok",
"RecipientCountry": "Thailand",
"RecipientPostalCode": "10110",
"RecipientContactNo": "+66812345678",
"ItemListing": [
{
"ItemDescription": "Cotton T-shirt, black, size M",
"ItemWeight": 0.250,
"NoOfPcs": 2,
"ItemValue": 15.00,
"ItemCurrency": "SGD",
"ItemOrigin": "SG",
"ItemDestination": "TH",
"HSCode": "610910",
},
],
}
resp = requests.post(f"{BASE_URL}/api/parcel/create-order", json=parcel,
headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
payload = resp.json()
print(payload["Data"]["WmgTrackingNo"])Node.js / TypeScript
const BASE_URL = "https://api.postal.test.wmgdelivery.com";
const TOKEN = "your_access_token";
const parcel = {
ServiceCode: "A0000",
TrackingNumber: "CUST0001234567",
Origin: "SG",
Destination: "TH",
Dep_Iata: "SIN",
Arr_Iata: "BKK",
Commodity: "Cotton T-shirts",
DeclaredCurrency: "SGD",
DeclaredValue: 45.50,
Qty: 1,
Weight: 1.250,
SenderName: "Jane Tan",
SenderAddress1: "10 Anson Road #12-01",
SenderCountry: "Singapore",
SenderPostalCode: "079903",
RecipientName: "Somchai Preecha",
RecipientAddress1: "99 Sukhumvit Road",
RecipientCity: "Bangkok",
RecipientState: "Bangkok",
RecipientCountry: "Thailand",
RecipientPostalCode: "10110",
RecipientContactNo: "+66812345678",
ItemListing: [
{
ItemDescription: "Cotton T-shirt, black, size M",
ItemWeight: 0.250,
NoOfPcs: 2,
ItemValue: 15.00,
ItemCurrency: "SGD",
ItemOrigin: "SG",
ItemDestination: "TH",
HSCode: "610910",
},
],
};
const res = await fetch(`${BASE_URL}/api/parcel/create-order`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${TOKEN}`,
},
body: JSON.stringify(parcel),
});
const payload = await res.json();
console.log(payload.Data.WmgTrackingNo);PHP
<?php
$BASE_URL = 'https://api.postal.test.wmgdelivery.com';
$TOKEN = 'your_access_token';
$parcel = [
'ServiceCode' => 'A0000',
'TrackingNumber' => 'CUST0001234567',
'Origin' => 'SG',
'Destination' => 'TH',
'Dep_Iata' => 'SIN',
'Arr_Iata' => 'BKK',
'Commodity' => 'Cotton T-shirts',
'DeclaredCurrency' => 'SGD',
'DeclaredValue' => 45.50,
'Qty' => 1,
'Weight' => 1.250,
'SenderName' => 'Jane Tan',
'SenderAddress1' => '10 Anson Road #12-01',
'SenderCountry' => 'Singapore',
'SenderPostalCode' => '079903',
'RecipientName' => 'Somchai Preecha',
'RecipientAddress1' => '99 Sukhumvit Road',
'RecipientCity' => 'Bangkok',
'RecipientState' => 'Bangkok',
'RecipientCountry' => 'Thailand',
'RecipientPostalCode' => '10110',
'RecipientContactNo' => '+66812345678',
'ItemListing' => [
[
'ItemDescription' => 'Cotton T-shirt, black, size M',
'ItemWeight' => 0.250,
'NoOfPcs' => 2,
'ItemValue' => 15.00,
'ItemCurrency' => 'SGD',
'ItemOrigin' => 'SG',
'ItemDestination' => 'TH',
'HSCode' => '610910',
],
],
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $BASE_URL . '/api/parcel/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($parcel));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);
$payload = json_decode($response, true);
echo $payload['Data']['WmgTrackingNo'] . "\n";
?>Notes
TrackingNumbermust be unique within your account. Re-sending one that already exists returnsTracking Number already exist— the call is not idempotent and will not return the earlier parcel.TrackingNumberandDestinationare normalised to upper case before processing, soData.WmgTrackingNois matched against the upper-case form later.Data.TrackingNoechoes your value with its original casing.- Omitting
ServiceCodeis allowed: your account's first configured service code is used. If your account has no service code at all, the call fails withUser Service Codes is Empty. RecipientAddress1,RecipientAddress2andRecipientAddress3are concatenated for the label. Their combined length must not exceed 320 characters, independently of each field's own limit.DeclaredCurrencyand everyItemCurrencymust be a currency accepted for the destination, otherwise the parcel is rejected. Item currency errors name the 1-based item position.- For destination
MY,Commodityand eachItemDescriptionare screened for medical and pharmaceutical wording and rejected withProhibited Item, Do Not Import!. - Date fields (
ETD,ETA,PickUpDate,DeliveryDate) use the formatYYYY-MM-DD HH:MM:SS. ISO 8601 strings with aTseparator or a timezone offset are rejected. ETAmust be later thanETDwhen both are supplied.- The Singapore GST fields become mandatory only when
DestinationisSG. Data.DeliveryId,Data.StatusandData.Errorare reserved and always come back empty. CheckCode, notError, to decide whether the call succeeded.- Validation stops at the first failure, so fixing one field can reveal the next. Expect to iterate when onboarding.
- All parameters are case-sensitive.
Error Codes
| code | message | Description |
|---|---|---|
1 | Tracking Number cannot be empty | TrackingNumber was missing or blank. |
1 | Tracking Number already exist | A parcel with that TrackingNumber already exists in your account. |
1 | User Service Codes is Empty | ServiceCode was omitted and your account has no service code configured. |
1 | ServiceCode invalid | ServiceCode is not one of the service codes enabled on your account. |
1 | The account you are using does not support destination "XX" for the time being, please contact your business manager to confirm. | No parcel-size configuration exists for that destination. |
1 | Destination not allow | The destination is configured but not permitted for your account and service. |
1 | DeclaredCurrency not allow | DeclaredCurrency is not accepted for the destination. |
1 | Item 1 ItemCurrency(SGD) not allow | That item's ItemCurrency is not accepted for the destination. The number is the 1-based item position. |
1 | ItemListing required | ItemListing is missing or empty. |
1 | Prohibited Item, Do Not Import! | Commodity or an ItemDescription contains medical or pharmaceutical wording for a MY destination. |
1 | The total length of addresses 1, 2, and 3 exceeds the maximum limit of 320 characters | The concatenated recipient address is longer than 320 characters. |
1 | TrackingNumber require | TrackingNumber is missing or empty. |
1 | max size of TrackingNumber must be 50 | TrackingNumber is longer than 50 characters. |
1 | Destination require | Destination is missing or empty. |
1 | size of Destination must be 2 | Destination is not exactly 2 characters. |
1 | Origin require | Origin is missing or empty. |
1 | size of Origin must be 2 | Origin is not exactly 2 characters. |
1 | Commodity require | Commodity is missing or empty. |
1 | DeclaredCurrency require | DeclaredCurrency is missing or empty. |
1 | size of DeclaredCurrency must be 3 | DeclaredCurrency is not exactly 3 characters. |
1 | DeclaredValue require | DeclaredValue is missing or empty. |
1 | Qty require | Qty is missing or empty. |
1 | Weight require | Weight is missing or empty. |
1 | IsDDP must be in Y,N | IsDDP is neither Y nor N. |
1 | IsCOD must be in Y,N | IsCOD is neither Y nor N. |
1 | CODType must be in 0,1,2 | CODType is not 0, 1 or 2. |
1 | Dep_Iata require | Dep_Iata is missing or empty. |
1 | size of Dep_Iata must be 3 | Dep_Iata is not exactly 3 characters. |
1 | Arr_Iata require | Arr_Iata is missing or empty. |
1 | size of Arr_Iata must be 3 | Arr_Iata is not exactly 3 characters. |
1 | ETA range is incorrect | ETA is not later than ETD. |
1 | SupplierName require | Destination is SG and SupplierName is missing. The same applies to GSTRegNo, GSTAmount, GSTCurrency and GSTStatus. |
1 | SenderName require | SenderName is missing or empty. The same pattern applies to every other required sender, recipient and item field. |
1 | max size of SenderName must be 60 | The field is longer than its documented maximum. The same pattern applies to every length-limited field. |
1 | Error encountered, please contact tech@wmg-group.com with screenshot of error page for resolution. | Unexpected server error. |
1003 | Token error | The token is missing, expired, or superseded by a newer login. Call Get Token again. |
Field-level validation messages follow the pattern <FieldName> require for missing values and max size of <FieldName> must be <n> / size of <FieldName> must be <n> for length problems, using the exact field name from the tables above.