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

# Add a parcel

> Add a parcel to an existing consignment until it is processed or manifested.

Requires the `consignments:write` scope. Customer-scoped API keys can add
parcels to their own consignments.

Use this when a shipment turns out to have more boxes than were declared at
create. Parcels can be added while the consignment is still editable. The
request is refused with `409 consignment_locked` once the consignment:

* was deleted (cancelled),
* is on hold,
* has a final-mile (last-mile) carrier label booked,
* has been processed in the warehouse (scanned into a group),
* is on a manifest,
* has been handed to a partner, or
* has a delivered parcel.

The error `message` says which of these applies. In that case, create a new
consignment for the extra parcel.

> [!NOTE]
>
> The same editable rule applies to customer-scoped API keys (and the customer
> portal) when they change the receiver (`PATCH /consignments/{id}` receiver
> fields) or generate a new own-template label (`POST /labels/generate`).
> Downloading (reprinting) an existing label is always allowed.

First-, middle-mile and pre-applied labels on the other parcels don't block
the add and are left as they are. The new parcel starts without a carrier
label. To book one, call
`POST /consignments/{id}/labels`; it
only labels parcels that don't have a label yet. To render your own label
template for the new parcel, pass `labels`.

When the workspace has a parcel barcode structure configured (Settings →
Defaults), the new parcel gets a `generated_barcode` from it, just as at
create. The consignment's tracking number does not change. A
`parcel.added` timeline event is recorded and delivered to your webhooks.

**id** `integer` *required*

The consignment ID.

## Body

The body is one parcel in the same shape as `parcels[]` on
[create](https://traddal.dev/api-reference/consignments/create.md).

**weight\_value** `number` *required*

Parcel weight, in the consignment's `weight_unit`. Must be greater than 0.

**packaging\_type** `string` (default: BOX)

`BAG`, `BOX`, `ENVELOPE`, `PALLET`, or `TUBE`.

**height** `number`

Height, in the consignment's `measurement_unit`.

**width** `number`

Width, in the consignment's `measurement_unit`.

**depth** `number`

Depth (length), in the consignment's `measurement_unit`.

**sender\_ref** `string`

Your reference for the parcel (max 100 chars).

**barcode** `string`

Your own parcel barcode. It must not already belong to another parcel in
the workspace (`409 barcode_exists`).

**declared\_value** `number`

Declared parcel value. Requires `currency_code`.

**currency\_code** `string`

ISO 4217 currency of `declared_value`.

**items** `array`

The parcel's contents, with the same fields as `parcels[].items[]` on
create. `order_ref` must name an order that is already on the
consignment.

**labels** `string` (default: none)

Your own label template for the new parcel. `sync` renders it before the
response, and the label URL is returned in `label`. `async` renders it in
the background and signals completion with the `label.generated` webhook.
`none` means no label is rendered; you can generate one later with
`POST /labels/generate`.

> [!NOTE]
>
> Pre-applied carrier labels (`carriers[]`) and nested `orders[]` can only be
> sent when the consignment is created.

## Response

Returns `201`.

**parcel** `object`

The new parcel, including `generated_barcode`, its `identifiers`, and its
`items`.

**parcel\_count** `integer`

The number of parcels on the consignment after the add.

**label** `object`

Only returned with `labels: "sync"`. Contains `label_url` and
`barcode_value`.

**label\_errors** `array`

Only returned when `labels: "sync"` failed, for example because no
template is set up. The parcel is still added.

```bash cURL theme={null}
curl -X POST https://{partner}.mytraddal.com/admin/api/v1/consignments/1234567890/parcels \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "packaging_type": "BOX",
    "weight_value": 2.4,
    "height": 20,
    "width": 30,
    "depth": 40,
    "sender_ref": "NS-SO-1042-3"
  }'
```

```json 201 theme={null}
{
  "success": true,
  "message": "Parcel 3 added",
  "parcel": {
    "id": 4829105736,
    "consignment_id": 1234567890,
    "sender_ref": "NS-SO-1042-3",
    "packaging_type": "BOX",
    "weight_value": "2.4",
    "height": "20",
    "width": "30",
    "length": "40",
    "barcode": null,
    "generated_barcode": "WPS000104203",
    "identifiers": [
      { "code": "WPS000104203", "kind": "barcode", "owner": "platform", "source": "created" }
    ],
    "items": []
  },
  "parcel_count": 3
}
```

```json 409 theme={null}
{
  "success": false,
  "code": "consignment_locked",
  "message": "Parcels can no longer be added — the shipment is already on a manifest"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.