# Split and Merge Shipments

A shipment doesn't always match how you'll ship its items. Some items may be on backorder, some may ship from
another warehouse, or several orders for the same customer may need to go out in one box. The split and merge
endpoints let you change which shipment holds which items before you buy a label.

- **Split** moves items from one shipment into one or more new shipments.
- **Merge** moves all of the items from one or more shipments onto another shipment and deletes the shipments
they came from.


Both operations keep each shipment linked to its sales orders, so order sources keep getting shipment
notifications for every item.

## Before You Start

Split and merge only work on shipments that haven't shipped yet and that came from a sales order. Every
shipment in the request must:

- Have a `shipment_status` of `pending`, `awaiting_payment`, or `on_hold`. You can't split or merge shipments
that have shipped or been cancelled.
- Be linked to at least one sales order. The `sales_order_ids` array on the shipment lists its sales orders. If
the array is empty, you can't split or merge the shipment.
- Not come from a marketplace that supplies its own shipping labels.


To check these values, get the shipment with
[Get shipment by id](/apis/openapi#operation/get_shipment_by_id). The response also has the
`items` array, which you'll need when you split.

### Sales Order Fields on Shipments

Shipment responses include these fields that show how a shipment is linked to its sales orders:

| Field | Description |
|  --- | --- |
| `sales_order_ids` | The sales orders the shipment is linked to. This array is always present and is empty if the shipment isn't linked to a sales order. It's read-only and is ignored in requests. |
| `items[].sales_order_id` | The sales order that the item belongs to, or `null` if the item isn't linked to one. |
| `items[].sales_order_item_id` | The sales order line item that the item belongs to, or `null` if the item isn't linked to one. |


These fields are returned by [Get shipment by id](/apis/openapi#operation/get_shipment_by_id),
[Get shipment by external ID](/apis/openapi#operation/get_shipment_by_external_id),
[List shipments](/apis/openapi#operation/list_shipments),
[Create shipments](/apis/openapi#operation/create_shipments), and
[Update shipment](/apis/openapi#operation/update_shipment).

## Split a Shipment

To split a shipment, send `POST /v2/shipments/{shipment_id}/split`. Each entry in the `shipments` array creates
one new shipment, and lists the items and quantities to move into it. Anything you don't list stays on the
original shipment.

### Requirements

- The `item_id` of each item you want to move. Use the `items[].item_id` values from the original shipment.
- The `quantity` of each item to move. This must be at least 1.


### Rules

- Every item you move must belong to the **same sales order**. Use `items[].sales_order_id` to check. To move
items from more than one sales order, send one split request for each sales order.
- At least one item must **stay on the original shipment**. To move everything, leave at least one unit behind,
or move the items to a shipment that already exists by using [merge](#merge-shipments).
- An item can be listed only **once** in each new shipment. You can list the same item in more than one new
shipment, but the total quantity you move can't be more than the quantity on the original shipment.
- You can create up to **100** new shipments in one request, and each new shipment can list up to **200** items.


### Example

The original shipment `se-202902255` has two items:


```json
{
  "shipment_id": "se-202902255",
  "sales_order_ids": ["8c1f2a5e-3b7d-4e9a-a6c2-1d4f5e6a7b8c"],
  "items": [
    {
      "item_id": "1402291169813",
      "sku": "MUG-BLUE",
      "quantity": 3,
      "sales_order_id": "8c1f2a5e-3b7d-4e9a-a6c2-1d4f5e6a7b8c"
    },
    {
      "item_id": "1402291169814",
      "sku": "TEE-L",
      "quantity": 1,
      "sales_order_id": "8c1f2a5e-3b7d-4e9a-a6c2-1d4f5e6a7b8c"
    }
  ]
}
```

To ship one of the mugs separately, move one unit of item `1402291169813` into a new shipment:

**POST /v2/shipments/se-202902255/split**


```http
POST /v2/shipments/se-202902255/split HTTP/1.1
Host: api.shipstation.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipments": [
    {
      "items": [
        { "item_id": "1402291169813", "quantity": 1 }
      ]
    }
  ]
}
```

**Response**


```json
{
  "shipment_id": "se-202902255",
  "new_shipment_ids": ["se-202902301"]
}
```

`new_shipment_ids` lists the new shipments in the same order as the `shipments` array in the request. After the
split:

- `se-202902255` has 2 units of `MUG-BLUE` and 1 unit of `TEE-L`.
- `se-202902301` has 1 unit of `MUG-BLUE`.


### What Happens to the New Shipments

Each new shipment:

- Is created from the original shipment, so it starts with the same details, such as addresses, tags, tax
identifiers, notes, and assigned user.
- Is linked to the same sales order as the items it holds.
- Gets a new `shipment_id`. Get it with [Get shipment by id](/apis/openapi#operation/get_shipment_by_id)
to see its items and other details.


The package weight and customs information are recalculated for the original shipment and for each new
shipment. Rates you got before the split may no longer be accurate, so get new rates before you buy labels.

Sales orders after a split
If you move all of a sales order's items off a shipment, the original shipment can still list that sales order in
`sales_order_ids`. To see which sales order each item belongs to, use `items[].sales_order_id`.

## Merge Shipments

To merge shipments, send `POST /v2/shipments/{shipment_id}/merge`. The shipment in the URL is the **target**. The
items from every shipment in `shipment_ids` move onto the target, and the shipments in `shipment_ids` are then
deleted.

### Requirements

- The `shipment_id` of the target shipment, in the URL.
- A `shipment_ids` array with the shipments to merge into it, up to **100** per request.


### Rules

- `shipment_ids` must include at least one shipment other than the target. If the array includes the target
shipment or lists a shipment more than once, the extra entries are ignored.
- The shipments can belong to **different sales orders**. The target becomes linked to the sales orders of every
shipment merged into it.
- Every shipment, including the target, must meet the requirements in [Before You Start](#before-you-start).


### Example

Merge shipments `se-202902301` and `se-202902302` into `se-202902255`:

**POST /v2/shipments/se-202902255/merge**


```http
POST /v2/shipments/se-202902255/merge HTTP/1.1
Host: api.shipstation.com
API-Key: __YOUR_API_KEY_HERE__
Content-Type: application/json

{
  "shipment_ids": ["se-202902301", "se-202902302"]
}
```

**Response**


```json
{
  "shipment_id": "se-202902255",
  "merged_shipment_ids": ["se-202902301", "se-202902302"]
}
```

### What Happens After a Merge

- The target shipment holds all of the items from the merged shipments, along with its own.
- The tags from the merged shipments are added to the target shipment.
- The target's `sales_order_ids` includes the sales orders of the merged shipments.
- The package weight and customs information on the target shipment are recalculated. Get new rates before you
buy a label.
- The shipments listed in `merged_shipment_ids` are deleted. Remove any references to them in your system.


## Errors

If a request can't be completed, the response has an `errors` array. The `error_code` tells you why:

| `error_code` | HTTP status | What it means |
|  --- | --- | --- |
| `invalid_field_value` | 400 | A value in the request can't be used. For example, a quantity is larger than the quantity on the shipment, an item is listed twice in the same new shipment, no items would stay on the original shipment, or `shipment_ids` has no shipment other than the target. |
| `invalid_identifier` | 400 or 404 | A split `item_id` isn't on the shipment (400), or a shipment wasn't found on your account (404). |
| `invalid_status` | 400 | A shipment has shipped, has been cancelled, or has another status that can't be split or merged. |
| `sales_order_link_required` | 400 | A shipment isn't linked to a sales order. |
| `multiple_sales_orders` | 400 | The items in a split belong to more than one sales order. Split them in separate requests. |
| `bring_your_own_label_not_supported` | 400 | A shipment comes from a marketplace that supplies its own shipping labels. |
| `unspecified` | 400 or 500 | The request was rejected for another reason. The `message` explains why. |


The `message` field describes the problem. When the problem is with a specific value, `field_name` and
`field_value` identify it.

## Related Guides

- [Understanding Orders & Shipments](/orders/understanding-orders-shipments)
- [List Shipments](/list-shipments)
- [Update Shipments](/shipments/update)
- [Tag Shipments](/tag-shipments)
- [Create Labels](/create-labels)