Endpoint
URL:
https://api.zonos.com/graphql
Headers:
credentialToken: {{YOUR_API_TOKEN}}
accountKey: {{SHIPPER_API_TOKEN}}
Example request
A complete CreateDeclarationShipment request you can copy and adapt — the mutation, its variables, and the response — for a single Japan Post parcel shipped DDP to the U.S. Each input is broken down in the step-by-step section below.
mutation CreateDeclarationShipment($partyInput: [PartyCreateWorkflowInput!]!$itemInput: [ItemCreateWorkflowInput!]!$cartonInput: [CartonCreateWorkflowInput!]!$shipmentRatingInput: ShipmentRatingCreateWorkflowInput!$landedCostInput: LandedCostWorkFlowInput!$declarationInput: DeclarationCreateWorkflowInput!$shipmentInput: ShipmentCreateWorkflowInput!) { partyCreateWorkflow(input: $partyInput) { id type location { line1 locality postalCode countryCode } } itemCreateWorkflow(input: $itemInput) { id name sku amount currencyCode hsCode } cartonsCreateWorkflow(input: $cartonInput) { id length width height dimensionalUnit weight weightUnit } shipmentRatingCreateWorkflow(input: $shipmentRatingInput) { id amount } landedCostCalculateWorkflow(input: $landedCostInput) { id method currencyCode amountSubtotals { duties taxes fees shipping landedCostTotal } } declarationCreateWorkflow(input: $declarationInput) { declaration { id source status } errors { code message } } shipmentCreateWorkflow(input: $shipmentInput) { id trackingDetails { number } shipmentCartons { label { url } } }}Step-by-step
The Status column on each table below uses these terms:
- Required — the request fails without it.
- Required for label — optional in the GraphQL schema, but needed to produce a valid Japan Post U.S. label.
- Conditional — required depending on another field (noted inline).
- Recommended — optional, but drives accurate duties and taxes.
- Optional — not needed.
1. partyCreateWorkflow
Creates the parties involved in the shipment — at minimum an ORIGIN (where the shipment ships from) and a DESTINATION (the buyer / consignee).
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
type | Required | ORIGIN, DESTINATION, RETURN, etc. |
location.countryCode | Required | ISO-2 country code. |
location.line1, locality, administrativeAreaCode, postalCode | Required for label | Address fields needed for a valid label. |
person.firstName, lastName, phone | Required for label | Contact details needed for a valid label. |
person.companyName, email | Optional |
Example payload:
[
{ "type": "DESTINATION", "location": { "countryCode": "US" }, "person": {} },
{ "type": "ORIGIN", "location": { "countryCode": "JP" }, "person": {} }
]
The response returns the created Party IDs and resolved address fields.
2. itemCreateWorkflow
Creates the line items that make up the shipment. These are the SKUs that will appear on the commercial invoice and drive the landed-cost calculation.
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
currencyCode | Required | Currency of the unit price. |
quantity | Required | Number of units of this item. |
amount | Conditional | Unit price (not total). Required unless totalAmount is provided. |
totalAmount | Optional | Alternative to amount; amount is derived from totalAmount / quantity. |
hsCode | Recommended | Harmonized System tariff code. Drives duty rates. |
countryOfOrigin | Recommended | ISO-2 code where the item was made. Drives duty / FTA. |
name, description | Recommended | Customer-facing product name + description. |
customsDescription | Optional | Customs description override. |
sku, productId | Optional | Your internal identifiers. |
measurements | Optional | Per-unit weight / dimensions. |
The HS code, country of origin, and amount are the three fields that most influence the duty/tax outcome in step 5.
3. cartonsCreateWorkflow
Creates the physical packages — the boxes, polybags, or letters that will hold the items.
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
dimensionalUnit | Required | INCH or CENTIMETER. |
weight, weightUnit | Required for label | Japan Post requires package weight. |
length, width, height | Optional | Outer dimensions. |
type | Optional | Packaging style (box, polybag, letter). Defaults to PACKAGE. |
Each carton becomes one parcel on the carrier label in step 7. Multiple cartons → multi-piece shipment with one tracking number per carton.
4. shipmentRatingCreateWorkflow
Records the rate quote the merchant is charging the buyer for shipping.
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
amount | Required | What the buyer is paying for shipping. Pass 0 if free. |
currencyCode | Required | Currency of amount. |
serviceLevelCode | Required | Carrier service code (e.g. japan_post.air.parcel). |
displayName | Optional | Pretty name for the receipt / invoice. |
This is the rate the buyer was quoted at checkout. It feeds into the landed-cost calculation as the "shipping" subtotal so duties and taxes are computed against the correct CIF value.
5. landedCostCalculateWorkflow
Runs the duties, taxes, and fees calculation for the destination country. Uses the items, parties, and shipping cost from the prior steps.
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
endUse | Required | NOT_FOR_RESALE or FOR_RESALE. Some destinations apply different rates for commercial vs personal end use. |
tariffRate | Required | Defaults to ZONOS_PREFERRED if omitted. Tells Zonos which tariff source/methodology to apply. |
calculationMethod | Recommended | DDP (buyer prepays) or DDU (buyer pays at the door). Use DDP for prepaid. Drives whether LandedCost.amountSubtotals includes duty/tax. |
currencyCode | Optional | Currency the landed-cost subtotals are returned in. |
arrivalDate | Optional | FX rates and tariff schedules are pinned to this date if provided. |
The response includes amountSubtotals (duties, taxes, fees, shipping, landedCostTotal) — these are the numbers you display to the buyer at checkout and that get printed on the commercial invoice.
6. declarationCreateWorkflow
Creates a Declaration — an identifier required to clear the package into the destination country under current customs regulations.
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
source | Required | POST, PREPAY, ZONOS, or DIRECT. In this flow, use DIRECT. |
landedCostIds | Optional | Usually omitted here because the previous step already produced a landed cost. |
The response returns a Declaration with an id, source, and status, or a list of errors. The id is what's needed for the shipment to be accepted; nothing else from this step is consumed by the caller in this flow.
7. shipmentCreateWorkflow
The terminal step — creates the Shipment entity, generates the carrier label, and (optionally) the commercial invoice / packing slip.
For Japan Post Verified Accounts, this is also where Zonos calls the Japan Post Label API (code 52) on your behalf, injects your Later Pay Numbers, creates the Declaration ID, and links the Declaration ID to the tracking number returned by Japan Post.
Key fields:
| Field↕ | Status↕ | Notes↕ |
|---|---|---|
serviceLevel | Required for label | The Japan Post service to ship with (e.g. japan_post.air.ems_merchandise). Must be a japan_post.* service level. |
generateLabel | Optional | Defaults to true; must be true to return a label. |
contentsType | Recommended | SALE_OF_GOODS, GIFT, DOCUMENTS, SAMPLE, etc. Drives customs treatment. |
nonDelivery | Optional | What the carrier should do if delivery fails: RETURN, ABANDON, FORWARD. |
references | Optional | Merchant-supplied reference numbers printed on the label and commercial invoice. See below. |
declaredValue / isDeclaredValue | Optional | Insurance value for the shipment. |
shipmentConsolidationId | Optional | Used when this shipment is part of a batch dispatch. |
references sub-input
These fields print on the carrier label and/or commercial invoice. Use them to surface PO numbers, license numbers, and free-text remarks the consignee or customs authority needs to see.
| Field↕ | Status↕ | Notes↕ | Length↕ |
|---|---|---|---|
invoiceNumber | Optional | Merchant invoice number. | — |
purchaseOrderNumber | Optional | Merchant PO number. | — |
licenseNumber | Optional | Export/import license number. | — |
certificateNumber | Optional | Customs certificate number. | — |
paymentConditions | Optional | Free-text terms-of-payment shown on the commercial invoice. | Limit to 200 characters — longer values overflow on the printed invoice. |
customsRemarks | Optional | Free-text customs remarks. | — |
taxCode | Optional | Custom tax code printed on the label. | — |
Response
The interesting fields on the returned Shipment are:
{
id
trackingDetails {
number
}
shipmentCartons {
label {
url
labelImage
}
}
}
trackingDetails.number is the Japan Post tracking number.
The label object can return the label two ways — request whichever fits your workflow (or both):
| Field↕ | Returns↕ | Use when↕ |
|---|---|---|
url | A hosted link to the rendered label file (PDF), ready to download or print. | You want to hand off a link — open it, email it, or fetch the file later without holding it in the payload. |
labelImage | The base64-encoded label image (PNG/PDF/ZPL) inline in the response. | You want the label bytes directly in the response to attach to a fulfillment workflow or save to your WMS. |
Select only the fields you need. Requesting url keeps the response small; requesting labelImage returns the full label inline so you don't need a second round trip to fetch it. The example above requests url.
Error handling
- Validation errors (missing required fields, invalid country codes, etc.) come back in the standard GraphQL
errorsarray and abort the rest of the chain. - Declaration errors (e.g. unsupported
source) surface insidedeclarationCreateWorkflow.errorsrather than the top-levelerrorsarray, so always check both. - Japan Post errors (label generation failure, invalid address, etc.) surface as GraphQL errors on
shipmentCreateWorkflow. If a retry is needed, contact support — the recommended path is to resubmit the full mutation with corrected input.
Permissions
Each step is independently secured. Your API key must hold the write scope for each entity in the chain (ITEM_WRITE, CARTON_WRITE, SHIPMENT_RATING_WRITE, LANDED_COST_WRITE, DECLARATION_WRITE, SHIPMENT_WRITE). The standard merchant role on a Verified Account grants all of these.
Next steps
- Batch dispatch (consolidation) — bundle the day's parcels into one Japan Post deferred-payment dispatch slip.
Create a single shipment
The
CreateDeclarationShipmentGraphQL workflow takes a Japan Post shipment from raw inputs to a printable label in one round trip.CreateDeclarationShipmentchains together seven*Workflowmutations into a single GraphQL request. Each step builds on the data the previous steps provided, and all of them are submitted together so a complete shipment can be created in one round trip:The
Workflowmutations are designed to be chained: you don't need to thread IDs from one step into the next, and you don't need to send a separate request per step. Submit the whole document, get the finalShipmentback.When the
serviceLevelon the final step is a Japan Post service level (japan_post.*), Zonos calls the Japan Post Label API (code 52) on your behalf using your Verified Account's Later Pay Numbers, generates the label and tracking number, creates the Declaration ID, and links them — all inside that finalshipmentCreateWorkflowstep.