Discounts tools
MCP tools for Discounts: discounts_delete, discounts_list.
discounts_delete: End a discountdiscounts_list: List discounts
discounts_delete
End a discount. Operation discounts.delete · Brand level · permission subscriptions:write · risk tier financial · since M5
Ends a discount now: it no longer applies to invoices from this moment on, and a discount scheduled to start
later never starts. Invoices already issued keep their discount, and a redemption already counted stays
counted. The discount stays readable with end set; ending an ended discount changes nothing.
Works for subscription and customer-level discounts. reason is recorded in the audit log.
Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (disc_…) | yes | – |
reason | string | no | (1–500 characters) |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
idempotency_key | string | no | A unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters) |
dry_run | boolean | no | true: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false) |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Idempotency: the result returns the
idempotency_keyused, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours). - Dry run: supported.
dry_run: truechecks permissions and rules and computes the result, then rolls everything back.
Errors
resource_not_found: No discount with this ID is visible to the request.version_conflict: The discount changed at the same time; retry.permission_denied: You can't change this brand's subscriptions.
Example
End a discount early
Arguments:
{
"id": "disc_01m4tx5nj8emwbyf7y9vcf47z3",
"reason": "Offer withdrawn after a dispute",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "disc_01m4tx5nj8emwbyf7y9vcf47z3",
"object": "discount",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"promotionCodeId": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"start": "2026-10-13T12:00:00.000Z",
"end": "2026-10-14T09:30:00.000Z",
"redeemedAt": "2026-10-13T12:00:00.000Z",
"status": "ended",
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
discounts_list
List discounts. Operation discounts.list · Brand level · permission subscriptions:read · risk tier read · since M5
Lists applied coupons (discounts) in the request's mode, newest first: each with the coupon, the promotion code
it was redeemed with, the customer and subscription it belongs to, the window it applies in (start to end,
null = forever) and its status now. Filter by customerId, subscriptionId or couponId.
Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
customerId | ID (cus_…) | no | Only this customer's discounts. |
subscriptionId | ID (sub_…) | no | Only this subscription's discounts. |
couponId | ID (cpn_…) | no | Only discounts of this coupon. |
limit | integer | no | (1–100) |
starting_after | ID (disc_…) | no | – |
entity_id | ID (ent_…) | no | Optional: the brand's legal entity (ent_…); brand_id alone is enough. |
brand_id | ID (brd_…) | no | The brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand. |
- Brand: pass
brand_idwith an organization or entity key; a brand key acts on its own brand. - Read-only: changes nothing;
idempotency_keyis ignored.
Errors
validation_failed: A filter or pagination value is malformed.permission_denied: You can't see this brand's subscriptions.
Example
A subscription's discounts
Arguments:
{
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "disc_01m4tx5nj8emwbyf7y9vcf47z3",
"object": "discount",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"promotionCodeId": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"customerId": "cus_01m4tx5nj8emwbyf7y9vcf47z4",
"subscriptionId": "sub_01m4tx5nj8emwbyf7y9vcf47z5",
"start": "2026-10-13T12:00:00.000Z",
"end": "2027-01-13T12:00:00.000Z",
"redeemedAt": "2026-10-13T12:00:00.000Z",
"status": "active",
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}