Inventory API

Build with the 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. For information about working with the Catalog API, see the Build a Simple Catalog.

  • Applications using OAuth must have INVENTORY_READ permission to read inventory information and INVENTORY_WRITE permission 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 topic for this product.

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

Information you need Permalink Get a link to this section

To use the steps in this topic, you need:

  • A valid access token. You should test with Sandbox credentials whenever possible. For more information, see Square API Access Tokens.

  • An active location ID. Copy a developer account location ID from the Locations page of your Square application in the Developer Dashboard or set the Developer Dashboard to Sandbox 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 following example code searches for two CatalogItemVariation objects ("Small" and "Medium") under the "Leather collar" CatalogItem.

Note

The following Java example configures the CatalogApi object SDK base URL to the Sandbox environment: 'https://connect.squareupsandbox.com'. In production, do not call setBasePath, so that the SDK uses 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 that two 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 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);

Related topics Permalink Get a link to this section