Skip to content

Update a coupon

The coupons.update operation: PATCH /api/v1/coupons/{id} in the REST API and the coupons_update tool in the MCP server.

PATCH/api/v1/coupons/{id}

Changes a coupon. Send only the fields to change; null clears an optional field.

The name, active (false archives, true reactivates) and metadata can always change. The terms (percent or amount off, duration, appliesTo, maxRedemptions, redeemBy) change only while the coupon is unused: once a discount references it or a redemption is counted they are fixed (coupon_immutable), so customers keep what they were promised. Create a new coupon for new terms.

At a glance

  • REST: PATCH /api/v1/coupons/{id}
  • MCP tool: coupons_update
  • Operation ID: coupons.update
  • Scope: Brand
  • Permission: catalog:write
  • Risk tier: write
  • Dry run: Supported (send Ownrecord-Dry-Run: true)
  • Idempotency: Idempotency-Key optional
  • Modes: Test and live
  • Authentication: API key with the catalog:write scope
  • Since: M5

Request

Path parameters

FieldTypeDescription
idcpn_… ID

Body

A JSON object (Content-Type: application/json):

FieldTypeRequiredDescription
namestringNoShown to customers at checkout and on invoices, e.g. Launch offer.
activebooleanNofalse archives the coupon, true reactivates it.
metadataobjectNoYour own key-value pairs (at most 50 keys). On updates the whole set is replaced.
percentOffPpmstring or nullNo
amountOffobject or nullNo
durationone of once, repeating, foreverNoonce (one billing period), repeating (durationInPeriods periods) or forever. Periods count from the first period boundary at or after the discount starts.
durationInPeriodsinteger or nullNo
appliesToobject or nullNo
maxRedemptionsinteger or nullNo
redeemBydate-time or nullNo

Response

200 OK with a JSON object:

FieldTypeDescription
idcpn_… ID
object"coupon"
brandIdbrd_… ID
livemodeboolean
namestring
percentOffPpmstring or nullPercent off in parts per million (500000 = 50%), or null for an amount-off coupon.
amountOffmoney or nullAmount off per invoice, or null for a percent-off coupon.
durationone of once, repeating, forever
durationInPeriodsinteger or null
appliesToobject or nullThe products and prices the coupon is limited to, or null for every line.
maxRedemptionsinteger or null
redeemBydate-time or null
timesRedeemedinteger
validbooleanWhether it can be redeemed now: active, before redeemBy, below its limit.
usedbooleanA discount references it or a redemption was counted: only name, status and metadata can change.
activeboolean
metadataobject
createdAtdate-time
updatedAtdate-time

Examples

Rename a coupon

HTTP
PATCH /api/v1/coupons/cpn_01m4tx5nj8emwbyf7y9vcf47z0
Authorization: Bearer or_test_…
Content-Type: application/json

{
  "name": "Launch week offer"
}

Response (200):

JSON
{
  "id": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "coupon",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "name": "Launch week offer",
  "percentOffPpm": "500000",
  "amountOff": null,
  "duration": "repeating",
  "durationInPeriods": 3,
  "appliesTo": {
    "productIds": [],
    "priceIds": ["price_01m4tx5nj8emwbyf7y9vcf47y2"]
  },
  "maxRedemptions": 500,
  "redeemBy": "2027-01-01T00:00:00.000Z",
  "timesRedeemed": 0,
  "valid": true,
  "used": false,
  "active": true,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-14T09:30:00.000Z"
}

Errors

CodeHTTP statusWhenWhat to do
validation_failed400No field to change was sent, or the new terms break a rule.Fix the fields listed in details.issues and send the request again.
coupon_immutable409The coupon is used and the request changes its terms.Create a new coupon with the new terms (and new promotion codes for it), then archive this one. Its name and status can still change.
resource_not_found404No coupon (or product or price in appliesTo) with this ID is visible.Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.
version_conflict409The coupon changed at the same time (for example a redemption); retry.Fetch the object again and retry the change.
permission_denied403You can't change this brand's catalog.Ask an organization owner or admin for a role or scope that allows this action.

It can also return these common errors: api_version_unsupported, invalid_json, unsupported_media_type, authentication_required, api_key_invalid, scope_required, idempotency_key_reused, idempotency_in_progress, approval_required, approval_rejected, approval_expired, stale_approval, approval_policy_denied, rate_limited, internal_error.