addToWallet.co
Workspaces
Pricing
API Docs
Tutorial Blog
Tools
Google Sheet Extension
PDF to Pass
Image to Pass
QR Code Generator
Barcode Generator
Integrations
© 2026 Hazelnut Ventures LLC. All Rights Reserved.
FAQsTrustContact Us
Overview
AuthenticationPass JSON GeneratorCreate PassGet PassUpdate PassDelete PassNotificationsGet Credits
Create TemplateList TemplatesGet TemplateUpdate TemplateDelete TemplateDynamic Pass Gen
Create Loyalty TemplateManage LoyaltyActivity Log
List User GroupsAdd UserList UsersUpdate UserDelete UserBatch Status

Create Loyalty Template API

Overview

A loyalty pass is a Dynamic Pass with a progress counter — a stamp card ("buy 5, get 1 free") or a points counter. This endpoint creates the loyalty template, which behaves like a dynamic pass template plus a loyaltyProgressData block describing the counter.

🔗 Same customer flow as Dynamic Pass

Once the template exists, you manage members with the exact same Manage Users endpoints as dynamic passes: Add User, List Users, Update User and Delete User. The loyalty-specific part is just this template and the Progress Update endpoint.

⚠️ Counter images are pre-generated

On creation, one image per count value (0 … maxStampCount) is rendered server-side from your counter config and stored on the template — you do not send countBasedImageUrls. For large maximums this is batched and may take a little time to finish.

Base URL

https://app.addtowallet.co
POST/api/v2/loyaltyPass/template

Authentication

All API requests must include your API key in the request headers:

"apikey": "your-api-key-here"

Request Body

The body is a pass template (same design fields as the Dynamic Pass template — see Create Template for the shared fields and {placeholder} syntax) with two loyalty additions: cardSubType and loyaltyProgressData.

Top-level fields

NameTypeRequiredDescription
namestringYes
A descriptive name for the loyalty template.
cardSubTypestringYes
Must be "dynamic_loyalty_stamp_card" to mark this template as a loyalty pass.
loyaltyProgressDataobjectYes
The counter configuration. See the breakdown below.
groupIdstringNo
Existing user group to attach. If omitted, a group is auto-created (look it up via List User Groups).
...templateDataobjectNo
Standard pass design fields (cardTitle, header, subheader, hexBackgroundColor, textModulesData, barcodeValue, …) — identical to the Dynamic Pass template. Any string may contain {placeholder} keys filled per customer.

loyaltyProgressData

This block is what makes the pass a loyalty card, and it comes in two shapes — pick one with loyaltyType and send the matching counter object:

  • STAMP — a row of stamp icons that fill up (e.g. "buy 5 coffees, get 1 free"). Send stampCounter.
  • TEXT — a "current / max" points counter (e.g. "60 / 100 pts"). Send textCounter.

loyaltyProgressData fields

NameTypeRequiredDescription
loyaltyType"STAMP" | "TEXT"Yes
STAMP renders a row of stamp icons; TEXT renders a "current / max" text counter.
stampCounterobjectConditional
Required when loyaltyType is STAMP.
maxStampCountnumberYes
Stamps needed to complete the card (the reward threshold).
initialStampCountnumberNo
Stamps a new member starts with. Defaults to 0.
stampIconNamestringYes
Which icon fills each stamp slot. One of the built-in names in the Stamp icons table below (default coffeeIcon2).
customStampIconstringNo
URL of your own hosted icon to use instead of a built-in one. When set, it overrides stampIconName.
stampBannerBgColorstringYes
Hex background colour of the stamp banner.
stampBannerIconBgColorstringYes
Hex background colour behind each stamp icon.
textCounterobjectConditional
Required when loyaltyType is TEXT.
maxProgressnumberYes
Target value that completes the card.
initialProgressnumberNo
Starting value for a new member. Defaults to 0.
textCounterFormatstringYes
Display format, e.g. {current}/{max}.
textCounterFontSizenumberNo
Font size of the counter text.
textColorstringYes
Hex colour of the counter text.
textBackgroundColorstringYes
Hex background colour behind the counter.
heroImageUrlstringNo
Optional background image for the counter banner.

Stamp icons

For STAMP cards, stampIconName chooses the icon drawn in each stamp slot. Use one of these built-in names:

  • coffeeIcon2 — Coffee cup (default)
  • coffeeIcon3 — Coffee cup (alternate style)
  • burgerIcon1 — Burger
  • donut1 — Donut
  • iceCream1 — Ice cream
  • pizza1 — Pizza slice
  • sandwich1 — Sandwich

How the icons are placed

  • Every slot except the last uses your stampIconName (or customStampIcon).
  • The final slot — the reward — always renders as a gift icon automatically; you don't configure it.
  • Filled slots appear in colour; not-yet-earned slots are shown greyed-out.
  • For a brand icon, set customStampIcon to a hosted image URL — it replaces the built-in stampIconName for every slot (except the gift reward).

Request Examples

The two loyalty types take different bodies. Switch tabs to see a complete, copy-pasteable request for each:

curl -X POST 'https://app.addtowallet.co/api/v2/loyaltyPass/template' \
  -H 'apikey: your-api-key-here' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "Cafe Muse Loyalty Card",
  "cardSubType": "dynamic_loyalty_stamp_card",
  "groupId": "66b6005bb7bddce8f05a3392",
  "cardTitle": "Cafe Muse",
  "hexBackgroundColor": "#45290d",
  "appleFontColor": "#ffffff",
  "logoUrl": "https://s3.amazonaws.com/i.addtowallet.co/assets/cafe-muse-logo.png",
  "barcodeType": "QR_CODE",
  "barcodeValue": "{_customerId}",
  "textModulesData": [
    {
      "id": "r1start",
      "header": "Member",
      "body": "{name}"
    }
  ],
  "header": "FREE COFFEE",
  "subheader": "REWARD ON 5TH VISIT",
  "loyaltyProgressData": {
    "loyaltyType": "STAMP",
    "stampCounter": {
      "maxStampCount": 5,
      "initialStampCount": 0,
      "stampIconName": "coffeeIcon2",
      "stampBannerBgColor": "#45290d",
      "stampBannerIconBgColor": "#ffffff"
    }
  }
}'

Response

On success the API returns:

  • dynamicPassId (string): ID of the created loyalty template. Use it as the dynamicPassId when checking members in.
  • message (string): Confirmation message.

Response Example

{
  "dynamicPassId": "686d0d92c2f0bc5cdf25c834",
  "message": "Template created successfully"
}

💡 Next steps

Add members to the template's group with Add User, then record visits with Progress Update and review history via the Activity Log.

Updating & deleting a loyalty template

A loyalty template is stored as a dynamic pass template, so you manage its lifecycle with the same template endpoints — there is no separate loyalty update/delete:

  • Fetch / list — Get Template and List Templates return loyalty templates too (the loyaltyProgressData block is included).
  • Update — Update Template works, with the caveats below.
  • Delete — Delete Template behaves exactly like a dynamic template: it soft-deletes the template and queues removal of every pass issued from it.

⚠️ Updating a loyalty template

  • Send the complete template. Update replaces the whole stored template with your body, so first Get Template, modify it, and send it all back — keeping cardSubType, the full loyaltyProgressData (including countBasedImageUrls). Omitting them turns the card back into a plain pass.
  • Counter visuals are fixed at create time. The stamp / counter images are generated only by this Create endpoint. Update does not rebuild them, so changing maxStampCount, stampIconName or the banner colours won't re-render the artwork — create a new template for those changes.
  • Text, links and other non-counter design fields update fine and re-render on existing passes.
Error CodeDescription
400Bad Request - Missing required fields or invalid loyaltyProgressData.
401Unauthorized - Missing or invalid API key.
429Too Many Requests - API rate limit exceeded. Please wait before making additional requests.
500Internal Server Error - Template or counter-image generation failed. Please contact support.