store/create-coupon creates a discount coupon: a percentage off, a fixed amount off the cart, or a fixed amount off each product.
A code that already exists is refused rather than quietly creating a second one.
At a glance
| Ability | store/create-coupon |
| Toolset | WooCommerce — toolset/woocommerce |
| Group | WooCommerce › Coupons |
| Requires | WooCommerce, active on the site |
| Capability | manage_options |
| Safety | Writes data |
| Repeatable | Not idempotent — each call changes the row set, so re-running is not a no-op |
| Ships in | AcrossAI Abilities Manager 0.0.34 and later |
Two refusals worth having
Duplicate codes are the first. WooCommerce will happily hold two coupons with the same code, and which one applies is then a matter of query order — so a shop can have a working code that occasionally applies the wrong discount, with nothing to explain it.
An unsupported discount type is the second. Stores can extend the type list, so the accepted set is read from the store rather than assumed, and a type this store does not offer is named rather than stored.
The three built-in types behave differently in ways that matter: percent scales with the cart, fixed_cart comes off once, and fixed_product comes off each qualifying product — which is how a £5-off coupon takes £40 off an order of eight.
Usage limits are the safety net on a public code. A percentage coupon with no limit and no expiry, posted somewhere public, is unbounded.
Input
| Name | Type | Required | What it is |
|---|---|---|---|
code | string | Yes | The code a customer types. Must not already exist. |
discount_type | string | No — defaults to fixed_cart | percent, fixed_cart or fixed_product. |
amount | string | No | The discount amount. For percent, 10 means ten per cent. |
description | string | No | Internal description. |
date_expires | string | No | Expiry date, YYYY-MM-DD. |
usage_limit | integer | No | Total times the coupon may be used. |
usage_limit_per_user | integer | No | Times one customer may use it. |
minimum_amount | string | No | Minimum cart total for the coupon to apply. |
maximum_amount | string | No | Maximum cart total for the coupon to apply. |
individual_use | boolean | No | Whether it cannot be combined with other coupons. |
free_shipping | boolean | No | Whether it grants free shipping. |
product_ids | array | No | Restrict to these products. |
excluded_product_ids | array | No | Exclude these products. |
product_categories | array | No | Restrict to these categories. |
What comes back
| Name | Type | What it is |
|---|---|---|
coupon | object | The created coupon. |
success | boolean | Whether the call completed. |
message | string | A one-line summary of what happened, suitable for showing a human. |
error_code | string | Present only on failure — a stable machine-readable reason, such as a missing field, a wrong field type or an unmet confirmation. |
Example
Ask your assistant:
Create a 10% off code called WINTER26 that expires at the end of December and can be used once per customer.
It resolves to one call:
{
"ability": "store/create-coupon",
"parameters": {
"code": "WINTER26",
"discount_type": "percent",
"amount": "10",
"date_expires": "2026-12-31",
"usage_limit_per_user": 1
}
}Worth knowing
fixed_productcomes off each qualifying product, not once per order.- A duplicate code is refused. Two coupons with one code is a real and confusing state.
- Set an expiry or a usage limit on any code that will be public.
- Not idempotent.
Related abilities
- Update Coupon — change it later
- Get Coupon — check it before publishing
Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager
Browse the rest: Every ability, by category