API docs

Coupons

Permission: coupons (read / write).

A coupon made through the API is the same as one made in Iron Register: the register accepts it, and a store_online coupon is mirrored to the shop's BigCommerce store by the background worker.

List and read

GET /v1/coupons. Filters: code, is_active, updated_since, limit, cursor.

GET /v1/coupons/{id}

{
  "object": "coupon",
  "id": 9,
  "code": "RANGEDAY",
  "name": "Range day 10% off",
  "type": "percent",
  "value": 10,
  "scope": "category",
  "channel": "store_online",
  "category_id": 530,
  "product_id": null,
  "min_subtotal_cents": 5000,
  "starts_at": "2026-09-01T04:00:00Z",
  "ends_at": null,
  "max_uses": null,
  "uses": 41,
  "is_active": true,
  "updated_at": "2026-09-20T12:00:00Z"
}
Field Values
code Letters, digits, dashes and underscores; stored upper-case (welcome-10 becomes WELCOME-10). Unique per shop.
type percent (value is a whole percent, at most 100) or fixed (value in cents)
scope all, category (needs category_id) or product (needs product_id)
channel store (counter only) or store_online (also on BigCommerce)
location_id Optional: the coupon works at this location's register only (null = every location). Online it goes on that location's own BigCommerce storefront, so store_online needs one.
min_subtotal_cents Optional minimum ticket subtotal
starts_at, ends_at Optional ISO-8601 window; ends_at must be after starts_at
max_uses Optional; 1 makes a single-use code. uses counts redemptions.

Create a coupon

POST /v1/coupons (write). code, name, type and value are required. scope defaults to all, channel to store, and is_active to true.

The typical caller is an email or SMS tool minting a unique, single-use code for each subscriber:

curl -X POST https://app.ironregister.com/api/v1/coupons \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: klaviyo-welcome-8H2KQ" \
  -d '{
    "code": "WELCOME-8H2KQ",
    "name": "Welcome series 10% (Klaviyo)",
    "type": "percent",
    "value": 10,
    "channel": "store_online",
    "max_uses": 1,
    "ends_at": "2026-12-31T23:59:59Z"
  }'
{ "status": "ok", "data": { "object": "coupon", "id": 212, "code": "WELCOME-8H2KQ", "name": "Welcome series 10% (Klaviyo)", "type": "percent", "value": 10, "scope": "all", "channel": "store_online", "category_id": null, "product_id": null, "min_subtotal_cents": null, "starts_at": null, "ends_at": "2026-12-31T23:59:59Z", "max_uses": 1, "uses": 0, "is_active": true, "updated_at": "2026-09-25T14:03:11Z" } }
  • A code already in use is 409 CODE_TAKEN.
  • Invalid values are 400 VALIDATION_ERROR, for example a percent over 100, an end before the start, a category scope without a category, or a code with nothing usable in it.
  • A store_online coupon scoped to a category or product needs that category or product to be linked to BigCommerce; otherwise it's 400 VALIDATION_ERROR naming category_id or product_id.
  • The coupon's internal note records that it was created through the API and by which key.

Update a coupon

PATCH /v1/coupons/{id} with any of the fields above. Changing the code checks it's still unique (409 CODE_TAKEN). Setting is_active: false switches a coupon off without deleting it.

curl -X PATCH https://app.ironregister.com/api/v1/coupons/212 \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{ "value": 15, "ends_at": "2027-01-31T23:59:59Z" }'

Delete a coupon

DELETE /v1/coupons/{id} removes the coupon and, if it was online, removes it from BigCommerce too.

{ "status": "ok", "data": { "object": "coupon", "id": 212, "code": "WELCOME-8H2KQ", "deleted": true } }

Sales that already used the code keep it on their receipts.

Webhooks

coupon.created, coupon.updated and coupon.deleted, whether the change came from Iron Register or the API.