***
title: Receiving
description: How to create and manage warehouse receiving orders using the ShipBob API
last-updated: 'February 24, 2026'
---------------------------------
## Overview
A **Warehouse Receiving Order (WRO)** is how ShipBob manages inbound shipments into their fulfillment centers. Some other solutions call this an "ASN" (Advanced Ship Notice).
This guide will walk you through building an integration to send inventory to ShipBob and sync it back to your system.
***
## How It Works
Here's the flow of creating and tracking a Warehouse Receiving Order:
```mermaid
sequenceDiagram
participant Your System
participant ShipBob
Your System->>ShipBob: 1. Check if products exist
ShipBob-->>Your System: Inventory IDs
Your System->>ShipBob: 2. Create WRO
ShipBob-->>Your System: WRO ID & Status: Awaiting
Your System->>ShipBob: 3. Get box labels (optional)
ShipBob-->>Your System: PDF labels
Note over Your System,ShipBob: Ship inventory to ShipBob warehouse
ShipBob->>ShipBob: Inventory arrives & stowed
loop Every 15-30 minutes
Your System->>ShipBob: 4. Poll for completed WROs
ShipBob-->>Your System: List of completed WROs
end
Your System->>Your System: 5. Update inventory in your system
Your System->>ShipBob: 6. Mark WRO as synced
ShipBob-->>Your System: Confirmed
```
***
## Step 1: Check if Products Exist in ShipBob
Before creating a WRO, every product needs an `inventory_id` from ShipBob.
**Check if a product exists:**
```javascript
GET https://api.shipbob.com/2026-01/product?sku=light-roast
```
If the product doesn't exist, create it first:
```javascript expandable
POST https://api.shipbob.com/2026-01/product
{
"name": "Light Roast Coffee",
"type_id": 1,
"variants": [
{
"name": "Light Roast Coffee",
"sku": "light-roast",
"packaging_requirement_id": 1,
"packaging_material_type_id": 1,
"barcode": "06547321109",
"customs": {
"country_code_of_origin": "US",
"hs_tariff_code": "6103.22.00",
"value": "10",
"description": "coffee"
}
}
]
}
```
Save the
`inventory_id`
when you create products in your system. This way, you won't need to look them up every time.
***
## Step 2: Create a WRO
Once you have your `inventory_id` values, create the WRO:
```javascript
POST https://api.shipbob.com/2026-01/receiving
```
**Example request (sending packages):**
```javascript
{
"fulfillment_center": {
"id": 10
},
"package_type": "Package",
"box_packaging_type": "EverythingInOneBox",
"expected_arrival_date": "2025-01-15",
"purchase_order_number": "PO-2026-001",
"boxes": [
{
"tracking_number": "1Z999AA10123456784",
"box_items": [
{
"inventory_id": 12345678, // get the inventory_id by making request to GET Products /2026-01/product?sku=light-roast
"quantity": 50
}
]
}
]
}
```
**What you'll get back:**
```javascript
{
"id": 987654,
"status": "Awaiting",
"package_type": "Package",
"box_packaging_type": "EverythingInOneBox",
"expected_arrival_date": "2025-01-15T00:00:00+00:00",
"purchase_order_number": "PO-2026-001",
"box_labels_uri": "/2026-01/receiving/987654/labels"
// ... additional fields
}
```
Use the
`box_labels_uri`
from the response in the next step if you are fetching box labels.
**Package types:**
* **Package** - For boxes (max 50 boxes per request)
* **Pallet** - For palletized freight shipments (each pallet is a separate box)
* **FloorLoadedContainer** - For container shipments (entire container as one box)
### Creating WROs with Lot Items
If you're sending lot-tracked items (products with expiration dates or batch numbers), you must include `lot_date` and `lot_number` for each item in your WRO.
**Example request with lot items:**
```javascript
POST https://api.shipbob.com/2026-01/receiving
{
"fulfillment_center": { "id": 8 },
"package_type": "Package",
"box_packaging_type": "EverythingInOneBox",
"expected_arrival_date": "2025-12-20T00:00:00Z",
"purchase_order_number": "PO-LOT-001",
"boxes": [
{
"tracking_number": "1Z999AA10123456784",
"box_items": [
{
"inventory_id": 12345678,
"quantity": 50,
"lot_number": "2222",
"lot_date": "2025-06-15T00:00:00Z"
}
]
}
]
}
```
**Key fields for lot items:**
| Field | Required | Description |
| -------------- | -------- | -------------------------------------------------------------- |
| `lot_number` | Yes | Your lot/batch identifier (e.g., "LOT-2222", "BATCH-A1") |
| `lot_date` | Yes | The lot expiration date or manufacture date in ISO 8601 format |
| `inventory_id` | Yes | The ShipBob inventory ID for the product |
| `quantity` | Yes | Number of units in this lot |
Both `lot_number` and `lot_date` are required for lot-tracked items. If you omit either field, the WRO creation will fail.
Make sure the product is already created in ShipBob and you have the `inventory_id` before creating the WRO. You can check if a product is lot-tracked by looking at the product details in the ShipBob dashboard or via the GET Product API.
**Multiple lots in one box:**
You can include multiple lots of the same product or different products in a single box:
```javascript
{
"boxes": [
{
"tracking_number": "1Z999AA10123456784",
"box_items": [
{
"inventory_id": 12345678,
"quantity": 50,
"lot_number": "LOT-2222",
"lot_date": "2025-06-15T00:00:00Z"
},
{
"inventory_id": 12345678,
"quantity": 30,
"lot_number": "LOT-3333",
"lot_date": "2025-08-20T00:00:00Z"
},
{
"inventory_id": 98765432,
"quantity": 100,
"lot_number": "BATCH-A1",
"lot_date": "2026-01-10T00:00:00Z"
}
]
}
]
}
```
***
## Step 3: Generate Box Labels (Optional)
Print box labels to help the warehouse identify your shipment:
```javascript
GET https://api.shipbob.com/2026-01/receiving/{wro_id}/box-labels
```
This returns a PDF with labels for each box/pallet. Print and attach them to your shipment before sending.
***
## Step 4: Poll for Completed WROs
Set up a recurring job (every 15-30 minutes) to check for completed WROs that need to be synced.
**Check for completed WROs:**
```javascript
GET https://api.shipbob.com/2026-01/receiving?statuses=Completed&ExternalSync=false
```
This returns all WROs that are:
* **Completed** - The warehouse has finished processing them
* **Not synced** - You haven't updated your system yet (ExternalSync=false)
**Here's what to do with each completed WRO:**
1. Get the inventory quantities from the WRO
2. Update your system with the new inventory levels
3. Mark the WRO as synced so you don't process it again
**Example code:**
```javascript expandable
// Run this every 15-30 minutes
async function checkForCompletedWROs() {
// 1. Get completed WROs that haven't been synced
const response = await fetch(
'https://api.shipbob.com/2026-01/receiving?statuses=Completed&ExternalSync=false',
{
headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' }
}
);
const wros = await response.json();
// 2. Process each WRO
for (const wro of wros) {
// Get the inventory quantities
wro.boxes.forEach(box => {
box.inventory.forEach(item => {
// Update your system with item.stowed_quantity
console.log(`Product ${item.inventory_id}: +${item.stowed_quantity} units`);
});
});
// 3. Mark as synced
await fetch(
`https://api.shipbob.com/2026-01/receiving:setExternalSync`,
{
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN' },
body: JSON.stringify({ "ids": [987654], "is_external_sync": true })
}
);
}
}
```
***
## Step 5: Mark WRO as Synced
After updating your inventory system, mark the WRO as synced to prevent duplicate processing:
```javascript
POST https://api.shipbob.com/2026-01/receiving:setExternalSync
{
"ids": [987654],
"is_external_sync": true
}
```
This endpoint accepts an array of WRO IDs, allowing you to mark multiple WROs as synced in a single request.
***
## Advanced: Track Individual Boxes
Want to see details for each box? Use this endpoint:
```javascript
GET https://api.shipbob.com/2026-01/receiving/{wro_id}/boxes
```
This shows you the status and quantities for each box, which would enable you to do partial receiving.
***
## Understanding the Inventory Quantities
When you sync a completed WRO, you'll see three quantity fields:
```mermaid
graph LR
A["Expected Quantity
(what you sent)"] --> B["Received Quantity
(what arrived)"]
B --> C["Stowed Quantity
(added to inventory)"]
style A fill:#e1f5ff
style B fill:#fff3cd
style C fill:#d4edda
```
| Field | What it means |
| ------------------- | ------------------------------------------ |
| `expected_quantity` | What you said you were sending |
| `received_quantity` | What actually arrived at the warehouse |
| `stowed_quantity` | What was added to your available inventory |
Always use
`stowed_quantity`
when updating your system. This may be less than expected if items were damaged or missing.
**Example:**
```javascript highlight={6}
{
"inventory_id": 12345678,
"sku": "light-roast",
"expected_quantity": 50, // You sent 50 units
"received_quantity": 48, // Only 48 arrived
"stowed_quantity": 48 // 48 added to inventory
}
```
***
## Important Fields
**`package_type`** - Determines how your shipment is configured. Choose based on your shipping method:
* **Package** - Standard boxes shipped via carrier (max 50 per request)
* **Pallet** - Palletized freight shipments (each pallet = one box)
* **FloorLoadedContainer** - Full container shipments (entire container = one box)
**`expected_arrival_date`** - The date your shipment is expected to arrive at the fulfillment center. Must be set to a future date - using today's date or a past date will result in an error.
**`purchase_order_number`** - Your internal PO number or shipment identifier. Use a unique value for each WRO to simplify tracking and reconciliation.
**`tracking_number`** - The carrier tracking number for each box or pallet. This enables the warehouse to scan and verify your shipment upon arrival.
**`is_external_sync`** - A boolean flag that tracks whether you've synced the WRO data back to your system:
* **Default value:** `false` when the WRO is created
* **Query unsynced WROs:** Use `ExternalSync=false` to find WROs that need processing
* **Mark as synced:** Set to `true` after updating your inventory system
* **Purpose:** Prevents duplicate processing of the same WRO
To mark one or more WROs as synced, use the batch endpoint:
```javascript
POST https://api.shipbob.com/2026-01/receiving:setExternalSync
{
"ids": [987654],
"is_external_sync": true
}
```
***
## WRO Status Flow
Your WRO goes through these stages:
| Status | Description |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Awaiting** | WRO has been created and is waiting for the shipment to physically arrive at the destination warehouse |
| **Arrived** | Entire shipment has physically arrived at the destination warehouse and is ready for processing |
| **PartiallyArrived** | Only part of the ordered items/quantities have arrived at the destination warehouse; the rest are still in transit or pending |
| **Processing** | Shipment has been checked in at the warehouse and receiving/unloading/quality check activities are in progress |
| **Completed** | All items have been fully received, inspected, and put away in the warehouse inventory. The WRO is closed |
| **Cancelled** | The Warehouse Receiving Order has been cancelled (no further receiving expected) |
You can only cancel a WRO while it's in
`Awaiting`
status.
For complete status reference including hub-related statuses, see the [Status Reference](/status-reference#warehouse-receiving-order-statuses) documentation.
***
## Common Issues
Set `expected_arrival_date` to tomorrow or later. Don't use today's date or past dates.
Create the product first, then use the `inventory_id` it returns.
Contact ShipBob support with your WRO ID. The warehouse might be experiencing delays.
Make a request to the GET Fulfillment Center endpoint at `/2026-01/fulfillment-center` to get a list of fulfillment centers you have access to.
***
## Tips
* **Poll every 15-30 minutes** - Receiving can take hours or a few days depending on warehouse volume
* **Use unique PO numbers** - Makes tracking and reconciliation easier
* **Always verify `inventory_id` exists** - Prevents WRO creation failures
* **API rate limit** - 150 requests per minute
* **Consider time zones** - Dates are in UTC; convert appropriately
***
## Related Resources
* [Create Warehouse Receiving Order API](https://developer.shipbob.com/api/receiving/create-warehouse-receiving-order)
* [ShipBob Receiving Best Practices](https://support.shipbob.com/s/article/Send-Inventory-to-ShipBob-WRO-Best-Practice)