RewardUpdate Payload Samples
These are the JSON payloads a client will receive for all supported variations of the RewardUpdate webhook.
1. Reward — Promo
PVP promo reward issued after scan results are processed.
{
"id": "fc5db27e-352e-43e9-a9c3-d72dbfc88d23",
"timestamp": 1776744008387,
"payload_data": {
"blink_receipt_id": "954d737a-c813-4249-8fab-428338abecff",
"update_type": "reward",
"status": "[pending|complete]",
"client_user_id": "test_user_123",
"reward_id": "dfcd3092-3320-4605-9e29-30dd8bce8d54",
"reward_type": "promo",
"reward_amount": 4,
"promo_ids_updated": [123],
"qualified_promos": [
{
"promo_id": 123,
"title": "Save $4.00 on any ONE (1) One A Day® 110ct+",
"qualified_count": 1,
"promo_amount": 4,
"status": "[pending|accepted|rejected]",
"reason": "REASON_CODE",
"products": [
{
"description": "ONE A DAY",
"price": 5,
"quantity": 1
}
]
}
]
},
"payload_type": "RewardUpdate",
"version": 1
}
- The top-level promo reward
payload_data.statusfollows this state machine:
- Each individual promo follows this state machine:
Notes
- All initial promo updates will have top-level
status: pendingand this status will not change in subsequent updates until all individual promo statuses have been resolved reward_amountrepresents the total potential awardable amount at a given time - it is the sum of all promo amounts that are inacceptedorpendingstatesreward_idwill remain constant throughout all related updatespromo_ids_updatedcontains thepromo_idvalues for promos whose status is first reported or changed in this webhook messagequalified_countandpromo_amountrepresent the number of instances of that promo and the total amount for that promo, respectively, that currently, or may in the future, qualify. In the case of a partial qualification, these fields will reflect only the portion that actually qualifiedreasonwill exist only when status ispendingorrejectedproductswill exist only when status ispendingoraccepted
2. Reward — Boost
Google SSV ad reward issued.
{
"id": "1e74a91c-0b63-4158-9d4c-29fe6e1d7fff",
"timestamp": 1776483872691,
"payload_data": {
"blink_receipt_id": "d4f5a8b2-9c3e-4a1f-b7d6-2e8f0c1a3b5d",
"client_user_id": "user-abc-123",
"reward_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"update_type": "reward",
"reward_type": "boost",
"reward_amount": 0.25,
"status": "[pending|complete]"
},
"payload_type": "RewardUpdate",
"version": 1
}
Notes
- For hard currency apps only, boosts cannot be paid out immediately after the user completes the ad watch. In this case only, a
pendingstatus will be sent out and then upon the next valid receipt submission, the reward will be paid and a subsequent webhook with statuscompletewill be sent.
3. Reward — Barcode Collection
UGC/barcode collection task reward issued.
{
"id": "1e74a91c-0b63-4158-9d4c-29fe6e1d7fff",
"timestamp": 1776483872691,
"payload_data": {
"blink_receipt_id": "d4f5a8b2-9c3e-4a1f-b7d6-2e8f0c1a3b5d",
"client_user_id": "user-abc-123",
"reward_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"update_type": "reward",
"reward_type": "barcode_collection",
"reward_amount": 0.50,
"status": "complete"
},
"payload_type": "RewardUpdate",
"version": 1
}
4. Reward — Base Scan
A basic paper receipt scan has been completed in the app.
{
"id": "1e74a91c-0b63-4158-9d4c-29fe6e1d7fff",
"timestamp": 1776483872691,
"payload_data": {
"blink_receipt_id": "bfcf4575-b287-4135-8236-d0eac733f3d0",
"client_user_id": "user-abc-123",
"update_type": "reward",
"status": "complete",
"reward_id": "0bd9a3ff-c79a-4d2a-9aee-0e82d895df81",
"reward_type": "base_scan",
"reward_amount": 0.5
},
"payload_type": "RewardUpdate",
"version": 1
}
5. Missed Earnings
Missed earnings request submitted and queued for processing.
{
"id": "251e0d6e-d117-4684-b047-98b6d4896b9f",
"timestamp": 1776458765539,
"payload_data": {
"blink_receipt_id": "d4f5a8b2-9c3e-4a1f-b7d6-2e8f0c1a3b5d",
"client_user_id": "user-abc-123",
"update_type": "missed_earnings",
"status": "[pending|complete]",
"reward_id": "0bd9a3ff-c79a-4d2a-9aee-0e82d895df81",
"reward_amount": 0,
"promo_ids_updated": [123],
"qualified_promos": [
{
"promo_id": 123,
"title": "Save $4.00 on any ONE (1) One A Day® 110ct+",
"qualified_count": 1,
"promo_amount": 4,
"status": "[pending|accepted|rejected]",
"reason": "REASON_CODE",
"products": [
{
"description": "ONE A DAY",
"price": 5,
"quantity": 1
}
]
}
]
},
"payload_type": "RewardUpdate",
"version": 1
}
Notes
- Similar structure and semantics to promo updates but with some notable differences:
- All amounts, promos, and products relate only to incremental earnings that have been preliminarily identified on this receipt in response to the user's corrections and/or supplementary data as part of the Missed Earnings process
- The
reward_amountstarts at 0 rather than the total potential rewardable amount as in promos, and is updated only when one or more promos are resolved asaccepted- this reflects the lower likelihood of missed earnings requests being validated - If a user's missed earnings request does not result in any preliminary incremental qualifications, the only webhook that will be sent out will have top level
status: completeand noqualified_promosarray.
Statuses / Reason Codes
For promo and missed earnings updates, these are the possible combinations of status and reason for entries in the qualified_promos array.
| Status | Reason code | Description |
|---|---|---|
accepted | [reason key will not exist in case of full acceptance] | Fully validated |
accepted | ACCEPTED_PARTIAL | Offer was partially validated |
pending | INITIAL | Initial offer match, awaiting downstream updates. |
pending | PENDING_AUTO_REVIEW | Standard happy-path pending — pipeline still running, no risk or review flags raised. |
pending | PENDING_HOLD_PERIOD | Approved and placed in a hold. Varying subrisk levels may be either auto-approved or remain in holding period. |
pending | PENDING_MANUAL_REVIEW | Routed for human review (standard manual, fraud specialist, admin-requested). |
pending | PENDING_MISSING_INFO | Processing paused on missing data (unparsed fields, awaited OCR retry, awaited match). Not user-actionable. |
pending | PENDING_SECONDARY_REVIEW | Already-reviewed submission pulled into senior/QA tier for a second look. Decision can flip. |
pending | PENDING_USER_ACTION_SUPPORT | Support has reached out to the user (clarification or additional images); paused until they respond. |
rejected | REJECTED_DUPLICATE | Receipt or transaction already redeemed/submitted — same user, different user, or anywhere in system. |
rejected | REJECTED_EMAIL_NO_MATCH | No merchant e-receipt email matched within the expected window. |
rejected | REJECTED_FRAUD | Fraud signals — image-forensic flags (screen, edit, banned phrases), ML decision, or generic 'fraud'. |
rejected | REJECTED_MEMBER_OFFER_MAX | Per-offer redemption cap hit. |
rejected | REJECTED_OFFER_NOT_ACTIVATED | Offer wasn't activated/clipped before purchase, or wasn't on the user's list. |
rejected | REJECTED_OFFER_RULES_CHANNEL | Fulfilment channel/medium not eligible (e.g., curbside pickup, ineligible online channel). |
rejected | REJECTED_OFFER_RULES_DATE | Purchase date outside the offer window — before start, after end, or past grace period. |
rejected | REJECTED_OFFER_RULES_ITEM | Eligible product not found, or didn't meet product/quantity/UPC/return conditions. |
rejected | REJECTED_OFFER_RULES_LOCATION | Offer not available in the user's area (state, zip, region). |
rejected | REJECTED_OFFER_RULES_MERCHANT | Merchant unrecognised or ineligible for the offer. |
rejected | REJECTED_OFFER_UNAVAILABLE | Offer no longer available — expired, exhausted, capped, or removed. |
rejected | REJECTED_QUALITY | Receipt image or parsed data inadequate (blurry, incomplete, missing fields, unparseable). User can resubmit a fresh image. |
rejected | REJECTED_RATE_LIMIT | Velocity threshold hit (uploads, redemptions, or dollars in the rate-limit window). Don't expose to end customer. |
rejected | REJECTED_SYSTEM_ERROR | Internal/partner-side error or config issue. |
rejected | REJECTED_USER_BLOCK | User on the partner's blocklist (prior fraud history or other reputation signals). Don't expose to end customer. |
Field Reference
| Field | Type | Description |
|---|---|---|
version | number | Always 1 |
id | string (UUID) | Top-level ID for the webhook |
timestamp | number | Unix timestamp of the reward update in milliseconds |
payload_type | string | Always "RewardUpdate" |
payload_data.blink_receipt_id | string (UUID) | Unique receipt ID |
payload_data.client_user_id | string | The client-specific user identifier, if one was provided during registration or on a subsequent SDK request. Omitted when no value is available. |
payload_data.reward_id | string (UUID) | Unique reward identifier |
payload_data.update_type | string | "reward" or "missed_earnings" |
payload_data.reward_type | string | "promo", "boost", "barcode_collection", "base_scan" (reward updates only) |
payload_data.reward_amount | number | Total Dollar amount of the reward (see notes above for meaning in promo and missed_earnings contexts) |
payload_data.status | string | "pending", "complete" |
payload_data.promo_ids_updated | number[] | Promo IDs whose status is first reported or changed in this webhook message |
payload_data.qualified_promos.promo_id | number | Identifier of this promo |
payload_data.qualified_promos.title | string | Name of the promotion the user's receipt qualified for |
payload_data.qualified_promos.qualified_count | number | Number of instances of the promo that qualified |
payload_data.qualified_promos.promo_amount | number | Dollar amount of the reward for the specific qualified promo |
payload_data.qualified_promos.status | string | "pending", "accepted", "rejected" |
payload_data.qualified_promos.reason | string | See table of reason codes above |
payload_data.qualified_promos.products.description | string | Product description of the specific qualified promo |
payload_data.qualified_promos.products.price | number | Price of the product(s) associated with the specific qualified promo |
payload_data.qualified_promos.products.quantity | number | Quantity of the product(s) associated with the specific qualified promo |
client_user_id is included in the payload only when a non-empty value was provided by the client during user registration or on a subsequent SDK request (GET /activations or POST /activations/scan_results). If no value has been set, the field is omitted entirely.