Inbound Shipments
Inbound Shipments represent incoming inventory deliveries to a warehouse. You can use the Public API to create, update, list, and inspect inbound shipments, as well as retrieve photos and receiving summaries.
Note
Mutations in this section require the change:inbound_shipments OAuth scope. If your token is missing the view:pii scope, booking_contact_name, booking_contact_email, and booking_contact_number will be returned as null in responses rather than causing an error.
- Create an Inbound Shipment
- Get a single Inbound Shipment
- List Inbound Shipments
- Update an Inbound Shipment
- Get Inbound Shipment Images
- Get Inbound Shipment Summary
- Get Inbound Shipment Location Summary
Create an Inbound Shipment
Use the inbound_shipment_create mutation to create a new inbound shipment. The only field required in every case is warehouse_id.
Note
You must provide either purchase_order_ids or vendor_id. If you omit purchase_order_ids, vendor_id becomes required — see Receiving on the fly below.
Below is an example using every field the mutation currently supports:
mutation {
inbound_shipment_create(
data: {
customer_account_id: "QWNjb3VudDo2NzU="
warehouse_id: "V2FyZWhvdXNlOjgwNzU="
purchase_order_ids: ["UHVyY2hhc2VPcmRlcjoxMjM0NQ=="]
vendor_id: "VmVuZG9yOjU1MTI="
carrier: "FedEx Freight"
pro_number: "PRO-12345"
bol_reference: "BOL-98765"
bol_url: "https://example.com/documents/bol-98765.pdf"
expected_dock: "D12"
dock_used: "D12"
container_number: "CONT456789"
notes: "Fragile items on pallet 3"
estimated_truck_arrival: "2026-08-15T14:00:00Z"
scheduled_at: "2026-08-15T14:00:00Z"
truck_arrived_at: "2026-08-15T14:10:00Z"
truck_unload_started_at: "2026-08-15T14:20:00Z"
truck_unload_finished_at: "2026-08-15T16:00:00Z"
truck_departure_at: "2026-08-15T16:15:00Z"
booking_contact_name: "John Doe"
booking_contact_email: "john@example.com"
booking_contact_number: "555-123-4567"
container_size: "s40ctr"
load_type: "ftl"
shipment_type: "pallet"
number_carton: 10
pallets_quantity: 4
people_for_unload: 2
people_for_receiving: 3
}
) {
request_id
complexity
inbound_shipment {
id
legacy_id
status
carrier
pro_number
bol_reference
bol_url
expected_dock
dock_used
container_number
notes
estimated_truck_arrival
scheduled_at
truck_arrived_at
truck_unload_started_at
truck_unload_finished_at
truck_departure_at
booking_contact_name
booking_contact_email
booking_contact_number
container_size
load_type
shipment_type
number_carton
pallets_quantity
people_for_unload
people_for_receiving
vendor_id
warehouse {
id
}
purchase_orders {
edges {
node {
id
po_number
}
}
}
}
}
}The shipment will be created with status PENDING_ARRIVAL (or ARRIVED if it’s created without a purchase order — see below).
Note
customer_account_id is only needed if you’re a 3PL performing this action on behalf of one of your customer accounts.
Note
Valid container_size values: s20ctr, s40ctr, s40hc, s45hc, s53_dry_van, box_truck, strait_truck, s48, reefer53, reefer48, dry_flatbed_pup, pup
Valid load_type values: ctn_carton, ltl, ftl, ctr
Valid shipment_type values: parcel, pallet, ctr_palletized, ctr_floor_loaded
Casing: send container_size, load_type, and shipment_type in lowercase (as shown above). They are returned in UPPERCASE on output (for example, load_type: FTL). This is expected behavior, not an error.
Field length limits: expected_dock and dock_used are limited to 8 characters, pro_number and bol_reference to 120 characters, bol_url to 500 characters, container_number to 25 characters, notes to 512 characters, booking_contact_name and booking_contact_email to 250 characters, and booking_contact_number to 45 characters.
Receiving on the fly (no purchase order)
If you don’t have a purchase order to attach yet, you can create an inbound shipment directly against a vendor instead of purchase_order_ids. ShipHero automatically creates an empty purchase order for that vendor and marks the shipment ARRIVED and unexpected:
mutation {
inbound_shipment_create(
data: {
warehouse_id: "V2FyZWhvdXNlOjgwNzU="
vendor_id: "VmVuZG9yOjU1MTI="
}
) {
request_id
complexity
inbound_shipment {
id
status
vendor_id
}
}
}Note
This call fails if receiving on the fly has been disabled for your account, or if neither purchase_order_ids nor vendor_id is provided.
Get a single Inbound Shipment
Use the inbound_shipment query to retrieve a single inbound shipment by its ID.
{
inbound_shipment(id: "SW5ib3VuZFNoaXBtZW50OjEyMzQ=") {
request_id
complexity
data {
id
legacy_id
account_id
warehouse_id
status
carrier
pro_number
bol_reference
bol_url
expected_dock
dock_used
container_number
notes
estimated_truck_arrival
truck_arrived_at
truck_unload_started_at
truck_unload_finished_at
truck_departure_at
booking_contact_name
booking_contact_email
booking_contact_number
container_size
load_type
shipment_type
number_carton
pallets_quantity
people_for_unload
people_for_receiving
vendor_id
created_at
scheduled_at
status_updated_at
warehouse {
id
legacy_id
}
purchase_orders {
edges {
node {
id
po_number
}
}
}
}
}
}List Inbound Shipments
Use the inbound_shipments query to list inbound shipments with optional filters and cursor-based pagination.
{
inbound_shipments(
statuses: ["arrived", "receiving"]
warehouse_ids: ["V2FyZWhvdXNlOjgwNzU="]
) {
request_id
complexity
data(first: 10) {
edges {
node {
id
legacy_id
account_id
warehouse_id
status
carrier
created_at
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}You can filter by customer_ids, statuses, warehouse_ids, search_term, dates_from, dates_to, estimated_truck_arrival_from, estimated_truck_arrival_to, status_updated_at_from, status_updated_at_to, and require_fai.
Update an Inbound Shipment
Use the inbound_shipment_update mutation to update an existing inbound shipment.
Note
inbound_shipment_update supports a smaller set of fields than inbound_shipment_create. vendor_id, bol_reference, bol_url, expected_dock, dock_used, container_number, notes, scheduled_at, truck_unload_started_at, truck_unload_finished_at, truck_departure_at, people_for_unload, and people_for_receiving can only be set at creation time — they cannot be changed afterwards through the Public API.
mutation {
inbound_shipment_update(
data: {
customer_account_id: "QWNjb3VudDo2NzU="
inbound_shipment_id: "SW5ib3VuZFNoaXBtZW50OjEyMzQ="
warehouse_id: "V2FyZWhvdXNlOjgwNzU="
purchase_orders_ids: ["UHVyY2hhc2VPcmRlcjoxMjM0NQ=="]
carrier: "UPS Freight"
pro_number: "PRO-67890"
estimated_truck_arrival: "2026-08-15T14:00:00Z"
truck_arrived_at: "2026-08-15T14:10:00Z"
booking_contact_name: "Jane Smith"
booking_contact_email: "jane@example.com"
booking_contact_number: "555-987-6543"
container_size: "s20ctr"
load_type: "ltl"
shipment_type: "parcel"
number_carton: 6
pallets_quantity: 2
}
) {
request_id
complexity
inbound_shipment {
id
status
carrier
pro_number
estimated_truck_arrival
truck_arrived_at
booking_contact_name
booking_contact_email
booking_contact_number
container_size
load_type
shipment_type
number_carton
pallets_quantity
}
}
}Note
The purchase_orders_ids field replaces the full list of associated purchase orders — it is the complete desired set, not a delta. If you want to keep existing POs, include them in the list along with any new ones. You cannot remove a purchase order once the shipment is ARRIVED or RECEIVING, and you cannot add one once it’s COMPLETED or DELETED.
As with inbound_shipment_create, container_size, load_type, and shipment_type are sent lowercase and returned uppercase.
Get Inbound Shipment Images
Use the inbound_shipment_images query to retrieve photos attached to an inbound shipment. Each image includes a signed URL for downloading the file.
{
inbound_shipment_images(inbound_shipment_id: "SW5ib3VuZFNoaXBtZW50OjEyMzQ=") {
data {
url
filename
mimetype
description
inbound_shipment_line_item {
id
sku
quantity
quantity_received
quantity_rejected
}
created_at
}
}
}Get Inbound Shipment Summary
Use the inbound_shipment_summary query to get an LPN-based summary of what has been received into an inbound shipment. This shows received inventory grouped by pallet/box.
{
inbound_shipment_summary(inbound_shipment_id: "SW5ib3VuZFNoaXBtZW50OjEyMzQ=") {
data {
stats {
unpalletized_boxes_count
pallets_count
}
in_lpns {
lpn {
id
barcode
container_type
}
quantity_received
quantity_loose
received_location {
id
location
zone
}
content {
product_info {
sku
name
}
lot {
id
name
sku
}
quantity_received
quantity_loose
is_unexpected
containers {
lpn {
id
barcode
container_type
}
quantity_received
}
receiving_location {
id
location
zone
}
receiving_workers {
id
first_name
last_name
}
inbound_shipment_line_item {
id
quantity
quantity_received
quantity_rejected
}
}
}
}
}
}Note
quantity_loose is inventory received but not yet placed into a container/pallet. containers lists any sub-containers (e.g. inner boxes on a pallet) holding this content. receiving_workers requires the view:pii scope — without it, this field returns null rather than an error.
You can optionally filter with only_owned_by_user, only_boxes_non_palletized, filter_by_location_id, lpn_id, and include_rejected.
Get Inbound Shipment Location Summary
Use the inbound_shipment_location_summary query to see where received inventory has been placed, grouped by warehouse location.
{
inbound_shipment_location_summary(inbound_shipment_id: "SW5ib3VuZFNoaXBtZW50OjEyMzQ=") {
data {
locations {
location {
id
location
zone
}
items_at_location {
product_info {
sku
name
}
lot {
id
name
sku
}
eaches_quantity
uom
is_unexpected
inbound_shipment_line_item {
id
quantity
quantity_received
quantity_rejected
}
}
}
}
}
}Note
uom indicates the unit of measure the quantity was recorded in at this location (for example, EACH or CASE), reflecting ShipHero’s unit-of-measure hierarchy for received inventory. lot is only populated for lot-tracked products. is_unexpected indicates the item wasn’t part of the original purchase order/ASN.