> ## Documentation Index
> Fetch the complete documentation index at: https://traddal.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a consignment

> Create a consignment with sender, receiver, parcels, orders, and items.

Requires the `consignments:write` scope. Creating a consignment runs your
workspace's validation rules synchronously (an `error`-severity hit rejects
the create with `422`; warnings ride the response) and then dispatches your
`consignment.created` automation flows.

Two payload shapes are accepted and can be mixed:

* **Consignment-level orders** — commercial orders in the top-level
  `orders[]` (no items), physical items in `parcels[].items[]`, linked back
  by `order_ref`.
* **Nested orders** — orders under their parcel in `parcels[].orders[]`,
  each carrying its own `items[]`.

Every request on this surface is audited: the response carries an
`X-Request-Id` header (a ULID) you can quote to support and look up later.

## Consignment

<ParamField body="shipment_ref" type="string" required>
  Your reference for the shipment (1–100 chars). The only required
  top-level field.
</ParamField>

<ParamField body="customer_id" type="integer">
  The customer this consignment belongs to. A customer-scoped API key pins
  its own customer and ignores this field; omitted otherwise, the
  consignment has no customer.
</ParamField>

<ParamField body="type" type="string" default="delivery">
  `delivery`, `return`, or `exchange`.
</ParamField>

<ParamField body="external_code" type="string">
  Your product/plan code — shipping rules and flows match on it.
</ParamField>

<ParamField body="incoterm" type="string">
  Incoterm (e.g. `DDP`, `DAP`).
</ParamField>

<ParamField body="entry_date" type="string">
  `YYYY-MM-DD`.
</ParamField>

<ParamField body="transport_mode" type="string">
  `sea`, `air`, `road`, or `rail`.
</ParamField>

<ParamField body="weight_unit" type="string">
  `kg`, `g`, `lb`, or `oz` — the unit for every weight in the payload.
</ParamField>

<ParamField body="measurement_unit" type="string">
  `cm`, `mm`, or `inch` — the unit for parcel dimensions.
</ParamField>

<ParamField body="movement_indicator" type="string">
  `b2b`, `b2c`, `c2b`, or `c2c`.
</ParamField>

<ParamField body="shipping" type="object">
  Shipment-level freight: `{ amount, currency_code }` (currency required
  when given).
</ParamField>

<ParamField body="insurance" type="object">
  Shipment-level insurance: `{ amount, currency_code }`.
</ParamField>

<ParamField body="tags" type="array">
  Free-text tags.
</ParamField>

<ParamField body="references" type="object">
  Carrier custom references: `external_item_code`, `external_order_code`,
  `special_provision`, `sender_ukims_number`, `receiver_ukims_number`.
</ParamField>

<ParamField body="supporting_agents" type="object">
  Supporting addresses keyed `return`, `pudo`, `importer_of_record`,
  `billing` — each a slim address (`company_name`, `address_1`,
  `address_2`, `city`, `state_province`, `post_code`, `country_code`,
  `type`, `contact`).
</ParamField>

<ParamField body="carrier" type="object">
  Explicit carrier selection — always wins over shipping rules:
  `{ org_carrier_id, service_id?, additional_service_ids? }`.
</ParamField>

Additional optional fields: `nature_type` (UPU CL136 code),
`shipping_date`, `invoice_number`, `invoice_url`, `office_of_origin`,
`windsor_not_at_risk`, `picking_ref`, `contract_condition`,
`total_discount` (`{ amount, currency_code }`), `attributes`
(`cash_on_delivery`, `notification_type`, `flexible_delivery`,
`pod_required`, `content_type`), `committed_delivery_window`
(`{ from, to }`), and `volume_unit` (`ml` | `l`).

## Sender and receiver

<ParamField body="sender" type="object">
  The shipper: `code`, `company_name`, `address_1`–`address_3`, `city`,
  `state_province`, `post_code`, `country_code` (ISO alpha-2), `contact`
  (`name`, `phone`, `email`), plus tax/duty registrations `eori_id`,
  `ioss_id`, `vat_id`, `tax_id`, `manufacturer_id`.
</ParamField>

<ParamField body="receiver" type="object">
  The consignee — same shape as `sender`, plus `time_zone` and `type`
  (`Business` | `Residential`).
</ParamField>

## Orders

<ParamField body="orders" type="array">
  Consignment-level commercial orders (up to 200). Each requires
  `order_ref` (unique across the consignment), plus optional `amount`,
  `currency_code`, `order_date`, `invoice_number`, `shipping_charge` /
  `insurance_charge` / `other_charge` (each `{ amount, currency_code }`).
</ParamField>

## Parcels

<ParamField body="parcels" type="array">
  Each parcel requires `weight_value`. Optional: `sender_ref`, `barcode`
  (your own parcel barcode — never overwritten by carrier labelling),
  `packaging_type` (`BAG` | `BOX` | `ENVELOPE` | `PALLET` | `TUBE`,
  default `BOX`), `height`, `width`, `depth`, `declared_value`,
  `currency_code`, plus its contents in `items[]` and/or legacy nested
  `orders[]`.
</ParamField>

<ParamField body="parcels[].items[]" type="array">
  The declared item lines. Per item:

  * `quantity` (required) — positive integer
  * `unit_value` (required) — **per-unit** price, not the line total
  * `currency_code` — ISO 4217
  * `order_ref` — links the item to a consignment-level order (must exist
    in `orders[]`)
  * `sku` — your item reference (stored as `item_ref`)
  * `title`, `description`
  * `harmonised_code` / `hs_code` — declared HS code, if known;
    `hs_code_source` records where it came from (audit only)
  * `country_of_origin` — ISO alpha-2 country of manufacture
  * `product_url` — the item's listing page (usable by AI classification)
  * `weight`
  * Section 232 metals traceability: `country_of_melt_pour`,
    `primary_country_of_smelt`, `secondary_country_of_smelt`,
    `country_of_cast`
  * CN23/ITMATT: `nature_type`, `certificate_number`
  * `compliance` — agency certs keyed by scheme (e.g. `cpsc`)
  * `dangerous_goods` — structured DG declaration (`un_id`,
    `shipping_name`, `product_class`, `packaging_group`, …)
</ParamField>

<Warning>
  **International consignments** (sender and receiver in different countries)
  must carry at least one item, and every item must have a
  `country_of_origin` — customs declarations and the commercial invoice are
  built from the item lines. Domestic consignments are exempt. Items must
  live inside a parcel (`parcels[].items[]`) or a nested order — top-level
  `items` are rejected.
</Warning>

## Response

Returns `201` with `data` containing the created tree:

<ResponseField name="data.consignment" type="object">
  The consignment (`id`, `shipment_ref`, `status`, `sender`, `receiver`,
  `created_at`, …) including its `customer` when one was linked.
</ResponseField>

<ResponseField name="data.parcels" type="array">
  The parcels, each with its orders and items nested.
</ResponseField>

<ResponseField name="data.orders" type="array">
  The consignment-level orders (commercial view, items included).
</ResponseField>

<ResponseField name="data.documents" type="array">
  Documents attached during creation — only populated when an inline flow
  (e.g. `generate_invoice`) ran; background flows attach later.
</ResponseField>

<ResponseField name="data.validation_warnings" type="array">
  Present when warning-severity validation rules matched — the consignment
  **was** created.
</ResponseField>

By default, `consignment.created` flows run in the background. A flow action
marked "Wait and include in API response" runs inline: the response then
carries fresh label/tracking/invoice data on the parcels and consignment,
and a failed wait-flow (with no side effects) rolls the create back and
returns `422` with the error message(s).

```json 422 theme={null}
{
  "success": false,
  "message": "Declared value exceeds the destination limit",
  "errors": ["Declared value exceeds the destination limit"],
  "validation_errors": [ { "message": "Declared value exceeds the destination limit" } ]
}
```

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://{partner}.mytraddal.com/admin/api/v1/consignments \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer {access_token}' \
    -d '{
      "shipment_ref": "SHIP-1001",
      "incoterm": "DAP",
      "weight_unit": "kg",
      "sender": {
        "company_name": "Acme Ltd",
        "address_1": "1 Warehouse Way",
        "city": "London",
        "post_code": "E1 6AN",
        "country_code": "GB",
        "eori_id": "GB123456789000"
      },
      "receiver": {
        "company_name": "Acme Inc",
        "address_1": "350 5th Ave",
        "city": "New York",
        "post_code": "10118",
        "country_code": "US",
        "type": "Business",
        "contact": { "name": "Jane Smith", "email": "jane@example.com" }
      },
      "orders": [
        { "order_ref": "ORDER-4412", "currency_code": "USD" }
      ],
      "parcels": [{
        "barcode": "PB123456789GB",
        "weight_value": 2.4,
        "items": [{
          "order_ref": "ORDER-4412",
          "sku": "BKP-40L",
          "title": "Waterproof hiking backpack 40L",
          "description": "Backpack with outer surface of man-made textile materials",
          "quantity": 2,
          "unit_value": 45.0,
          "currency_code": "USD",
          "country_of_origin": "VN",
          "harmonised_code": "4202.92.3120",
          "weight": 1.1
        }]
      }]
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "success": true,
    "data": {
      "consignment": {
        "id": 1841,
        "customer_id": null,
        "shipment_ref": "SHIP-1001",
        "external_code": null,
        "type": "delivery",
        "incoterm": "DAP",
        "status": "created",
        "weight_unit": "kg",
        "sender": {
          "company_name": "Acme Ltd",
          "address_1": "1 Warehouse Way",
          "city": "London",
          "post_code": "E1 6AN",
          "country_code": "GB",
          "contact": { "name": null, "email": null, "phone": null },
          "tax_duty": { "eori_id": "GB123456789000" }
        },
        "receiver": {
          "company_name": "Acme Inc",
          "address_1": "350 5th Ave",
          "city": "New York",
          "post_code": "10118",
          "country_code": "US",
          "contact": { "name": "Jane Smith", "email": "jane@example.com", "phone": null }
        },
        "customer": null,
        "created_at": "2026-07-30T10:15:02.000Z",
        "updated_at": "2026-07-30T10:15:02.000Z"
      },
      "parcels": [
        {
          "id": 3320,
          "barcode": "PB123456789GB",
          "packaging_type": "BOX",
          "weight_value": "2.4",
          "items": [
            {
              "item_ref": "BKP-40L",
              "title": "Waterproof hiking backpack 40L",
              "quantity": 2,
              "amount": "45",
              "currency_code": "USD",
              "country_of_origin": "VN",
              "harmonised_code": "4202.92.3120"
            }
          ]
        }
      ],
      "orders": [
        { "order_ref": "ORDER-4412", "currency_code": "USD" }
      ],
      "documents": []
    }
  }
  ```
</ResponseExample>
