Inventory Adjustment Reasons

Learn how to categorize inventory adjustments with standard and custom adjustment reasons and filter inventory change history by reason.

Applies to: Inventory API

Link to section

Overview

Adjustment reasons let applications record why an inventory quantity changed, using the same set of reasons that sellers see in the Square Dashboard and Square Point of Sale. Every InventoryAdjustment can carry a reason_id that identifies a standard reason provided by Square (such as DAMAGED or RECEIVED) or a custom reason defined by the seller (such as "Donated to charity").

With adjustment reasons, your application can:

  • Write adjustments with a reason, so they're categorized consistently with first-party Square products.
  • Manage the seller's custom adjustment reasons (create, update, delete, and restore).
  • Filter the inventory change history by one or more reasons.
Link to section

Reason identifiers

A reason is identified by an InventoryAdjustmentReasonId object rather than a single ID string, in order to support predefined reason codes alongside the seller's custom reasons:

  • Standard and system-generated reasons are identified by type alone - for example, { "type": "DAMAGED" }.
  • Custom reasons use type CUSTOM plus the seller-specific custom_reason_id - for example, { "type": "CUSTOM", "custom_reason_id": "R5BX3PDCZ6EXAMPLE" }.

The full InventoryAdjustmentReason resource adds a name (custom reasons only), a direction (INCREASE or DECREASE), timestamps, and an is_deleted flag.

Link to section

Standard reasons

Standard reasons are predefined by Square, available to every seller, and can be written on adjustments by your application. Each standard reason implies a direction:

Reason typeDirection
RECEIVEDINCREASE
RETURNEDINCREASE
DAMAGEDDECREASE
THEFTDECREASE
LOSTDECREASE
SPOILAGE_WASTEDECREASE
SAMPLES_PROMOTIONALDECREASE
INTERNAL_USEDECREASE
VENDOR_RETURNDECREASE
PRODUCTION_WASTEDECREASE
Link to section

System-generated reasons

Some reasons are only ever attached to adjustments generated by Square products and cannot be written by your application: SALE, RECOUNT, TRANSFER, IN_TRANSIT, and CANCELED_SALE. You might encounter them when reading the change history. By default, they're omitted from ListInventoryAdjustmentReasons results; pass include_system_codes=true to include them.

Link to section

Custom reasons

Sellers (and your application, on their behalf) can define custom reasons with a name of up to 50 characters and a direction. Deleting a custom reason is a soft delete: historical adjustments keep referencing it, deleted reasons can still be retrieved by ID, and a deleted reason can be brought back with RestoreInventoryAdjustmentReason.

Link to section

Endpoints

EndpointRoutePermission
ListInventoryAdjustmentReasonsGET /v2/inventory/adjustment-reasonsINVENTORY_READ
RetrieveInventoryAdjustmentReasonPOST /v2/inventory/adjustment-reasons/retrieveINVENTORY_READ
CreateInventoryAdjustmentReasonPOST /v2/inventory/adjustment-reasons/createINVENTORY_WRITE
UpdateInventoryAdjustmentReasonPUT /v2/inventory/adjustment-reasons/updateINVENTORY_WRITE
DeleteInventoryAdjustmentReasonPOST /v2/inventory/adjustment-reasons/deleteINVENTORY_WRITE
RestoreInventoryAdjustmentReasonPOST /v2/inventory/adjustment-reasons/restoreINVENTORY_WRITE
Link to section

List the available reasons

The following example lists the reasons available to the seller. The response contains the standard reasons and the seller's custom reasons. Include deleted custom reasons with include_deleted=true, and system-generated reasons with include_system_codes=true.

curl https://connect.squareup.com/v2/inventory/adjustment-reasons \ -H 'Square-Version: 2026-07-15' \ -H 'Authorization: Bearer {ACCESS_TOKEN}' \ -H 'Content-Type: application/json'
Link to section

Create a custom reason

Provide an idempotency key and the reason's id, name, and direction. The id must have type CUSTOM and omit custom_reason_id - Square assigns the ID and returns it in the response.

curl https://connect.squareup.com/v2/inventory/adjustment-reasons/create \ -X POST \ -H 'Square-Version: 2026-07-15' \ -H 'Authorization: Bearer {ACCESS_TOKEN}' \ -H 'Content-Type: application/json' \ -d '{ "idempotency_key": "0e485885-fabc-43cc-ae63-2d3666dc0f27", "adjustment_reason": { "id": { "type": "CUSTOM" }, "name": "Donated to charity", "direction": "DECREASE" } }'

Only the name of an existing custom reason can be changed later (with UpdateInventoryAdjustmentReason, passing the reason's full id in adjustment_reason alongside the new name). The direction is fixed at creation because historical adjustments already recorded with the reason rely on it. Standard and system-generated reasons cannot be modified.

Link to section

Write an adjustment with a reason

Set reason_id on the adjustment in a BatchChangeInventory request. The reason's direction must match the state transition - for example, a DECREASE reason like DAMAGED pairs with a transition out of IN_STOCK, such as IN_STOCK to WASTE.

To use a custom reason instead, pass its full identifier. Custom reasons apply to plain stock increases and decreases: an INCREASE custom reason pairs with a NONE to IN_STOCK transition, and a DECREASE custom reason pairs with IN_STOCK to NONE. For example, the following change removes 3 units using a seller-defined reason:

{ "type": "ADJUSTMENT", "adjustment": { "catalog_object_id": "6F4K33KPNUVDWKZ43KUIFH6K", "from_state": "IN_STOCK", "to_state": "NONE", "from_location_id": "EF6D9SACKWBKZ", "to_location_id": "EF6D9SACKWBKZ", "quantity": "3", "occurred_at": "2026-07-16T14:25:00.000Z", "reason_id": { "type": "CUSTOM", "custom_reason_id": "R5BX3PDCZ6EXAMPLE" } } }

You can also change the reason on a past adjustment with UpdateInventoryAdjustment - see Update a past adjustment. The same validity rules apply, and the reason of a system-generated adjustment can't be changed.

Link to section

Filter the change history by reason

BatchRetrieveInventoryChanges accepts a reason_ids filter that returns only adjustments recorded with one of the given reasons.

curl https://connect.squareup.com/v2/inventory/changes/batch-retrieve \ -X POST \ -H 'Square-Version: 2026-07-15' \ -H 'Authorization: Bearer {ACCESS_TOKEN}' \ -H 'Content-Type: application/json' \ -d '{ "catalog_object_ids": ["6F4K33KPNUVDWKZ43KUIFH6K"], "types": ["ADJUSTMENT"], "reason_ids": [ { "type": "DAMAGED" }, { "type": "CUSTOM", "custom_reason_id": "R5BX3PDCZ6EXAMPLE" } ] }'

Important

The reason_ids filter cannot be combined with the states filter in the same request.

Link to section

Delete and restore custom reasons

Deleting a custom reason hides it from sellers and from default ListInventoryAdjustmentReasons results, but doesn't remove it from adjustments that already reference it.

curl https://connect.squareup.com/v2/inventory/adjustment-reasons/delete \ -X POST \ -H 'Square-Version: 2026-07-15' \ -H 'Authorization: Bearer {ACCESS_TOKEN}' \ -H 'Content-Type: application/json' \ -d '{ "reason_id": { "type": "CUSTOM", "custom_reason_id": "R5BX3PDCZ6EXAMPLE" } }'

Restore a deleted reason with the same request body sent to POST /v2/inventory/adjustment-reasons/restore. A deleted reason cannot be updated until it's restored.