Switch the program, VIP tiers, e-mails or referrals on or off
PATCH /program/switches/{switch}| Scope | program:write |
| Customer session token | Not accepted: call from your server with an API key |
| Rate limit class | write_shopify (limits) |
| Idempotency key | Required (idempotency) |
| MCP tool | charm_update_program_switch |
Flips one master switch through the same save as the admin, logged in the program changes. Every real change, on or off, is refused with 409 confirmation_required until the call carries confirm_switch: true; the dry run and the refusal carry impact: who starts or stops earning, for VIP tiers how many members land in each tier and how many gift codes are minted with their most possible value, for e-mails which templates start going out. Show the merchant the impact, get a clear yes, then confirm. Switching tiers on places every member in the background and mints their gift codes; switching e-mails on sends nothing retroactively.
Parameters
Section titled “Parameters”| Name | In | Type | Description |
|---|---|---|---|
switch | path | string: program, tiers, emails, referrals | program, tiers, emails or referrals. |
Request body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
enabled | boolean | |
confirm_switch | boolean | Required on the real call, after the merchant saw impact from the dry run and said yes. (optional) |
dry_run | boolean | Preview only: validate, resolve references and return the diff and summary, but write nothing. Costs no idempotency key and is limited as a read. Call with this first, show the merchant, then repeat without it. (optional) |
if_revision | integer | The program revision you last read (from GET /program or a previous write). When the program changed since, the write is refused with 409 revision_conflict instead of overwriting a concurrent admin edit. (optional) |
Response 200
Section titled “Response 200”Returns ProgramSwitchWriteResult.
| Field | Type | Description |
|---|---|---|
dry_run | boolean | |
revision | integer | |
switch | string: program, tiers, emails, referrals | |
enabled | boolean | The switch as it is (or, on a dry run, would be) after the call. |
operation | string: update, none | none: the switch was already in that position. |
impact | ProgramSwitchImpact or null | (nullable) |
{ "dry_run": false, "revision": 1, "switch": "program", "enabled": true, "operation": "update", "impact": { "members": 1, "members_with_email": 1, "members_in_tiers": 1, "emails_enabled": false, "tiers_enabled": false, "tier_impact": null, "gift_value": { "amount": 1, "currency": "EUR", "up_to": false, "complete": false }, "code_valid_days": 1, "approaching_emails": 1, "templates_sending": [ "templates sending" ], "launch_announcement_queued": false, "live_friend_codes": 1, "notes": [ "notes" ] }}Example
Section titled “Example”# 1. Dry run: writes nothing and needs no Idempotency-Key. Show the merchant the result.curl -X PATCH "https://charm.appfleece.app/api/v1/program/switches/<switch>" \ -H "Authorization: Bearer chrm_live_..." \ -H "Content-Type: application/json" \ -d '{"enabled":true,"dry_run":true}'
# 2. After the merchant says yes: the real call with the confirmation.curl -X PATCH "https://charm.appfleece.app/api/v1/program/switches/<switch>" \ -H "Authorization: Bearer chrm_live_..." \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"enabled":true,"confirm_switch":true}'Errors
Section titled “Errors”unauthorized · invalid_token · insufficient_scope · access_required · not_found · validation_error · rate_limited · idempotency_conflict · shopify_unavailable
Every error body carries code, message, request_id and a doc_url pointing at the matching entry in the error catalog.