PUT
Replace the cart-recovery settings

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.

Body

application/json

EVERY KEY IS REQUIRED, including the three that may be null. The save underneath is an upsert of the whole row, so an omitted key is a CLEARED field and not an unchanged one: sending {"enabled": true} alone would blank the sender name and the discount code and zero the cadence. The cadence at least fails loudly; the two strings would blank in silence and the merchant would find out from the next batch of recovery mail, which goes out on a background scan hours later with no request to correlate it to. A missing key is a 400 naming it. Read the settings, edit the document you received, and send it back.

expected_updated_at
string | null
required

The updated_at you last read. Required, because these settings are a singleton written by this route AND by the merchant's dashboard: a write naming no version silently reverts whatever moved under it, answers 200 to both parties, and surfaces only as recovery mail on the old cadence hours later. A mismatch is 409 settings_modified. null asserts that this store has never saved settings, which is the only way a first write can name a version that does not exist, and it is refused once a row does exist.

enabled
boolean
required

The single switch. False and the background scan skips this store entirely, however good the cadence is.

stage1_minutes
integer
required

MINUTES after the cart goes idle for the first recovery email. Read as hours it would mail a shopper sixty times sooner than intended, which is why stage1_hours is refused by name.

stage2_minutes
integer
required

MINUTES after the cart goes idle for the second email. Must be greater than stage1_minutes.

stage3_minutes
integer
required

MINUTES after the cart goes idle for the third email. Must be greater than stage2_minutes. All three must be positive and STRICTLY INCREASING: the scan spaces each stage from the previous SEND, so a gap computed from out-of-order delays is negative and the stage fires immediately after its predecessor.

sender_name
string | null
required

The display name on the recovery email, null to fall back to the store's notification defaults. It is NOT the from address: that lives on the store's notification provider settings, which this family neither reads nor writes, and sender_email is refused by name for that reason.

discount_code
string | null
required

The promotion code the recovery email carries, null for none. One code per store, mailed in plaintext to every abandoning shopper, so it is published on the read as well.

Response

Success

data
object