arvato Inventory Service

The arvato Advanced Inventory Service provides a single view across retailer’s entire inventory. With this insight merchants can manage and utilize their inventory more efficiently, saving costs and opening up new revenue streams. Eliminate out-of-stocks by shipping from store and offer a seamless experience between online and in-store to your customers.

Arvato’s highly scalable cloud solution provides an API that enables integration with all sorts of inventory sources, including legacy back-end systems and in-store item data. The API can then be used to power online checkout processes and in-store experiences.

Overview

The arvato Inventory Service provides the ability to manage and monitor stock items and transactions. It can be integrated into your checkout process to check the availability of products and improve your customer's omnichannel experience. Connect all of your stock and item level sources to get a single view across your entire inventory. Get realtime information about RFID tagged products and IoT devices.

The service provides retailers with inventory accuracy and visibility necessary to explore new ways to engage and inform consumers online and in physical stores. For example, sales representatives can easily locate the right size, shape, color, etc. of a product by using a phone or tablet or provide customers with self-service tools. The arvato Inventory Service can also help to find misplaced items and to investigate lost items. Accurate inventory has direct impact on revenue. Out-of-stock situations can be avoided and less safety stock levels means less markdown pricing.

Online consumers have an accurate view of inventory. This improves customer satisfaction and the omnichannel experience, for example by enabling ship-from-store and buy-online-pickup-in-store functionality.

The highly scalable API includes:

  • Inventory source management
    • Connect inventory sources such as ERP systems, warehouses and retail stores.
    • Configure online inventory sources to manage stock levels directly via the API or user interface.
  • Stock item management
    • Create, lookup, update and delete stocks
    • Create, lookup and update EPC items based on RFID tags.
    • Calculate product availability (for ATP checks, etc.)
  • Inventory transactions
    • Reserve a specified quantity
    • Commit a specified quantity
    • Release a specified quantity
  • Transaction history

Concepts

Source: For the inventory service a source simply means a logical grouping of items. Whether it represents a real physical source or a digital store, is not relevant here. It's important to note that a stock keeping unit must be unique within one source. Both stock and source identifiers are case insensitive.

Stock Keeping Unit (SKU): Unique identifier of a warehousing item. This often represents a product with unique characteristics (such as brand, color and size). A SKU has to be unique per source. It is case insensitive.

Stock: One stock item keeps track of quantities for a single SKU in a single source.

Quantity onHand: The total number units of a SKU that is available in the source at the current time. From a source perspective this usually means it includes items that are already allocated for other needs (pending orders, etc.). From an OMS perspective this might represent the quantity that is available to sell via this service. In this case it should exclude items already allocated by other systems. (See section "Use Cases" below for more information on this topic.)

Quantity reserved: Quantity allocated for fulfilling a pending order.

Quantity available: Represents the total number of units that is available for sale. In other words, it is the On Hand Quantity minus Pending Quantity.

Transaction: An inventory transaction modifies the quantity of a stock item. The following transactions are currently supported:

  • CREATE: Creates a new stock item with the specified initial quantity on hand.
  • UPDATE: Updates the quantity on hand for an existing stock item.
  • RESERVE: Increases the quantity reserved and decreases the quantity available.
  • RELEASE: Decreases the quantity reserved and increases the quantity available.
  • COMMIT: Decreases the quantity reserved and decreases the quantity on hand.

Transaction history: The service provides an optional feature to keep records of inventory transactions. This can be used for auditing or to understand the history of quantities.

Transactions

The following diagram shows examples of a single stock item and how different transactions affect its quantities.

Inventory transaction examples

  1. The stock item is created with an initial quantity of 10.
  2. An attempt is made to reserve 11 units, but only 10 are available. This will result in an error and the request is not fulfilled.
  3. Three units are reserved. This reduces the amount available to 7.
  4. The previously reserved units are committed. This clears the reserved counter and reduces the on hand quantity.
  5. This is an alternative where we release 2 of the 3 previously reserved units. The amount available is now 9.
  6. This is an edge case where an attempt is made to commit 4 units, but only 3 were reserved. The inventory service will reduce the amount on hand by 4, however, it will set the amount of reserved units to 0 to avoid a negative value. A warning is also returned.
  7. An attempt is made to release 4 units. However, only 3 were previously reserved. This will cause an error.
  8. The quantity on hand is updated to 2, but we already have 3 units reserved. This will cause a warning, but the quantity on hand is still updated to 2. The quantity available is set to 0 to avoid any negative values.
  9. Similar to 6.: Even if more units are committed than what was reserved and is available on hand, it will still succeed and the counters will be set to 0 to avoid any negative values.

Common integration scenarios

The inventory service is flexible to be used in many scenarios. If you have a specific use case that you would like to discuss with us, please get in contact and one of our solution architects will be looking forward to support you with your integration needs.

The following section describes the most common use cases.

Online store (eStore) to Order Management System (OMS)

A very common scenario is to integrate an order management system with an online store. Especially legacy order management systems are often not designed to handle the demand and high availability requirements of an online store. Here, the inventory service can act as a buffer between the high volume online store and an OMS which is more used to handling batches.

eStore, inventory service and OMS overview

The online shop (on the left) interacts with the inventory service by checking, reserving, committing and releasing stock items. These are usually live transactions.

The order management system (on the right) is responsible for creating stock items and updating their quantity on hand. This usually happens in batch operations.

Sometimes the OMS might know about other systems that manipulate inventory (for example orders taken by phone that are not placed in the eshop). In this case the OMS should set the quantity on hand of the inventory service to the quantity available instead (quantity on hand minus reserved orders from other systems).

The following sequence diagram shows a typical integration. This is just an example. Your integration could look different depending on your use case. If you would like to discuss your use case with us, please contact us.

eStore, inventory service OMS sequence

  1. The order management system (or the source management system) sends stock items in batches. In this example we assume a single SKU with a total available quantity of 10.
  2. The consumer adds 2 units to the shopping cart. The eshop then checks with the inventory service whether there is enough stock to fulfill this request.
  3. If there's enough stock available, the consumer proceeds to checkout. Just before the order is placed, the inventory service is invoked to reserve 2 units. This will make it unavailable for other consumers to purchase.
  4. After the order is placed, there might be a grace period during which the consumer can cancel the order. If the order is fine and ready for fulfillment, the eshop sends it over to the OMS for fulfillment. At the same time the inventory service is invoked to commit the previously reserved quantity. This will remove the amount reserved and decrease the quantity on hand. Subsequent updates from the OMS should take this into consideration and exclude such orders from the qty on hand update.

Accessing the API

Endpoint

Production

The following endpoint is the base for all live transactions:

Base URL for this endpoint is: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}

RAML specification: https://api.yaas.io/arvato/inventory/v1/public/api/api.raml

Test

The TEST endpoint can be used to try out and verify your integration with our API. New features will be released to this environment first. We promote consumer-based testing and encourage you write contract tests that you can verify against this endpoint.

The base URL for this endpoint is: https://api.yaas.io/arvato/inventory/test/tenants/{tenant}

RAML specification: https://api.yaas.io/arvato/inventory/test/public/api/api.raml

Please note: The TEST environment is also where we beta test new features. It has limited availability and is less stable than the production environment. There is no uptime guarantee either.

Authentication and Authorization

All API calls are secured by access tokens. Please refer to the general guide about how to retrieve access tokens.

Required subscriptions

No subscription to other services is required.

Scopes

At the moment no specific scope is required when requesting access tokens; a subscription to the service is enough.

Stock Management API

The following sections contain examples how to manage stock items. Please find the complete API specification at the bottom of this page.

Create single stock item

The following example shows how to create a single stock item.

Request

  • Method: POST
  • URL: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/{source}/stocks
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: Your source id
  • Body:
{
  "sku": "product1",
  "onHand": 100
}
Example
curl -X POST -H "Authorization: Bearer {token}" -H "Accept: application/json" -H "Content-Type: application/json" -d '{
  "sku": "product1",
  "onHand": 100
}' https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1/stocks

Response

  • Status Code: 201
  • Headers:
    • location: https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/wh1/stocks/product1

Retrieve a single stock item

The following example shows how to GET stock information of a specific source and sku.

You can optionally send the requested parameter. If the parameter is present, then the inventory service will perform a check against the amount available. If the amount available is less than the amount requested, a 409 error response is returned. A common use case is to perform this check when adding a product to the shopping cart and reject the action if there's not enough inventory.

If you do not specify the requested parameter, then a snapshot of the the stock item is returned.

Request:

  • Method: GET
  • URL: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/{source}/stocks/{sku}
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: Your source id
      • sku: product1
  • Query Parameters:
    • requested: 10
Example
curl -X GET -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1/stocks/product1?requested=10

Response

  • Status Code: 200
Example
{
  "sourceId": "wh1",
  "sku": "product1",
  "onHand": 100,
  "reserved": 22,
  "available": 78
}

Retrieve all stock items for a source.

You can also retrieve an array of stock items for a given source. The result set is usually limited and header values in the response can be used for pagination.

Request:

  • Method: GET
  • URL: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/{source}/stocks
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: Your source id
  • Query Parameters:
    • limit: 5
Example
curl -X GET -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1/stocks?limit=5

Response

  • Status Code: 200
  • Headers:
    • next: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1/stocks?limit=5&start=productF
Example
[
    {
        "sourceId": "wh1",
        "sku": "product1",
        "onHand": 1000,
        "reserved": 100,
        "available": 900
    },
    {
        "sourceId": "wh1",
        "sku": "product2",
        "onHand": 10,
        "reserved": 0,
        "available": 10
    },
    {
        "sourceId": "wh1",
        "sku": "product3",
        "onHand": 20,
        "reserved": 20,
        "available": 0
    },
    {
        "sourceId": "wh1",
        "sku": "product4",
        "onHand": 0,
        "reserved": 0,
        "available": 0
    },
    {
        "sourceId": "wh1",
        "sku": "product5",
        "onHand": 20,
        "reserved": 1,
        "available": 19
    },
    {
        "sourceId": "wh1",
        "sku": "product6",
        "onHand": 1000,
        "reserved": 0,
        "available": 1000
    }
]

Delete stock

The following example shows how to delete a single stock item.

Request

  • Method: DELETE
  • URL: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/{source}/stocks/{sku}
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: Your source id
      • sku: product1

Example

curl -X DELETE -H "Authorization: Bearer {token}" -H "Accept: application/json" -H "Cache-Control: no-cache" -d https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1/stocks/product1

Response

  • Status Code: 204

Delete stocks for a source

You can also delete all stocks for a specific source:

Request

  • Method: DELETE
  • URL: https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/{source}
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: wh1
Example
curl -X DELETE -H "Authorization: Bearer {token}" -H "Accept: application/json" -H "Cache-Control: no-cache" -d https://api.yaas.io/arvato/inventory/v1/tenants/{tenant}/sources/wh1

Response

  • Status Code: 204

Update stock

To update the quantity on hand of existing stock items you can either use a batch operation or an update transaction. Both are explained in the sections further below. It's not possible to change the sku attribute. You can however delete the stock item with the current sku and then create a new stock item with the new sku.

Batch operations

Multiple stocks can be created or updated in batches.

Create or update multiple stocks

The following example shows how to create or update existing stocks for a given source. A new stock item will be created if it doesn't exist yet. Otherwise the quantity on hand of the existing stock item is update.

Request

  • Method: POST
  • URL: https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/{source}/batches/stocks
  • Path Parameters:
    • tenant: Your tenant identifier
      • source: default
Example
curl -X POST -H "Authorization: Bearer {token}" -H "Accept: application/json" -H "Cache-Control: no-cache" -d '[
    {
      "sku": "product2",
      "onHand": 100
    },
    {
      "sku": "product3",
      "onHand": 50
    }
]' https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/wh1/batches/stocks

Response

  • Status Code: 201
Example
[
    {
        "status": 201,
        "type": "successfull",
        "moreInfo": "http://localhost:8080/sources/whA/stocks/product2",
        "id": "product2"
    },
    {
        "status": 400,
        "type": "client_error",
        "message": "Constraint violation",
        "id": "product5"
    },
    {
        "status": 200,
        "message": "successfull",
        "moreInfo": "http://localhost:8080/sources/whA/stocks/product3",
        "id": "product3"
    }
]

Transactions API

Create stock transactions

Execute stock transactions and create stock histories for the execution action. See the following examples to see a successful and an insufficient stock error:

Request

  • Method: POST
  • URL: https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/{source}/stocks/{sku}/transactions
  • Body:
    • type: "CREATE, "UPDATE", RESERVE", "RELEASE" or "COMMIT"
    • quantity: the quantity (Number)
    • description: an optional description of this transaction (for example the system or person that triggered it)
Example
curl -X POST -H "Authorization: Bearer {token}" -H "Accept: application/json" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
   "type": "RESERVE",
   "quantity": "2",
   "description": "customer reserve"
}' https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/wh1/stocks/product1/transactions

Response

  • Status Code: 200
Example
{
  "status": 200,
  "type": "successful",
  "message": "OK",
  "id": "mzy7"
}

Response

  • Status Code: 409 (Insufficient stock)
Example
{
    "status": 409,
    "type": "insufficient_stock_violation",
    "message": "Available amount (10) is less than requested amount (11)",
    "details": [
        {
            "message": "error.message.insufficientstockavailable",
            "values": {
                "available": 10,
                "requested": 11
            }
        }
    ]
}

Getting transactions history

The following request retrieves the stock histories for the specified sku in specified source:

Request

  • Method: GET
  • URL: https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/wh1/stocks/product1/transactions
Example
curl -X GET -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d https://api.yaas.io/arvato/inventory/v1/{tenant}/sources/wh1/stocks/product1/transactions

Response

  • Status Code: 200
Example
[
    {
        "id": "mzy7",
        "sourceId": "wh1",
        "sku": "product1",
        "type": "CREATE",
        "onHand": 100,
        "reserved": 0,
        "available": 100,
        "time": "2015-08-18T16:43:03.391+0000"
    },
    {
        "id": "2k0u",
        "sourceId": "wh1",
        "sku": "product2",
        "type": "UPDATE",
        "onHand": 100,
        "reserved": 0,
        "available": 100,
        "time": "2015-08-18T16:43:03.828+0000"
    },
    {
        "id": "TdiR",
        "sourceId": "wh1",
        "sku": "product3",
        "type": "RESERVE",
        "onHand": 100,
        "reserved": 2,
        "available": 98,
        "description": "customer reserve",
        "time": "2015-08-18T16:43:04.019+0000"
    }
]