Cancel an exchange
Authorizations
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
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
Body
Takes no parameters, and an empty body is expected. THIS FAMILY'S DELETE: there is no DELETE route and there will not be one, because cancelling leaves the row, both item sides and the stamps exactly where a chargeback dispute six months later needs to find them. canceled_at is stamped the first time the exchange enters cancelled and is never rewritten. LEGAL FROM requested, approved AND received, which is wider than approve's single source state, because an exchange can be called off at any point before the replacement ships. From shipped, or from cancelled again, it answers 409 invalid_transition, so a second cancel does not answer 200. NO MONEY MOVES, whatever difference_total_minor says. That figure is a snapshot taken when the exchange was opened and it settles on SHIP, which this API does not publish, so nothing is charged to the customer and nothing is refunded here. CANCELLING AFTER RECEIPT DOES NOT UNDO THE RESTOCK. Receiving an exchange puts the inbound goods back into stock; cancelling afterwards flips the status and leaves that stock exactly where it is. Move it again through the inventory api if it is not staying on the shelf. THE BODY IS READ ONLY TO REFUSE IT, against the same list the approve route uses. cancel_reason is the key an integrator reaches for first and it is refused BY NAME, because the exchange row has no column for prose: a reason sent here would be dropped while the 200 read as though it had been recorded. refund, refund_to and amount are refused because cancelling moves no money, restock and location_id because stock is write_inventory's authority, status because the route in the url is the transition, and the provenance keys (id, store_id, order_id, created_by, canceled_at, created_at, updated_at) because the server owns them. The response is the WHOLE exchange in the shape GET /api/v1/exchanges/{exchangeId} serves.
Response
Success
