Promotion codes tools
MCP tools for Promotion codes: promotion_codes_archive, promotion_codes_create, promotion_codes_get, promotion_codes_list, promotion_codes_update.
promotion_codes_archive: Archive a promotion codepromotion_codes_create: Create a promotion codepromotion_codes_get: Get a promotion codepromotion_codes_list: List promotion codespromotion_codes_update: Update a promotion code
promotion_codes_archive
Archive a promotion code. Operation promotion_codes.archive · Brand level · permission catalog:write · risk tier write · since M5
Archives a promotion code: customers can't use it any more. Discounts already applied with it keep running,
and its code stays taken. Archiving an archived code changes nothing. Reactivate it with
promotion_codes.update and active: true.
reason is recorded in the audit log.
Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (promo_…) | 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 promotion code with this ID is visible to the request.version_conflict: The code changed at the same time; retry.permission_denied: You can't change this brand's catalog.
Example
Stop a leaked code
Arguments:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"reason": "Shared on a coupon site",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": false,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}
promotion_codes_create
Create a promotion code. Operation promotion_codes.create · Brand level · permission catalog:write · risk tier write · since M5
Creates a customer-facing code for a coupon, such as LAUNCH50. Customers enter it at checkout (any case);
codes are unique in the brand and mode and are never reused, archived ones included.
restrictions limit who can use it and when: firstTimeOnly (no earlier successful payment or paid invoice),
minimumAmount (the purchase before discounts, same currency), customerId, expiresAt and
maxRedemptions. They are checked when the code is applied; redemptions are counted on successful payment.
The code and its restrictions can't change later: archive it and create another.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
couponId | ID (cpn_…) | yes | The coupon customers get with the code. |
code | string | yes | What customers type, e.g. LAUNCH50. Case doesn't matter; unique in the brand and mode. |
restrictions | object | no | Who can use the code and when. They can't change later: create a new code instead. |
active | boolean | no | Default true; false creates it archived. |
metadata | object | no | Your own key-value pairs (at most 50 keys). On updates the whole set is replaced. |
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
validation_failed: The code or a restriction is malformed, orexpiresAtis in the past.promotion_code_taken: The brand already has this code in this mode (in any case).coupon_not_redeemable: The coupon is archived, expired or used up.resource_not_found: The coupon or the restricted customer isn't in this brand and mode.customer_deleted: The restricted customer was deleted.permission_denied: You can't change this brand's catalog.
Example
A launch code for first-time customers
Arguments:
{
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"maxRedemptions": 200
},
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": true,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
promotion_codes_get
Get a promotion code. Operation promotion_codes.get · Brand level · permission catalog:read · risk tier read · since M5
Returns one promotion code of the brand in the request's mode, archived or not, with its restrictions and how often it was redeemed. To find a code by what customers type, use promotion_codes.list with code.
Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (promo_…) | yes | – |
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
resource_not_found: No promotion code with this ID is visible to the request.permission_denied: You can't see this brand's catalog.
Example
A launch code
Arguments:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": true,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
promotion_codes_list
List promotion codes. Operation promotion_codes.list · Brand level · permission catalog:read · risk tier read · since M5
Lists the brand's promotion codes in the request's mode, newest first. Filter by couponId, by active, or by
code to look a code up the way customers type it (case doesn't matter; at most one result).
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 |
|---|---|---|---|
couponId | ID (cpn_…) | no | Only the codes of this coupon. |
code | string | no | Find the promotion code customers type as this text (case doesn't matter). (1–100 characters) |
active | string | no | Only active (true) or archived (false) codes. |
limit | integer | no | (1–100) |
starting_after | ID (promo_…) | 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 catalog.
Examples
Look up a code as a customer typed it
Arguments:
{
"code": "launch50",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": true,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
A coupon's codes
Arguments:
{
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}
Result output:
{
"object": "list",
"data": [
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": true,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-13T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}
promotion_codes_update
Update a promotion code. Operation promotion_codes.update · Brand level · permission catalog:write · risk tier write · since M5
Archives (active: false) or reactivates (active: true) a promotion code, or replaces its metadata. The code
and its restrictions never change: archive the code and create a new one instead. A reactivated code still
needs a redeemable coupon to be used.
Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
id | ID (promo_…) | yes | – |
active | boolean | no | false archives the code, true reactivates it. |
metadata | object | no | Your own key-value pairs (at most 50 keys). On updates the whole set is replaced. |
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
validation_failed: Neitheractivenormetadatawas sent.resource_not_found: No promotion code with this ID is visible to the request.version_conflict: The code changed at the same time (for example a redemption); retry.permission_denied: You can't change this brand's catalog.
Example
Pause a code
Arguments:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"active": false,
"brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
"idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}
Result output:
{
"id": "promo_01m4tx5nj8emwbyf7y9vcf47z2",
"object": "promotion_code",
"brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
"livemode": false,
"couponId": "cpn_01m4tx5nj8emwbyf7y9vcf47z0",
"code": "LAUNCH50",
"restrictions": {
"firstTimeOnly": true,
"minimumAmount": null,
"customerId": null,
"expiresAt": null,
"maxRedemptions": 200
},
"timesRedeemed": 0,
"active": false,
"metadata": {},
"createdAt": "2026-10-13T12:00:00.000Z",
"updatedAt": "2026-10-14T09:30:00.000Z"
}