Inventory API

Build with Inventory API

Build a custom integration with Inventory API to manage inventory counts and integrate with 3rd party tracking software.

Backend
Catalog API
Inventory API

Prerequisites and assumptions
Permalink Get a link to this section

To use the Inventory API, the following must be true:

  • You have items defined in your Square product catalog. See the Catalog API Build guide for details on working with the Catalog API.

  • Applications using OAuth must have INVENTORY_READ permission to read inventory information and INVENTORY_WRITE permissions to update inventory states.

  • You are using Square-Version 2018-09-18 or later.


Additionally, this guide makes the following assumptions:

  • You have read the What It Does page for this product.

  • You are familiar with basic web development. If you are new to web development, we recommend reading Getting started with the Web by Mozilla.org before continuing.

Information you will need
Permalink Get a link to this section

To use the steps in this guide you will need the following information:

  • A valid access token. Square recommends testing with sandbox credentials whenever possible. See Square API Access Tokens for more information.

  • An active location ID. Copy a valid Developer Account location ID from the Locations setting page of your Square application in the Developer Dashboard, or set the dashboard to Sandbox Settings mode and then copy a sandbox location ID.

Step 1: Find the relevant catalog items
Permalink Get a link to this section

Look up the CatalogItemVariation IDs you want to modify using the Catalog API. The example code below searches for 2 CatalogItemVariation objects ("Small", "Medium") under the "Leather collar" CatalogItem.

Note

The following Java example configures the CatalogAPI object SDK base URL to the v2 Sandbox (beta) environment - 'https://connect.squareupsandbox.com'. In production, do not call setBasePath, so that the SDK will use the production environment.

// Import classes:
//import com.squareup.connect.ApiClient;
//import com.squareup.connect.ApiException;
//import com.squareup.connect.Configuration;
//import com.squareup.connect.auth.*;
//import com.squareup.connect.api.CatalogApi;


String itemName = "Leather collar"; // Replace with your CatalogItem name
String variation1Name = "Small";  // Replace with your CatalogItemVariation name
String variation2Name = "Medium"; // Replace with your CatalogItemVariation name
String variation1Id = "";
String variation2Id = "";

ApiClient apiClient = Configuration.getDefaultApiClient();
// Set sandbox url
apiClient.setBasePath('https://connect.squareupsandbox.com');

// Configure OAuth2 access token for authorization: oauth2
OAuth oauth2 = (OAuth) apiClient.getAuthentication("oauth2");
// Set your sandbox token
oauth2.setAccessToken("YOUR_SANDBOX_ACCESS_TOKEN");
                
CatalogApi catalogApi = new CatalogApi();

// Search for an Item with the desired name attribute.
SearchCatalogObjectsResponse itemResponse =
    catalogApi.searchCatalogObjects(new SearchCatalogObjectsRequest()
        .addObjectTypesItem(SearchCatalogObjectsRequest.ObjectTypesEnum.ITEM)
        .query(new CatalogQuery()
            .exactQuery(new CatalogQueryExact()
            .attributeName("name")
            .attributeValue(itemName))));

// Retrieve the first returned object, an Item.
CatalogObject item = itemResponse.getObjects().get(0);

// Retrieve the desired ItemVariations from the Item.
List<CatalogObject> variations = item.getItemData().getVariations();
for (CatalogObject variation : variations) {
    String name = variation.getItemVariationData().getName();
    if (variation1Name.equals(name)) {
        variation1Id = variation.getId();
    } else if (variation2Name.equals(name)) {
        variation2Id = variation.getId();
    }
}

Step 2: Add IN_STOCK quantities of your item variations
Permalink Get a link to this section

Create a BatchChangeInventoryRequest with an InventoryAdjustment that moves a quantity of the CatalogItemVariation objects from NONE to IN_STOCK.

String locationId = "YOUR_LOCATION_ID";
// Create an adjustment for 5 units of "small" variation from NONE to IN_STOCK.
InventoryAdjustment addStockAdjustment = new InventoryAdjustment()
    .catalogObjectId(variation1Id)
    .locationId(locationId)
    .fromState(InventoryAdjustment.FromStateEnum.NONE)
    .toState(InventoryAdjustment.ToStateEnum.IN_STOCK)
    .quantity("5");

// Create an adjustment for 7 units of "medium" variation from NONE to IN_STOCK.
InventoryAdjustment damagedStockAdjustment = new InventoryAdjustment()
    .catalogObjectId(variation2Id)
    .locationId(locationId)
    .fromState(InventoryAdjustment.FromStateEnum.NONE)
    .toState(InventoryAdjustment.ToStateEnum.IN_STOCK)
    .quantity("7");

List<InventoryChange> changes = asList(
    new InventoryChange().adjustment(addStockAdjustment),
    new InventoryChange().adjustment(damagedStockAdjustment));

// Construct a request with an idempotency key and a single InventoryChange object.
BatchChangeInventoryRequest addStockRequest = new BatchChangeInventoryRequest()
    .idempotencyKey(UUID.randomUUID().toString())
    .changes(changes);

Step 3: Send the update request
Permalink Get a link to this section

Send the BatchChangeInventoryRequest to the server.

BatchChangeInventoryResponse addStockResponse =
    inventoryApi.batchChangeInventory(addStockRequest);

// Check for errors.
if (!addStockResponse.getErrors().isEmpty()) {
    System.err.println("Error calling BatchChangeInventory: " +
        addStockResponse.getErrors());
    return;
}

// The response contains the quantity following the adjustment.
for (InventoryCount count : addStockResponse.getCounts()) {
    System.out.println("item variation: " + count.getCatalogObjectId());
    System.out.println("  new quantity: " + count.getQuantity());
}

Step 4: Transition a quantity of item variations to a new state
Permalink Get a link to this section

Recording a transition from one state to another works the same way as adding IN_STOCK quantities. For example, to indicate 2 units of variation1Id are no longer suitable for sale and send the BatchChangeInventoryRequest to the server.

// Create an adjustment to move 2 units from state IN_STOCK to WASTE.
InventoryAdjustment wasteAdjustment = new InventoryAdjustment()
    .catalogObjectId(variation1Id)
    .locationId(locationId)
    .fromState(InventoryAdjustment.FromStateEnum.IN_STOCK)
    .toState(InventoryAdjustment.ToStateEnum.WASTE)
    .quantity("2");

InventoryChange wasteChange = new InventoryChange().adjustment(wasteAdjustment);
BatchChangeInventoryRequest wasteRequest = new BatchChangeInventoryRequest()
    .idempotencyKey(UUID.randomUUID().toString())
    .addChangesItem(wasteChange);

BatchChangeInventoryResponse wasteResponse =
    inventoryApi.batchChangeInventory(wasteRequest);

// Check for errors.
if (!wasteResponse.getErrors().isEmpty()) {
    System.err.println("Error calling BatchChangeInventory: " +
        wasteResponse.getErrors());
    return;
}

Step 5: Confirm current quantities
Permalink Get a link to this section

Inventory change requests always return the current quantities of the targeted item variation in each state. You can use this information to determine the number of IN_STOCK units after the adjustment is applied.

Important

If you are processing itemized payments with Square APIs or hardware, item variation quantities are automatically transitioned from IN_STOCK to SOLD. If you are using any other method, you will need to apply the adjustment manually.

// Display IN_STOCK and WASTE quantities.
for (InventoryCount count : wasteResponse.getCounts()) {
    if (count.getState() == InventoryCount.StateEnum.IN_STOCK) {
        System.out.println("In stock: " + count.getQuantity());
    } else if (count.getState() == InventoryCount.StateEnum.WASTE) {
        System.out.println("Waste: " + count.getQuantity());
    }
}

Step 6: Retrieve quantities of multiple item variations
Permalink Get a link to this section

Use the BatchRetrieveInventoryCounts endpoint to retrieve quantities for multiple item variations at once. For example, to request the current counts of all item variations sold through an eCommerce site.

Create a BatchRetrieveInventoryCountsRequest containing the Catalog object IDs of the item variation quantities you want to retrieve and send the BatchRetrieveInventoryCountsRequest to the server. You can also use location IDs to filter the search against specific locations.

BatchRetrieveInventoryCountsRequest countsRequest = new BatchRetrieveInventoryCountsRequest()
    .addLocationIdsItem(locationId1)
    .addLocationIdsItem(locationId2)
    .addCatalogObjectIdsItem(item1VariationToken)
    .addCatalogObjectIdsItem(item2VariationToken);

BatchRetrieveInventoryCountsResponse countsResponse =
    inventoryApi.batchRetrieveInventoryCounts(countsRequest);

Next steps

Now that you have a basic build in place, expand on it with these recipes!