RewardStar API
RewardStar API
Issue prepaid RewardStar gift cards to members and look up previously issued cards. This surface is part of the Custom API (externalApi).
Base URL
https://us-central1-incentable-app-37d9c.cloudfunctions.net/externalApi/api/v1/external
Authentication & permissions
Use a Bearer API key (inc_…):
Authorization: Bearer YOUR_API_KEY
| Action | Required permission |
|---|---|
| Issue a card | rewardStar → write |
| Look up a card | rewardStar → read |
Keys come from a Custom API or Braze integration in the Admin dashboard — see Getting your API key. Optionally set a Default RewardStar Card on the integration so requests can omit cardId.
Issue a card
POST /rewardstar/cards
Request body
| Field | Type | Required | Description |
|---|---|---|---|
member.email | string | Yes | Recipient email |
member.firstname | string | Yes | First name |
member.lastname | string | Yes | Last name |
member.accountKey | string | No | Matched before email when present |
member.mobile | string | No | Optional mobile |
denomination | number | Yes | Face value in dollars; must be a produced denomination on the card |
expiryDays | number | No | 30–365 (default 90) |
cardId | string | Conditional | Card id (shown on RewardStar Card pages in Admin); required unless a default is configured |
externalRef | string | No | Your idempotent reference (unique per cardId) |
idempotencyKey | string | No | Explicit idempotency key |
Also accepted: Idempotency-Key header. Resolution order: body idempotencyKey → header → externalRef → generated key.
externalRef with every request. A generated key is different on every attempt, so it does not stop a retry from issuing a second card.Example
curl -X POST \
"https://us-central1-incentable-app-37d9c.cloudfunctions.net/externalApi/api/v1/external/rewardstar/cards" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm-order-12345" \
-d '{
"cardId": "abc123",
"denomination": 50,
"expiryDays": 90,
"externalRef": "crm-order-12345",
"member": {
"email": "jane@example.com",
"firstname": "Jane",
"lastname": "Doe",
"accountKey": "ACME-001"
}
}'
Success response (201)
{
"data": {
"id": "codeDocId",
"status": "issued",
"amount": 50,
"expiresAt": "2026-10-19T06:00:00.000Z",
"redeemUrl": "https://redeem.rewardstarcard.com/?t=…",
"isTest": false,
"externalRef": "crm-order-12345"
},
"memberId": "memberDocId",
"memberCreated": true,
"message": "RewardStar card issued successfully"
}
Opted-out recipients (202)
If the member has unsubscribed from Incentable emails, no card is issued and nothing is drawn from the fund. The request is held for an admin to review and the API returns 202 Accepted:
{
"quarantined": true,
"quarantineId": "quarantineDocId",
"reasonId": "member_email_opt_out",
"reasonLabel": "Member opted out of email",
"message": "Member has opted out of email. Card was not issued or funded. Awaiting admin review."
}
Admins release or discard quarantined requests from the RewardStar card's Issue Cards page. Resending the same externalRef while it is pending returns the same 202.
Replays and duplicates
Idempotent replays of the same key return 200 with the original payload. Duplicate externalRef for the same cardId returns 409 with the existing card (no redeemUrl on that conflict payload). The same externalRef may be reused on a different RewardStar card.
Behaviour notes
- Member upsert: accountKey → email → create Pending member (encrypted fields + auth sync).
- Email: Branded HTML is compiled server-side from the card template (CTA, produced card image, placeholders). Recipients receive the redeem link by email.
- Fund: Live cards draw down the program fund (face + fee + GST where applicable). Cards with test mode on skip fund movement and set
isTest: true. redeemUrl: Returned only on issue (and idempotent replay). The plaintext token is never stored; GET lookup does not includeredeemUrl.
Common errors
| Status | Code | Meaning |
|---|---|---|
| 400 | NO_CARD_SPECIFIED | No cardId and no default configured |
| 400 | BRAZE_CREDENTIALS_REQUIRED | Braze integration has no Braze REST cluster / API key saved |
| 400 | INVALID_ARGUMENT / VALIDATION_ERROR | Bad body or denomination not on the card |
| 402 | INSUFFICIENT_FUND | Program fund balance too low |
| 403 | PERMISSION_DENIED | Key lacks rewardStar write |
| 409 | DUPLICATE_EXTERNAL_REF | externalRef already used for this cardId |
| 409 | AMBIGUOUS_EXTERNAL_REF | GET by externalRef matched multiple cards — pass ?cardId= |
| 409 | IDEMPOTENCY_IN_PROGRESS | Same key still processing |
| 422 | SETUP_INCOMPLETE_CATALOGUE / SETUP_INCOMPLETE_DENOMINATIONS / SETUP_INCOMPLETE_CLIENT_NAME | Card setup not finished in Admin |
| 422 | DENOMINATION_NOT_PRODUCED | Amount is configured but its card image was not produced |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit reached for the key |
Get an issued card
GET /rewardstar/cards/{id}
{id} may be the issued code document id or an externalRef. When looking up by externalRef, you can pass ?cardId= to disambiguate (references are unique per card, not across every card in the program).
curl -X GET \
"https://us-central1-incentable-app-37d9c.cloudfunctions.net/externalApi/api/v1/external/rewardstar/cards/crm-order-12345?cardId=YOUR_CARD_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
Example response
{
"data": {
"id": "codeDocId",
"status": "issued",
"amount": 50,
"cardId": "abc123",
"memberId": "memberDocId",
"externalRef": "crm-order-12345",
"isTest": false,
"expiresAt": "2026-10-19T06:00:00.000Z",
"issuedAt": "2026-07-21T06:00:00.000Z"
}
}
Related guides
- RewardStar Card (Admin) — Design, produce, catalogue, and issue from the dashboard
- Braze → RewardStar Cards — step-by-step Braze campaign / Canvas webhook setup
- API Overview — base URL, auth, getting your API key
