How to generate bulk unique discount codes on Shopify
One shared code ends up on a coupon site. A batch of unique single-use codes does not, and each one can be attributed to the recipient who used it. The part that matters operationally is knowing which codes actually landed.
- Spend goal
- MERIDIAN-4KQ2M
- MERIDIAN-9XT7B
- MERIDIAN-2HN5R
- MERIDIAN-8PW3L
- MERIDIAN-6DZ1C
- MERIDIAN-3VJ9K
The recipient enters the code from their email and the discount applies. Because the code is single use, forwarding it to a friend does not work, so the campaign stays inside the list you sent it to.
How to set this up
- 1
Campaign > Method
Build the offer as usual, then set the method to code rather than automatic.
discountMethod = code
- 2
Codes > Generate a batch
Choose the prefix, the length, and how many codes to generate. A recognisable prefix makes the batch easy to identify in analytics later.
CodeBatch = prefix plus count
- 3
Codes > Limits
Set one use per code so a forwarded code does not work, and set an expiry so the batch stops being redeemable when the campaign ends.
eligibility.usageLimit = 1
- 4
Codes > Push and verify
Pushing a batch runs through an asynchronous import on the Shopify side, so the batch moves through pushing and polling before it is verified. Wait for the verified state before you send the email.
CodeBatch.syncStatus = verified
- 5
Handle a partial import
A batch can come back partial, meaning some codes imported and some were rejected. Check the batch before sending, because a partial batch means some recipients would get a code that does not work.
CodeBatch.syncStatus = partial or failed
- 6
Sync to email
Sync the batch to Klaviyo so each recipient receives a code that belongs to them, rather than everyone receiving the same string.
Every setting, spelled out
These are the real configuration keys the offer is saved with, so you can check your own setup against this table field by field.
| Setting | Value | Config key |
|---|---|---|
| Method | code | discountMethod |
| Batch size | set per batch | CodeBatch |
| Uses per code | 1 | eligibility.usageLimit |
| Once per customer | recommended true | eligibility.appliesOncePerCustomer |
| Sync states | pending, pushing, polling, verified, partial, failed | CodeBatch.syncStatus |
| Email sync | Klaviyo | EspLink |
| Counts against the 25 cap | no, the cap is automatic discounts only | discountMethod |
See it built end to end
The episode is not up yet
We are recording this one. The written recipe above is complete, so you can build it today.
What Shopify does natively
The Shopify admin can generate bulk discount codes for a discount, and it handles reasonable batch sizes without an app.
The native flow gives you no verification step, so a partially imported batch is discovered when a customer complains. It also has no direct sync to an email platform, which means exporting a file and hoping the mapping is right.
Watch out for
- Wait for the batch to reach the verified state before sending the email. A batch can come back partial, and partial means some recipients receive a code that does not work.
- A code batch does NOT eat into the 25-discount cap, because that cap counts automatic discounts only. This is one of the few places where choosing a code over an automatic offer buys you headroom.
- One use per code is what stops a code being forwarded. Without it, a single leaked code behaves like a public one.
- Set an expiry. A batch with no expiry stays redeemable long after the campaign is over.
Common questions
- Why use unique codes instead of one shared code?
- A shared code ends up on coupon sites within hours. Unique single-use codes cannot be redistributed usefully and each redemption is attributable to a recipient.
- How do I know the codes actually imported?
- The batch has a sync state. It moves through pushing and polling to verified, and it can come back partial or failed. Check for verified before you send.
- Can the codes go straight into my email platform?
- Yes, a batch can be synced to Klaviyo so each recipient gets their own code.
- Does a code batch use up my 25 discount slots?
- No. Shopify caps active AUTOMATIC discounts; code discounts are not counted. If you are near the ceiling, moving a promotion to codes is a legitimate way to free a slot.
Related examples
A sale that starts and ends on schedule, with a countdown and no manual intervention.
How the active-discount cap is counted, and how to model a big sale so you never hit it.
Build a test cart and see which discounts apply, and which get dropped, before publishing.
Build this in your own store
Every recipe in this library runs on the same server-side engine, so the cart total and the checkout total agree.