DOCS

Batch dispatch (consolidation)

Batch dispatch (consolidation)

Bundle a day's Japan Post parcels into one deferred-payment dispatch slip with the consolidation flow.

This document walks through the three-stage flow for creating a Japan Post deferred-payment dispatch batch via the Zonos GraphQL API: open a consolidation, attach n shipments to it (each through the standard chained shipment-creation workflow), then close it to receive Japan Post's manifest document.

When to use this flow 

Japan Post's deferred-payment program (後納) lets a merchant settle their daily shipping bill in one transaction at end-of-day, rather than per-parcel at drop-off. The merchant brings all the day's parcels to the post office along with one dispatch slip (差出票) covering up to 250 shipments. Postage is invoiced to the merchant's pre-registered Later Pay Number.

If you're shipping individual Japan Post labels and paying parcel-by-parcel at the counter, you don't need this flow — call the single-shipment chain directly without a consolidation.

Overview 

1. shipmentConsolidationCreate            → open the batch (returns consolidation ID)
2. CreateDeclarationShipment × n          → create each shipment + label, attached to the batch
3. shipmentConsolidationUpdate(CLOSED)    → close the batch (returns the manifest document)

The consolidation ID returned from step 1 is threaded into every shipmentCreateWorkflow call in step 2 via the shipmentConsolidationId field. Each label is created with your Later Pay Number embedded so that Japan Post will accept it onto the dispatch slip when step 3 closes the batch.

Why three calls instead of one mutation? Steps 2.1, 2.2, ..., 2.n happen across the merchant's day — labels are printed and parcels are sealed as orders come in. The batch can't be a single round-trip the way the single-shipment chain is: there's a multi-hour gap between opening the consolidation and closing it.

Prerequisites 

Before this flow works for a given Verified Account:

  • Your account must have a Japan Post deferred-payment Later Pay Number (後納お客様番号) saved on it — a hyphen-formatted value like 1111111111-222222-3333333333-444444. Pass it on shipmentConsolidationCreate via accountNumber (Step 1).
  • Your API key must hold SHIPMENT_WRITE, plus the standard scopes the per-shipment workflow needs.

Endpoint 

All three steps below are GraphQL operations sent to the same endpoint with the same headers.

URL:

https://api.zonos.com/graphql

Headers:

credentialToken: {{YOUR_API_TOKEN}}
accountKey:      {{SHIPPER_API_TOKEN}}

Step 1: shipmentConsolidationCreate 

Opens an empty consolidation. The carrier code locks the batch to Japan Post; subsequent shipments must use Japan Post service levels.

Mutation:

mutation {
  shipmentConsolidationCreate(
    input: {
      carrierCode: JAPAN_POST
      accountNumber: "1111111111-222222-3333333333-444444"
      name: "Tokyo dispatch — 2026-05-01"
      externalId: "merchant-batch-20260501-001"
    }
  ) {
    id
    status
    accountNumber
    carrierCode
  }
}
FieldNotes
carrierCodeRequired. Use JAPAN_POST.
accountNumberRequired for Japan Post. Hyphen-formatted Later Pay Number. Format is validated at create time — bad values are rejected immediately rather than at close.
nameOptional. Human-readable label for your records. Defaults to the consolidation's generated ID.
externalIdOptional. Your internal batch identifier; defaults to the consolidation's generated ID if omitted.
shipmentIdOptional. ID of an initial shipment to attach. Most callers leave this null and attach shipments individually in step 2.

Response:

{
  "data": {
    "shipmentConsolidationCreate": {
      "id": "sc_01hjk...",
      "status": "OPEN",
      "accountNumber": "1111111111-222222-3333333333-444444",
      "carrierCode": "JAPAN_POST"
    }
  }
}

The id (e.g. sc_01HJK...) is what you thread into every shipment-create call in step 2. The status is OPEN until step 3.

Step 2: CreateDeclarationShipment × n — attach shipments 

For each parcel you need to ship today, run the full chained single-shipment workflow. The only addition for the consolidation flow is passing the consolidation ID on the final shipmentCreateWorkflow step. All preceding mutations in the chain are identical to the single-shipment workflow.

The relevant fields on shipmentCreateWorkflow:

shipmentCreateWorkflow(
  input: {
    serviceLevel: "japan_post.air.ems_merchandise"
    shipmentConsolidationId: "sc_01hjk..."
    generateLabel: true
  }
) {
  id
  trackingDetails {
    number
  }
  shipmentCartons {
    label {
      labelImage
    }
  }
}

Pass shipmentConsolidationId (the id from Step 1) on the final step to attach this shipment to the batch.

FieldNotes
shipmentConsolidationIdThe ID from Step 1. Tells the platform "attach this shipment to that batch." This is the only field that distinguishes a consolidation-bound shipment from a standalone one.
serviceLevelMust be a Japan Post service level (japan_post.*). Mixing carriers within a single consolidation is not supported.

What you get back when shipmentConsolidationId is set on a Japan Post shipment:

  • A tracking number, as usual.
  • A shipping-label PDF that does not include the customer/post-office receipt copies. Those receipts are deferred to Step 3, where they're bundled into the dispatch-slip document for the whole batch.
  • The shipment is associated with the consolidation; you can re-query it via shipmentConsolidation(id: ...) to see its members.

Repeat this step for every parcel in the day's batch. Up to 250 shipments per consolidation; attempting to close a larger batch fails with a clear validation error before any Japan Post call is made.

You can also verify the batch's contents before closing:

query {
  shipmentConsolidation(id: "sc_01hjk...") {
    status
    shipments {
      id
      trackingDetails {
        number
      }
    }
  }
}

status is OPEN until the consolidation is closed in Step 3.

Step 3: shipmentConsolidationUpdate(status: CLOSED) 

Closes the batch. This is the call that asks Japan Post to generate the deferred-payment dispatch slip covering every member's tracking number, and attaches the resulting PDF to the consolidation.

Mutation:

mutation {
  shipmentConsolidationUpdate(input: { id: "sc_01hjk...", status: CLOSED }) {
    id
    status
    statusTransitions {
      status
      changedAt
      note
    }
    shipments {
      id
      customsDocuments {
        documentType
        fileUrl
      }
    }
  }
}
FieldNotes
idThe consolidation ID from Step 1.
statusSet to CLOSED to close the batch and produce the dispatch slip.
shipmentIdOptional. Adding a shipment + closing in the same call is supported; usually omitted at this stage.

On a CLOSED request:

  1. The consolidation is validated: ≤250 shipments, and every member must have a tracking number. If a shipment is missing its tracking number (its label was never created), the call is rejected.
  2. Japan Post is asked to generate a deferred-payment dispatch slip covering every member's tracking number.
  3. The status briefly moves to MANIFEST_CREATED while the slip PDF is being fetched, then to CLOSED once the document has been attached.
  4. The dispatch slip PDF (one file containing the slip plus every member's customer/post-office receipts) is attached to the consolidation as a CustomsDocument with documentType: MANIFEST_DOCUMENT.

Response:

{
  "data": {
    "shipmentConsolidationUpdate": {
      "id": "sc_01hjk...",
      "status": "CLOSED",
      "statusTransitions": [
        {
          "status": "OPEN",
          "changedAt": "2026-05-01T08:00:00Z",
          "note": "Shipment batch created"
        },
        {
          "status": "MANIFEST_CREATED",
          "changedAt": "2026-05-01T17:30:12Z",
          "note": "Dispatch slip created with Japan Post"
        },
        {
          "status": "CLOSED",
          "changedAt": "2026-05-01T17:30:14Z",
          "note": "Dispatch slip downloaded and uploaded"
        }
      ],
      "shipments": [
        {
          "id": "ship_...",
          "customsDocuments": [
            {
              "documentType": "MANIFEST_DOCUMENT",
              "fileUrl": "https://customs-docs.zonos.com/.../japanpost-dispatch-slip.pdf"
            }
          ]
        }
      ]
    }
  }
}

Print the PDF at fileUrl. It contains:

  • Page 1: The deferred-payment dispatch slip — hand this to the post office.
  • Pages 2+: The customer/post-office receipts for each parcel — one stapled to each parcel, the other kept by the post office.

Once printed, bring the parcels + the dispatch slip + the receipts to the post office in one trip. Japan Post invoices your Later Pay Number at the end of the billing period.

Putting it together 

A representative day for a merchant shipping 50 Japan Post parcels looks like:

08:00 → shipmentConsolidationCreate(JAPAN_POST, accountNumber)  → sc_01HJK...
08:30 → CreateDeclarationShipment( ... shipmentConsolidationId: "sc_01HJK..." )    parcel 1
09:15 → CreateDeclarationShipment( ... shipmentConsolidationId: "sc_01HJK..." )    parcel 2
...
16:45 → CreateDeclarationShipment( ... shipmentConsolidationId: "sc_01HJK..." )    parcel 50
17:30 → shipmentConsolidationUpdate(id: "sc_01HJK...", status: CLOSED)
17:32 → Print PDF

If you ship across multiple business units / billing accounts, run a separate consolidation per account — pass a different accountNumber on each shipmentConsolidationCreate and route shipments accordingly.

Error handling 

Validation errors (caught before any Japan Post call)

  • accountNumber malformed — rejected at Step 1 (shipmentConsolidationCreate) before the consolidation is even saved. Error message identifies the offending segment.
  • >250 shipments — rejected at Step 3, before the Japan Post call is made.
  • Member shipment missing a tracking number — rejected at Step 3. Means a label create silently failed earlier; investigate the affected shipment via shipment(id: ...) { trackingDetails }.
  • No deferred-payment number set on the consolidation — rejected at Step 3. Pass accountNumber on shipmentConsolidationCreate.

Japan Post API errors

If Japan Post rejects the dispatch slip request, the close mutation surfaces the carrier's error code and message as a GraphQL error. The most common:

CodeMeaningWhat to check
E034Deferred customer numbers missingaccountNumber on the consolidation.
E035Tracking numbers must be 13 chars separated by -Member shipments somehow have malformed tracking numbers.
E036Tracking numbers must be alphanumericSame as above.
E037Not a valid deferred shipmentA member's label was created without the deferred-payment customer number. Contact Zonos support.
E046Total weight requiredUpstream label create was malformed. Contact Zonos support.
50Parameter format errorField-length or type violation on the input.
51Authentication errorContact Zonos support.

Retries

If the close call fails after Japan Post has accepted the dispatch slip request (i.e. during PDF retrieval), retrying shipmentConsolidationUpdate(status: CLOSED) is safe — the platform will skip the carrier call and just re-attempt fetching and attaching the document.

If the close fails before Japan Post has accepted the request (validation error, E0xx, network timeout), no state has changed — fix the root cause and retry.

GraphQL API ReferenceTypes, inputs, and operations used in this guide
Book a demo

Was this page helpful?