PUT
Replace the store's flow sending policy

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

An UPSERT behind a PUT: a store with no policy row gets one, a store with one has it replaced whole. EVERY FIELD IS REQUIRED. A dropped respect_quiet_hours would decode to false and switch the store's send window off entirely, which on a store with SMS steps means mailing people in the middle of their night, and it would answer 200. Read GET /api/v1/marketing-flow-settings and send every field back. THE TWO HOURS ARE A SEND WINDOW, NOT A QUIET PERIOD, and reading them backwards is the single likeliest way to blast a list at 3am. Sending is PERMITTED while the recipient's local hour is in [start, end) and deferred otherwise, so the policy "quiet hours 21:00 to 09:00" is the window [9, 21), which is the default. quiet_start_hour and quiet_end_hour are refused by name. expected_updated_at IS REQUIRED and is the other half. This row has several writers, so an integration echoing back what it read ten seconds ago would silently revert the change the merchant just made in their dashboard, with a 200 on both calls. A mismatch is 409 settings_modified: re-read and send the new updated_at. NULL is legal and means "I expect this store to have no settings row yet"; it is refused the moment a row exists, so it cannot be used to opt out of the check. An ABSENT key is 400, because absence asks for the blind overwrite this exists to prevent.

send_window_start_hour
integer
required

Local hour sending becomes permitted, 0 to 23.

send_window_end_hour
integer
required

Local hour sending stops, 0 to 23, exclusive.

respect_quiet_hours
boolean
required

The master switch for the window. False sends whenever a step comes due. The message spine keeps its own statutory floor for marketing SMS regardless, so turning this off widens email rather than defeating that.

enrollment_dedupe_enabled
boolean
required

Applies the per-flow re-enrollment policy. With it off a contact may re-enter as soon as their previous run finished. The one-live-run-per-contact guard is a database index and holds either way.

unknown_tz_mode
enum<string>
required

What happens to a contact whose time zone cannot be resolved. NEITHER VALUE EVER SENDS IMMEDIATELY: us_safe clamps to a window that is daytime across the continental US, store_tz uses the store's own zone, and an unresolvable zone always defers.

Available options:
us_safe,
store_tz
wake_jitter_seconds
integer
required

Spreads a cohort that all finished the same wait at the same instant. Applied forward-only and BEFORE the send-window clamp, so jitter can never push a send back out of the window it was just moved into.

max_steps_per_claim
integer
required

How far one wake may walk a run before yielding, 1 to 500.

max_runs_per_contact_per_day
integer
required

An ENROLLMENT ceiling, which is a different thing from a send ceiling: per-contact send frequency belongs to the message spine's gate, and counting it here as well would double-count and drift out of agreement with it. 0 means unlimited.

expected_updated_at
string<date-time> | null
required

The updated_at you last read. Send null only when you expect this store to have no settings row yet.

Response

Success

data
object