Inventory
If you are using Dynamic Slotting, this section will explain the basic mutations and queries available:
Also, for managing Inventory through our API we have two powerful tools:
Managing Inventory on Dynamic Slotting Accounts
If you are using Dynamic Slotting, you might need to use the following queries & mutations when managing Inventory:
- Location Query
- Locations Query
- Locations list for a specific Product Query
- Create a new Location Mutation
- Update an existing Location Mutation
- Inventory add / Inventory remove Mutations
- Inventory Replace Mutation
Location Query
This query will allow you to get the location’s name
, warehouse_id
or type
by using the location’s id
.
query {
location(id: "QmluOjIyNDMwNDY=") {
request_id
complexity
data {
legacy_id
name
warehouse_id
type {
name
}
}
}
}
You should get something like this:
{
"data": {
"location": {
"request_id": "5f5692457acb6db59e0d556e",
"complexity": 1,
"data": {
"legacy_id": 2243046,
"name": "01PE06CC02",
"warehouse_id": "V2FyZWhvdXNlOjExNzkw",
"type": {
"name": "Bin"
}
}
}
}
}
Locations Query
This query will allow you to navigate through all the locations on a specific warehouse, for example, for warehouse_id = “V2FyZWhvdXNlOjExNzkw” if you try the following query:
query {
locations(warehouse_id: "V2FyZWhvdXNlOjExNzkw") {
request_id
data {
edges {
node {
id
name
zone
type {
name
}
pickable
sellable
}
}
}
}
}
You should get something like this:
{
"data": {
"locations": {
"request_id": "5ecbfee8e0e42dd4a4e13928",
"data": {
"edges": [
{
"node": {
"id": "QmluOjE0OTQxMDg=",
"name": "Bin BO",
"zone": "A",
"type": "Pallet storage",
"pickable": false,
"sellable": false
}
},
{
"node": {
"id": "QmluOjEGehEDg=",
"name": "Bin-A1",
"zone": "A",
"type": "Pallet storage",
"pickable": true,
"sellable": true
}
}]
}
}
}
}
Locations list for a specific Product Query
If you need to get all the existing locations for a specific SKU, you can use the location’s connection on the Product Query, for example, for SKU:“1122334458”
query {
product(sku: "1122334458") {
request_id
data {
sku
name
warehouse_products {
warehouse_id
locations {
edges {
node {
location_id
quantity
}
}
}
}
}
}
}
And the response should be all of its locations on the different warehouses:
{
"data": {
"product": {
"request_id": "5ecc00a2075127485340d212",
"data": {
"sku": "1122334458",
"name": "Test Product 4",
"warehouse_products": [
{
"warehouse_id": "V2FyZWhvdXNlOjExNzkw",
"locations": {
"edges": [
{
"node": {
"location_id": "QmluOjE0OTQxMDg=",
"quantity": 0
}
},
{
"node": {
"location_id": "QmluOjE0OTQxMTM=",
"quantity": 18387
}
}
]
}
}
]
}
}
}
}
Create a new Location Mutation
If you need to create a new Location, you can use the location_create
mutation, for example:
mutation {
location_create(data: {
warehouse_id: "V2FyZWhvdXNlOjExNzkw",
name: "Bin-12345"
zone: "C2"
pickable: false
sellable: false
}) {
request_id
location {
name
zone
type {
name
}
pickable
sellable
}
}
}
Update an existing Location Mutation
You can also edit the settings on an existing location by using the location_update
mutation and using the location_id
, for example:
mutation {
location_update(data: {
location_id: "123BVerb3456jnx"
pickable: true
sellable: true
}) {
request_id
location {
name
zone
type {
name
}
pickable
sellable
}
}
}
Inventory add / Inventory remove Mutations
When removing or adding inventory for a specific SKU on a location, you can use both inventory_add
and inventory_remove
mutations. They both work similar, for example:
mutation {
inventory_add(data: {
sku: "1122334458",
warehouse_id: "V2FyZWhvdXNlOjExNzkw",
location_id: "QmluOjE0OTQxMDg="
quantity: 1
reason: "Test removing inventory from Public API"
}) {
request_id
warehouse_product {
locations {
edges {
node {
location_id
quantity
}
}
}
}
}
}
If you are going to perform this on a 3PL account you should also include the customer_account_id
Inventory Replace Mutation
This mutation works similar to what add or remove does, but it replaces the existing inventory on that location, for example:
mutation {
inventory_replace(data: {
sku: "1122334458",
warehouse_id: "V2FyZWhvdXNlOjExNzkw",
location_id: "QmluOjE0OTQxMDg="
quantity: 5
reason: "Testing replacing inventory from Public API"
includes_non_sellable: False
}) {
request_id
warehouse_product {
locations {
edges {
node {
location_id
quantity
}
}
}
}
}
This action will replace all the inventory for that Location on the Warehouse.
If the action is performed on a 3PL account, customer_account_id
should also be included.
Inventory Sync
In this section, we will explore some examples of how can you use Inventory Sync.
- Inventory sync Mutation
- Inventory sync statuses Query
- Inventory sync status Query
- Inventory sync items status Query
- Inventory sync abort Mutation
Note
For better readability, all of the available fields may not be included in our example queries. To navigate through the Schema and see all of the fields available, please check our Documentation section.
Overview
In this section, we will explore some examples of how you can use the Inventory Sync feature to Sync inventory using a CSV file.
This new Feature resembles the one availabe on our Web App through Inventory Upload.
For these examples, we will follow this flow:
- Upload a CSV file using
inventory_sync
mutation - Check all the
inventory_sync_statuses
by using a query - Check a particular
inventory_sync_status
using a query - Check all the rows of that batch with an
inventory_sync_items_status
query
Inventory sync Mutation
In this example you will use the inventory_sync
Mutation, that allows you to upload inventory:
mutation{
inventory_sync(data:{
url:"https://some-url.com/inv-sync.csv",
warehouse_id:"V2FyZdfhens73hsA="
}){
request_id
complexity
sync_id
}
}
And the response for it should be something like this:
{
"data": {
"inventory_sync": {
"request_id": "5d9624af8f00587f435deb37",
"complexity": 0,
"sync_id": "5d9624b054de070001fd315a"
}
}
}
Important
- Fields that need to be on the CSV file are:
#sku
,quantity
,action
,reason
and in case the account has Dynamic Slotting,location
. - For Dymanic Slotting account, if you don’t include
location
it will be assigned to an unassigned bin. - All SKUs included must be existing SKUs and available on that specific warehouse.
- CSV file also needs to be available for download without any type of credentials needed.
- Only replace is supported for
action
. - CSV file shouldn’t have over 3000 lines to achieve optimal processing performance.
- For an example CSV file, please see:
- Static Slotting Accounts: Download File
- Dynamic Slotting Accounts: Download File
Inventory sync statuses Query
This query allows you to get the status from all the sync batches you have
query {
inventory_sync_statuses {
request_id
complexity
data(first:3) {
edges {
node {
id
url
user_id
account_id
warehouse_id
customer_account_id
total_count
status
error
created_at
updated_at
}
}
}
}
}
And the response should look something like this:
{
"data": {
"inventory_sync_statuses": {
"request_id": "5d9654d6d49dd410acb3f5644",
"complexity": 11,
"data": {
"edges": [
{
"node": {
"id": "5d9624b054de070001fd315",
"url": "https://some-url.com/inv-sync.csv",
"user_id": "VXNlcjo5MTIp",
"account_id": "iWNjb3VudDozODA1",
"warehouse_id": "V2FyZWh3eXNlOjQzNTA=",
"total_count": 3,
"status": "error",
"error": "error in 3 out of 3 rows",
"created_at": "2019-10-03T16:41:20+00:00",
"updated_at": "2019-10-03T16:41:21+00:00"
}
},
{
"node": {
"id": "5d95fc1754de070001fd30a",
"url": "https://some-url2.com/inv-sync.csv",
"user_id": "VXNlcjo5MTIp",
"account_id": "iWNjb3VudDozODA1",
"warehouse_id": "V2FyZWh3eXNlOjQzNTA=",
"total_count": 178,
"status": "error",
"error": "error in 178 out of 178 rows",
"created_at": "2019-10-03T13:48:07+00:00",
"updated_at": "2019-10-03T13:48:14+00:00"
}
},
{
"node": {
"id": "5d95f884f5189700012e690",
"url": "https://some-url.com/inv-sync.csv",
"user_id": "VXNlcjo5MTIp",
"account_id": "QWNjb3VudDozODA1",
"warehouse_id": "V2FyZWhvdXNlOjQzNTA=",
"total_count": 3,
"status": "error",
"error": "error in 3 out of 3 rows",
"created_at": "2019-10-03T13:32:52+00:00",
"updated_at": "2019-10-03T13:32:59+00:00"
}
}
]
}
}
}
}
Inventory sync status Query
This query allows you to get the status of a specific sync batch
query{
inventory_sync_status(id:"5d9624b054de070001fd3132"){
request_id
complexity
data{
id
url
user_id
account_id
warehouse_id
customer_account_id
total_count
status
error
created_at
updated_at
}
}
}
And the response should look something like this:
{
"data": {
"inventory_sync_status": {
"request_id": "5d9624b054de070001fd3132",
"complexity": 1,
"data": {
"id": "5d9b6a3ba1361e00012268ea",
"url": "https://some-url.com/inv-sync.csv",
"user_id": "VXNlcjo5MTIz",
"account_id": "QWNjb3VudDozODAx",
"warehouse_id": "V2FyZWhvdXNlOjY1NDU=",
"customer_account_id": null,
"total_count": 5,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
}
}
}
Inventory sync items status Query
This query allows you to get status for every row inserted from a specific sync batch
query {
inventory_sync_items_status(id: "5d9625ebd49dd410acb3f554") {
request_id
data {
edges {
node {
id
row
sku
quantity
action
reason
location
status
error
created_at
updated_at
}
}
}
}
}
And the response should look something like this:
{
"data": {
"inventory_sync_items_status": {
"request_id": "5d9b6adb2e9fef31169533f8",
"complexity": 101,
"data": {
"edges": [
{
"node": {
"id": "5d9b6a3ba1361e00012268e8",
"row": 1,
"sku": "45933041",
"quantity": 10,
"action": "change",
"reason": "Reason for changing inventory",
"location": null,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
},
{
"node": {
"id": "5d9b6a3ba1361e00012268e8",
"row": 2,
"sku": "46401204",
"quantity": 10,
"action": "change",
"reason": "Reason for changing inventory",
"location": null,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
},
{
"node": {
"id": "5d9b6a3ba1361e00012268e8",
"row": 3,
"sku": "49071335",
"quantity": 10,
"action": "change",
"reason": "Reason for changing inventory",
"location": null,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
},
{
"node": {
"id": "5d9b6a3ba1361e00012268e8",
"row": 4,
"sku": "47028683",
"quantity": 10,
"action": "change",
"reason": "Reason for changing inventory",
"location": null,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
},
{
"node": {
"id": "5d9b6a3ba1361e00012268e8",
"row": 5,
"sku": "48061840",
"quantity": 10,
"action": "change",
"reason": "Reason for changing inventory",
"location": null,
"status": "success",
"error": null,
"created_at": "2019-10-07T16:39:23+00:00",
"updated_at": "2019-10-07T16:39:24+00:00"
}
}
]
}
}
}
}
Inventory sync abort Mutation
This mutation allows you to abort a specific sync batch that was uploaded. Aborting a sync batch should be done before the batch is changed to a success status, and will not revert the lines already processed from the CSV file.
mutation {
inventory_sync_abort(
data: { sync_id: "5e4dac71b50fb5475c7b00d4", reason: "Wrong File" }
) {
request_id
complexity
sync {
id
url
user_id
account_id
warehouse_id
customer_account_id
total_count
status
error
created_at
updated_at
success_count
error_count
finished_count
}
}
}
Inventory Snapshot
In this section, we will explore some examples of how we can use the Inventory snapshot.
- Inventory generate snapshot Mutation
- Inventory abort snapshot Mutation
- Inventory snapshot Query
- Inventory snapshots Query
Overview
A snapshot is just an asynchronous job that iterates over all warehouses that satisfy the criteria (owned or associated with a 3PL relationship), then iterates over all products in each warehouse that meet the criteria and aggregates vendors+bins+lots for each product, and throws all of that info into a big map of products to vendors, warehouses, and lots for each in JSON format.
When it finishes, it can send an email or post to an endpoint. This email or webhook will contain a link to the exported JSON file, which will be available for download for 24 hours.
To get either of the above, you must pass the notification_email or post_url fields respectively. Please ensure you are passing a valid email and/or endpoint URL that accepts POST messages.
We also offer a data export option that may be better suited for your needs. Reach out to support for more information.
Examples of how the snapshot should look like are:
Important
Requesting a full snapshot of all products from all warehouses is not recommended, and the request may not succeed for accounts with high SKU and warehouse counts.
To limit the size of the snapshot, use one of the following filters:
warehouse_id
to get results for a specific warehouse.customer_account_id
to receive only SKUs for a specific customer account if you trigger the snapshot as a 3PL account.has_inventory
to return only SKUs that have stock.updated_from
to retrieve only SKUs that have been updated since the specified date-time (in UTC).
Inventory generate snapshot Mutation
In this example we will use the inventory_generate_snapshot
Mutation, that allows us to generate a snapshot:
mutation {
inventory_generate_snapshot(
data: {
warehouse_id: "V2FyZWhvuXNlOjEjUzkw"
notification_email: "test@shiphero.com"
}
) {
request_id
complexity
snapshot {
snapshot_id
job_user_id
job_account_id
warehouse_id
customer_account_id
notification_email
email_error
post_url
post_error
post_url_pre_check
status
error
created_at
enqueued_at
updated_at
snapshot_url
snapshot_expiration
}
}
}
And the response for it should be something like this:
{
"data": {
"inventory_generate_snapshot": {
"request_id": "5e70d213fa462c9432d1a383",
"complexity": 30,
"snapshot": {
"snapshot_id": "5e70d213ec6c5e62d4bf7170",
"job_user_id": "VXNlcjo5MTIz",
"job_account_id": "QWNjb3VudDo2MzM0",
"warehouse_id": "V2FyZWhvuXNlOjEjUzkw",
"customer_account_id": null,
"notification_email": "test@shiphero.com",
"email_error": null,
"post_url": null,
"post_error": null,
"post_url_pre_check": true,
"status": "enqueued",
"error": null,
"created_at": "2020-03-17T13:35:15+00:00",
"enqueued_at": "2020-03-17T13:35:15.815864+00:00",
"updated_at": "2020-03-17T13:35:15+00:00",
"snapshot_url": null,
"snapshot_expiration": null
}
}
}
}
Inventory abort snapshot Mutation
If you would like to abort a snapshot that is being generated, you can use the inventory_abort_snapshot
Mutation, that allows us to abort a specific snapshot, this is:
mutation {
inventory_abort_snapshot(
data: { snapshot_id: "5e94c048cec17923fcb7ec32", reason: "Wrong endpoint" }
) {
request_id
complexity
snapshot {
snapshot_id
job_user_id
job_account_id
warehouse_id
customer_account_id
notification_email
email_error
post_url
post_error
post_url_pre_check
status
error
created_at
enqueued_at
updated_at
snapshot_url
snapshot_expiration
}
}
}
Note
Snapshots can also be posted to a specific URL. In order to do this, you have to include two fields:
post_url
: “https://testendpoint.net/"post_url_pre_check
: false
As for post_url_pre_check
, if false, a pre-check on the POST URL will not be performed. This eliminates immediate validation and feedback in the mutation response, before sending the request to the worker. Nonetheless, disabling this check can be useful if a one-time token is used to authenticate the endpoint.
Inventory snapshot Query
This query allows us to get the status for a specific snapshot
query {
inventory_snapshot(snapshot_id: "5e94c048cec17923fcb7ec32") {
request_id
complexity
snapshot {
snapshot_id
job_user_id
job_account_id
warehouse_id
customer_account_id
notification_email
email_error
post_url
post_error
post_url_pre_check
status
error
created_at
enqueued_at
updated_at
snapshot_url
snapshot_expiration
}
}
}
And the response should look something like this:
{
"data": {
"inventory_snapshot": {
"request_id": "5e94c1d95dd8b16bf28392a9",
"complexity": 1,
"snapshot": {
"snapshot_id": "5e94c048cec17923fcb7ec32",
"job_user_id": "VXNlcjo5MTIz",
"job_account_id": "QWNjb3VudDozODAx",
"warehouse_id": "V2FyZWhvdXNlOjgwNzU=",
"customer_account_id": null,
"notification_email": "test@shiphero.com",
"email_error": null,
"post_url": null,
"post_error": null,
"post_url_pre_check": true,
"status": "success",
"error": null,
"created_at": "2020-04-13T19:40:56+00:00",
"enqueued_at": "2020-04-13T19:40:56.912000+00:00",
"updated_at": "2020-04-13T19:40:57+00:00",
"snapshot_url": "https://shiphero-uploads.s3.amazonaws.com/inventory_snapshots/3801/8075/Any/b24278f6-7dbe-11ea-9903-0af9fd70a979.json",
"snapshot_expiration": null
}
}
}
}
Inventory snapshots Query
This query allows us to get the status of all the snapshots for a specific warehouse or customer
query {
inventory_snapshots(warehouse_id: "V2FyZWhvdXNlOjgwNzU=") {
request_id
complexity
snapshots(first: 1) {
edges {
node {
snapshot_id
job_user_id
job_account_id
warehouse_id
customer_account_id
notification_email
email_error
post_url
post_error
post_url_pre_check
status
error
created_at
enqueued_at
updated_at
snapshot_url
snapshot_expiration
}
}
}
}
}
And the response should look something like this:
{
"data": {
"inventory_snapshots": {
"request_id": "5e94c0c401117d1e2b1a822c",
"complexity": 11,
"snapshots": {
"edges": [
{
"node": {
"snapshot_id": "5e94c048cec17923fcb7ec32",
"job_user_id": "VXNlcjo5MTIz",
"job_account_id": "QWNjb3VudDozODAx",
"warehouse_id": "V2FyZWhvdXNlOjgwNzU=",
"customer_account_id": null,
"notification_email": "test@shiphero.com",
"email_error": null,
"post_url": null,
"post_error": null,
"post_url_pre_check": true,
"status": "success",
"error": null,
"created_at": "2020-04-13T19:40:56+00:00",
"enqueued_at": "2020-04-13T19:40:56.912000+00:00",
"updated_at": "2020-04-13T19:40:57+00:00",
"snapshot_url": "https://shiphero-uploads.s3.amazonaws.com/inventory_snapshots/3801/8075/Any/b24278f6-7dbe-11ea-9903-0af9fd70a979.json",
"snapshot_expiration": null
}
}
]
}
}
}
}