PATCH
Update or retire a stock location

Authorizations

Authorization
string
header
required

A secret API key. Publishable keys cannot reach this API. A key may carry an expiry, and an expired key is refused exactly like an unknown one, with a 401 that names no reason; check the key's expires_at in the dashboard rather than inferring it from a response. When a merchant rolls a key's secret they choose a grace window of up to 3 days, and for its duration BOTH the new secret and the one it replaced authenticate, so an integration moves over on its own deploy schedule instead of at the instant the button is pressed. Move before the window closes: after it, the old secret is refused. Nothing else about this contract moves with a roll. The key keeps its id and its scopes, so the only thing an integration updates is the credential itself.

Headers

Idempotency-Key
string
required

A unique key per logical write. Replaying a request with the same key returns the first response byte for byte instead of applying the write twice.

Path Parameters

locationId
string
required

Body

application/json

PATCH rather than the admin surface's PUT, and the method is the contract. That one is a full replace driven by a form that re-sends every field on every save; an integration that computed a partial body against it would blank the warehouse's street, city and phone and get a 200 for it. Here an omitted key keeps its stored value and clearing a column is the explicit act of sending null. THIS IS ALSO THE RETIRE ROUTE, because there is no DELETE on this family: send is_active false and the location stops being somewhere new stock is placed while every level already held there stays readable and resolvable, and one more patch undoes it. A DELETE would cascade every inventory_level at the location away with no restore, which is why the reversible form is the only one published. RETIRING A LOCATION MOVES NO STOCK. The quantities held there are unchanged and still readable at /api/v1/inventory-levels?location_id=, so a client totalling sellable stock must decide for itself whether to count a retired site. No money moves and nothing is emitted: this family registers no webhook topics. AN EMPTY PATCH IS A 400, not a no-op that still bumps updated_at. A client that sent nothing meant to send something. IT CONVERGES: every value is absolute, so replaying the same body with a fresh key past the idempotency window lands the same location in the same state. THE RESPONSE IS THE LOCATION RE-READ THROUGH THE READ PATH, so a cleared column comes back as null rather than as "", and the body is what GET /api/v1/stock-locations/{locationId} serves. A location id that resolves to nothing in this store is a generic 404. stocked_quantity, variant_id, inventory_levels, reserved_quantity, the nested address object, state, region, country and the provenance keys are refused BY NAME, exactly as on the create.

name
string

NOT NULL on the row, so it cannot be cleared: an explicit null is refused, and a present-but-blank value is a 400 naming the key rather than a nameless warehouse. Omit the key to leave it unchanged.

is_active
boolean

false retires the location, true returns it to service. It may not be null, and omitting it leaves the stored value alone.

address_line_1
string | null

ABSENT AND NULL ARE DIFFERENT HERE, which is the whole of the patch contract: an absent key keeps the stored value, an explicit null CLEARS the column, and an empty string clears it the same way, because "" is stored as SQL NULL. All seven address fields behave this way.

address_line_2
string | null
city
string | null
province
string | null
postal_code
string | null
country_code
string | null

The ISO 3166-1 alpha-2 code, stored exactly as sent: nothing upper-cases or lower-cases it, so the read answers the case you wrote.

phone
string | null

Response

Success

data
object