Version
DESTRUCTIVE

deactivate_coupon

Switch a coupon code off so no new subscriber can redeem it. A checkout that already applied it keeps its discount. Emits coupon.deactivated.

Stop a code right now. Switching off is the safe way to retire a coupon: no new subscriber can redeem it, while the redemptions already recorded stay exactly as they are and a buyer who applied the code before you called keeps the discount they were quoted. Nothing is deleted, so activate_coupon brings it back.

Why this, and not delete_coupon

delete_coupon refuses while a checkout holding the code is still in progress, because the discount has already reached a gateway. Deactivating never refuses for that reason — it is the call to make when a code has leaked or a campaign has to end this minute. Delete later if you want the row gone.

Announces coupon.deactivated rather than a generic coupon.updated, so an automation that reacts to codes being withdrawn does not have to diff payloads to notice. Re-calling on a code that is already off leaves it unchanged; the event emits on every successful call, so key a consumer on the coupon's state rather than on counting events.

Requires ability

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveIdempotent

A client that honours annotations asks a person before running it. Sending the same arguments twice changes nothing the second time.

Arguments

coupon_id*string

UUID of the coupon to switch off.

What it returns

{  "data": {    "id": "4b9d3e08-a1f6-4275-9c83-7e01d6a2f594",    "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",    "code": "BLACKFRIDAY",    "name": "Black Friday 2026",    "discount_type": "percentage",    "discount_value": "25.0000",    "currency": null,    "duration": "once",    "max_redemptions": 500,    "max_redemptions_per_user": 1,    "minimum_amount": null,    "redemptions": {      "count": 137,      "remaining": 363,      "exhausted": false    },    "starts_at": "2026-11-27T00:00:00+00:00",    "expires_at": "2026-12-01T00:00:00+00:00",    "plan_ids": [],    "active": false,    "redeemable": false,    "created_at": "2026-11-20T09:14:02+00:00"  }}

The full get_coupon row, with active: false. redeemable is always false on a deactivated code; redemptions is untouched.

How it fails

VALIDATION_FAILED

the caller is a team member whose role lacks the team's coupon-update

RESOURCE_NOT_FOUND

unknown coupon_id, a coupon on another team's project, one outside the

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-coupon:update.

How is this guide?

Last updated on