Coupon campaigns
The header a batch of generated coupon codes hangs off.
A campaign is the header a batch of generated codes hangs off. The codes under it are ordinary coupon rows with a group_id, so every coupon route works on them unchanged. See Coupons.
List coupon campaigns
/api/v1/kahunacart/coupon-groups
Campaigns of coupon codes. A campaign is the header a batch of generated codes hangs off: the prefix and pattern its codes are built from, the per-code limits each one is stamped with, the budget for the campaign as a whole, and the discount and restrictions every code in it shares. Each row carries live totals — how many codes exist, how many redemptions they have between them, and how many codes have been used at least once — plus an example code so a caller can see what the pattern produces. The codes themselves are ordinary coupons and are listed by list_coupons.
Parameters
| Name | Type | Description |
|---|---|---|
| page optional | integer |
At least 1.
Default:
1 |
| per_page optional | integer |
At least 1.
Default:
100 |
| sort optional | string |
A column to sort every row by before it is paged; leave out for the usual order
One of:
campaign, codes, used, budget, status |
| dir optional | string |
One of:
asc, descDefault:
asc |
| q optional | string | Words to search for in the campaign name and the prefix; every word has to be there, in any order. Applied before the sort and the page, and total counts what it found |
Read one coupon campaign
/api/v1/kahunacart/coupon-groups/{id}
One campaign with its totals and a page of the codes under it. Use export_coupon_group for the whole list as a CSV — a campaign can hold tens of thousands of codes, and this returns a page of them, not all of them.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Campaign id |
| page optional | integer |
At least 1.
Default:
1 |
| per_page optional | integer |
At least 1.
Default:
200 |
Create a coupon campaign
/api/v1/kahunacart/coupon-groups
Create the header a batch of codes will be generated into. Creating a campaign mints no codes: call generate_coupon_codes for that, which is what lets a merchant get the settings right before minting five hundred rows.
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | What the merchant calls this campaign |
| prefix optional | string | Put in front of every generated code, so `AUTUMN-` reads as a campaign rather than as noise. Upper-cased. |
| pattern optional | string | What a generated code looks like. `#` is a generated character and anything else is a literal, so `####-####` is two groups of four. Characters come from Crockford base32 — the alphabet less I, L, O and U — so a code survives being handwritten and read back. Defaults to `########`. |
| enabled optional | boolean | Off switches every code in the campaign off at once |
| usage_limit optional | integer or null | Redemptions allowed per generated code, stamped onto each one. Normally 1 — a campaign code that can be redeemed twice is a campaign code somebody photographed. |
| usage_limit_per_user optional | integer or null | Stamped onto each generated code |
| total_usage_limit optional | integer or null | Redemptions across the whole campaign — the budget. Null for no cap. Reaching it refuses every code in the campaign with its own message, distinct from a single code being used up. |
| used_codes_limit optional | integer or null | The same budget counted in customers: how many of the campaign's codes may ever be redeemed. Null for no cap. Set it to 50 with a usage_limit of 5 and the offer is "for the first 50 customers, a few orders each" rather than fifty orders. Once it is reached an unused code is refused; a code that has already been redeemed goes on working up to its own limit. |
| template optional | object | The discount and restrictions every code generated into this campaign is stamped with. The same fields create_coupon takes, less the code itself and the usage limits, which the campaign owns. Editing it changes what the next batch is stamped with and never what an existing code holds. Keys: `type`, `percent`, `amount`, `basis`, `min_total`, `max_total`, `currency_amounts`, `starts_at`, `expires_at`, `enabled`, `individual_use`, `free_shipping`, `exclude_sale_items`, `limit_to_items`, `allowed_emails`, `grants_customer_group_id`, `conditions`, `scopes` |
Update a coupon campaign
/api/v1/kahunacart/coupon-groups/{id}
Change a campaign's fields. Only what is sent is written. Editing the template changes what the next generated batch is stamped with; codes already minted keep exactly what they were given, because a code sitting in a customer's inbox is a promise.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Campaign id |
| name optional | string | |
| prefix optional | string | |
| pattern optional | string | |
| enabled optional | boolean | |
| usage_limit optional | integer or null | |
| usage_limit_per_user optional | integer or null | |
| total_usage_limit optional | integer or null | |
| used_codes_limit optional | integer or null | |
| template optional | object | The settings the next batch is stamped with; see create_coupon_group |
Delete a coupon campaign
/api/v1/kahunacart/coupon-groups/{id}
Delete the campaign header. The codes are released, not deleted — they are on orders that have already been placed and in customers' inboxes, and they go on working as ordinary codes with whatever limits they were stamped with. Answers how many were released.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Campaign id |
Generate coupon codes
/api/v1/kahunacart/coupons/generate
Mint a batch of unique codes into a campaign. The codes are drawn from Crockford base32 using the campaign's prefix and pattern, checked against every code in the store in one query, and written in one transaction, so a batch of ten thousand is a handful of round trips rather than ten thousand. Each code is stamped with the campaign's template and per-code limits. A batch that would claim more than half the pattern's keyspace is refused before anything is drawn, and the refusal names the pattern and the number that would fit. Answers the codes it minted.
Parameters
| Name | Type | Description |
|---|---|---|
| group_id required | integer | Campaign to mint into |
| count required | integer | How many codes |
Export a coupon campaign
/api/v1/kahunacart/coupon-groups/{id}/export
Every code in a campaign as a CSV — code, whether it is enabled, how many times it has been redeemed, its own limit, and the day it was minted. A file rather than a JSON payload, because what happens to it next is a mail merge or a print run. Use this rather than get_coupon_group when the campaign holds more codes than a page.
Parameters
| Name | Type | Description |
|---|---|---|
| id required | integer | Campaign id |
Campaign fields are name, prefix, pattern (# is a generated character, everything else a literal), enabled, usage_limit and usage_limit_per_user (stamped onto each code it mints), total_usage_limit (the campaign budget, summed live from its codes) and template (the discount and restrictions every code shares).
POST /kahunacart/coupons/generate takes a group_id and a count between 1 and 50,000, and answers the codes it minted. A batch that would claim more than half the pattern's keyspace is refused before anything is drawn, and the refusal names the pattern and the number that would fit. Editing a campaign's template changes what the next batch is stamped with and never what an existing code holds.
DELETE on a campaign deletes the header and releases its codes rather than deleting them; the response says how many were released. The export route answers text/csv with the code, whether it is enabled, its redemptions, its own limit and the day it was minted, paged internally, so a campaign of fifty thousand codes is not held in memory at once.