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.
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_statusofpending,awaiting_payment, oron_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_idsarray 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. The response also has the items array, which you'll need when you split.
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, Get shipment by external ID, List shipments, Create shipments, and Update 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.
- The
item_idof each item you want to move. Use theitems[].item_idvalues from the original shipment. - The
quantityof each item to move. This must be at least 1.
- Every item you move must belong to the same sales order. Use
items[].sales_order_idto 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.
- 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.
The original shipment se-202902255 has two items:
{
"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
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
{
"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-202902255has 2 units ofMUG-BLUEand 1 unit ofTEE-L.se-202902301has 1 unit ofMUG-BLUE.
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 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.
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.
- Productionhttps://api.shipstation.com/v2/shipments/{shipment_id}/split
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
- Move one unit of an item into a new shipment
- Create two new shipments
curl -i -X POST \
https://api.shipstation.com/v2/shipments/se-28529731/split \
-H 'Content-Type: application/json' \
-H 'api-key: YOUR_API_KEY_HERE' \
-d '{
"shipments": [
{
"items": [
{
"item_id": "1402291169813",
"quantity": 1
}
]
}
]
}'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.
- The
shipment_idof the target shipment, in the URL. - A
shipment_idsarray with the shipments to merge into it, up to 100 per request.
shipment_idsmust 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.
Merge shipments se-202902301 and se-202902302 into se-202902255:
POST /v2/shipments/se-202902255/merge
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
{
"shipment_id": "se-202902255",
"merged_shipment_ids": ["se-202902301", "se-202902302"]
}- 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_idsincludes 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_idsare deleted. Remove any references to them in your system.
- Productionhttps://api.shipstation.com/v2/shipments/{shipment_id}/merge
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://api.shipstation.com/v2/shipments/se-28529731/merge \
-H 'Content-Type: application/json' \
-H 'api-key: YOUR_API_KEY_HERE' \
-d '{
"shipment_ids": [
"se-202902301",
"se-202902302"
]
}'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.