Settings API

Last updated: May 12, 2026

Get Settings

GET /api/v1/store/review-settings

{
  "settings": {
    "collection_enabled": false,
    "default_experience": "chat",
    "auto_moderation_preset": "manual",
    "review_request_trigger": "fulfilled",
    "review_request_delay_days": 7,
    "review_request_delivery_fallback_days": 14,
    "request_token_expiry_days": 90,
    "digest_enabled": false,
    "digest_recipient_email": null
  }
}

Update Settings

PUT /api/v1/store/review-settings

Pass only the settings you want to change.

{
  "settings": {
    "default_experience": "chat",
    "auto_moderation_preset": "balanced",
    "digest_enabled": true
  }
}

Four keys are NOT settable via this endpoint

collection_enabled, review_request_trigger, review_request_delay_days, and require_marketing_consent are rejected with HTTP 422 error: "unknown_settings_key". The cohort cascades those keys trigger (Shopify pagination, audit, warmup provisioning, consent-gate cancellation) need the dry-run-confirm flow the embedded admin extension owns.

{
  "error": "unknown_settings_key",
  "key": "collection_enabled",
  "message": "`collection_enabled` cannot be set via this endpoint — use the merchant admin UI (or the admin-ext `/api/admin-ext/collection/*` routes if integrating directly)."
}

Partner-API integrations that need to flip these keys: route the flip through the admin extension on the merchant's behalf. Reading them via the GET above is fine.


GET /api/admin-ext/collection/consent-metrics (admin-ext, JWT-auth required)

Returns the cached daily-cron metric of the merchant's recent-customer marketing-consent distribution — used by the Collect → Request audience UI to render a badge next to the Require marketing consent toggle. Computed by ConsentRateMetricFanOutWorker at 04:30 UTC daily; queries Shopify's customers(first: 250, query: "created_at:>=<30d>") per store and writes the result into review_settings. The endpoint NEVER triggers a fresh fetch on read — it returns whatever the daily worker last cached.

{
  "consent_rate_pct": 23.5,
  "sample_size": 100,
  "subscribed_count": 24,
  "cached_at": "2026-06-03T04:30:00Z"
}

All four fields can be null when the worker has not yet populated the cache for the store (brand-new install, worker disabled, prior days of failures). The UI handles null as "no data yet" rather than rendering 0%.


Setting Reference

SettingTypeDefaultDescription
collection_enabledbooleanfalseRead-only via this PUT (422 on write). When true, the configured Shopify order event automatically creates review requests. Set via the merchant admin UI / admin-ext /collection/{enable,disable} only — the cohort cascade requires the dry-run-confirm flow.
default_experiencestring"chat"chat (AI-guided conversation) or form (simple star + text).
auto_moderation_presetstring"manual"Controls automatic review publishing. "manual" requires merchant approval for all reviews. Other values — "open", "relaxed", "balanced", "careful" — publish reviews that score above a preset threshold. Spam, abuse, and complaint reviews always require manual review regardless of preset. Changing this from "manual" to a non-manual preset triggers retroactive scoring of the BR-collected (platform IN ('direct','public')) pending backlog; imports are excluded.
review_request_triggerstring"fulfilled"Read-only via this PUT (422 on write). Event that starts the send countdown: "created", "paid", "fulfilled", or "delivered". Set via the merchant admin UI / admin-ext /collection/config-change only — the cascade (cancel-in-flight vs in-place reschedule) requires the dry-run-confirm flow.
review_request_delay_daysinteger7Read-only via this PUT (422 on write). Days to wait after the trigger event before sending. Set via the merchant admin UI / admin-ext /collection/config-change only.
review_request_delivery_fallback_daysinteger14Only applies when review_request_trigger = "delivered". If no carrier delivery confirmation arrives within this window, BetterReviews sends the email anyway (measured from fulfillment). Range 3–30. Default 14 balances carrier-signal latency against customer recall. Can be overridden per product — see product_timing_overrides.
product_timing_overridesobject{}Not settable via this PUT (operator-configured only). Per-product override of delay/fallback timing for long-lead-time products (made-to-order, pre-orders, subscriptions). Maps Shopify product_id → { "fallback_days": N } / { "delay_days": N } (each 1–180). When a request covers an overridden product, BetterReviews uses the longest matching value instead of the store-wide setting. Contact support to configure (no self-serve UI yet).
require_marketing_consentbooleanfalseRead-only via this PUT (422 on write). When true, review-request emails only go to customers whose Shopify emailMarketingConsent.marketingState is SUBSCRIBED. When false (default for new stores; transactional mode), BetterReviews sends to every non-suppressed customer per the spec's industry-standard treatment of non-promotional post-purchase requests. The legally explicit-no states (UNSUBSCRIBED / REDACTED / INVALID) are hard-skipped regardless of the flag. Flipping false → true cancels in-flight non-SUBSCRIBED rows with cancelled_reason="consent_gate_tightened". Set via the merchant admin UI / admin-ext /collection/config-change only — the cascade + dual audit (SettingsAuditLog + founder_audit_log require_marketing_consent_flipped) require the dry-run-confirm flow.
request_token_expiry_daysinteger90How long each review-request link stays valid. Range 30–180.
send_window_local_startinteger9Earliest local hour to send review-request emails (in customer's resolved timezone). Range 0–23.
send_window_local_endinteger21Latest local hour (exclusive) to send. Range 1–24.
send_time_strategystring"even_jitter""even_jitter" spreads sends across 9–21 local with deterministic per-row jitter; "off" uses legacy time-of-trigger timing (no local-window adjustment).
digest_enabledbooleanfalseWeekly digest email with review stats.
digest_recipient_emailstringnullOverride email for digest (defaults to store owner).
auto_recharge_enabledbooleanfalseOpt in to fair auto-recharge — BetterReviews auto-purchases extra AI credits when you exceed your plan's monthly limit. Starter: $25 per 100 credits. Growth: $50 per 300. Scale: $100 per 1,000. First 10% of each period's overage is free. Tier is determined by your plan and cannot be set via this API — upgrade your plan for a bigger block at a lower per-credit rate. Setting to false disables auto-recharge and flips auto_recharge_state to "off".
monthly_spend_cap_centsinteger20000Maximum cents BetterReviews will spend on auto-recharge per billing period. Range 5000 ($50) to 100000 ($1,000). Freely settable inside this range — no Shopify approval required. The $1,000 ceiling is approved at install; the merchant cap is enforced locally.
auto_recharge_statestring (read-only)"off"Server-managed state machine: "off", "active", "cap_reached", "shopify_rejected". Read-only — flipped by BetterReviews based on settings + billing events. (The legacy "pending_confirmation" value is no longer reachable since auto-recharge enable became local-only in v3.)

Note on the legacy pending_overage_tier key: pre-v2, merchants picked a tier via this settings key. It has been removed — any PUT containing pending_overage_tier returns HTTP 422 with error: "pending_overage_tier_removed". Use auto_recharge_enabled instead.

Note on promotional content in email_template.*: any text field inside email_template (subject, heading, body_text, button_text, footer_text) that contains promotional phrases (discounts, percent-off offers, dollar-amount offers, coupons, promo codes, referral incentives, free-shipping mentions, loyalty/rewards framing, gift cards, or cross-promo language) is rejected with HTTP 422 error: "promotional_content_detected". Response carries key (e.g. "email_template.body_text") and phrase (e.g. "percent off") identifying the offending field and pattern. Review-request emails are sent as transactional, post-purchase emails — promotional content would void that classification under CAN-SPAM, PECR, CASL, and GDPR. Use a marketing email platform (Klaviyo, Shopify Email, etc.) for promotional sends. The same gate also fires on POST /api/v1/store/send-test-email if email_template overrides carry promotional content.

Note on cap changes: as of v3 (2026-05-09), monthly_spend_cap_cents is freely settable within $50–$1,000 with no Shopify approval required. The legacy cap_increase_requires_resubscribe error is no longer returned.


Example Configurations

The 4 protected keys (collection_enabled, review_request_trigger, review_request_delay_days, require_marketing_consent) are NOT shown in these examples — they're set through the admin UI. Examples below cover what's settable via this PUT.

Manual-only moderation, no digest

{
  "settings": {
    "auto_moderation_preset": "manual",
    "digest_enabled": false
  }
}

All reviews land in pending for manual approval. No weekly digest email.

Balanced auto-moderation with chat experience + digest

{
  "settings": {
    "default_experience": "chat",
    "auto_moderation_preset": "balanced",
    "digest_enabled": true
  }
}

Reviews scoring above the balanced threshold are published automatically; others require manual review. Weekly digest summarises pending + published activity.

Form experience with relaxed moderation

{
  "settings": {
    "default_experience": "form",
    "auto_moderation_preset": "relaxed",
    "review_request_delivery_fallback_days": 10,
    "digest_enabled": true
  }
}

Star + text form (no chat). Looser auto-publish threshold; tighter delivery fallback (10 instead of the 14 default). The review_request_delivery_fallback_days key IS settable through this PUT — it only affects future fallback scheduling, no cohort cascade.


Email Moderation Settings (admin extension)

Email-driven moderation lets a merchant's CS team approve / reply / archive pending reviews directly from their inbox. These settings are managed through the Shopify admin extension (App Bridge JWT), not the public API. The full endpoint reference lives in the betterreviews-api skill; the keys are summarized here for completeness.

KeyTypeDefaultDescription
email_actions_enabledbooleanfalseMaster toggle for the entire email-driven moderation surface. When false, no notification emails fire and existing email-action links won't work.
pending_notification_modestring"instant""instant" sends a notification email per pending review (deduplicated on (store_id, review_id)). This is the resting default once email_actions_enabled is on. "digest_only" silences per-review sends and is reserved for the upcoming digest worker. "off" is equivalent to flipping email_actions_enabled off.
auto_dm_from_email_actionbooleantrueWhen true, approving a review from an email action fires the merchant's standard auto-thank-you DM via Shopify Flow's review-created trigger. When false, the DM is suppressed for all email-action approvals. The rep can additionally opt out per-review via a checkbox on the email confirmation page.

Recipient management (add / revoke / resend verification / list) and the Invalidate all pending notification links safety button are also admin-extension endpoints — they don't appear on the public API. Recipients are capped at 5 per store (active + pending verification combined), require one-time email-link verification before activation, and have their emails stored encrypted at rest and masked in the admin UI.