Passes
Passes are a way to provide your users with a digital representation of a physical product. This can be a coupon, a storecard or a prepaidcard.
Inspect pass with email
Search for a pass using a members email address for a specific brand.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
passes.get- Type
- string
- Description
The scope required to access this endpoint.
Query parameters
- Name
email- Type
- string|Required
- Description
The email address of the member.
- Name
brand_id- Type
- string|Required
- Description
The UUID of the brand.
- Name
pass_code- Type
- string|Required
- Description
The code of the pass.
Request
curl -X GET https://api.walletapp.co/passes
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"brand_id": "<brand_id>",
"email": "<email>",
"pass_code": "<pass_id||qr_code>"
}'
Response
{
"success": true,
"data": {
"brand_id": "<brand_id>",
"code": "<code>",
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"demo": 0,
"redeemed": 0,
"active": 1,
"expired": 0,
"blocked": 0,
"reminder_send": 0,
"expiration_date": "<timestamp>",
"start_date": null,
"reminder_date": null,
"parsed_historical": 0,
"coupon": {
"identifier": "<identifier>",
"price": "<coupon shop price>",
"points": "<coupon shop points>",
"external_reference": "<reference>"
},
"storecard": {
"identifier": "<identifier>",
"points": "<points>",
"balance": "<balance>",
}
}
}
Inspect passes
Search for a pass only using the pass code.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
search.pass- Type
- string
- Description
The scope required to access this endpoint.
Query parameters
- Name
pass_code- Type
- string|Required
- Description
The code of the pass.
Request
curl -X GET https://api.walletapp.co/search/pass
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"pass_code": "<pass_id||qr_code>"
}'
Response
{
"success": true,
"data": [
{
"created_at": "<timestamp>",
"updated_at": "<timestamp>",
"expiration_date": "<timestamp>",
"downloaded": 1,
"start_date": "<timestamp>",
"batch_reference": null,
"reminder_date": null,
"download_lat": null,
"user_name": "<username>",
"member_id": "<member_id>",
"download_long": null,
"pass_code": "<pass_code>",
"status": "active",
"brand": {
"name": "<name>",
"identifier": "<UUID>"
},
"coupon": {
"title": "<title>",
"identifier": "<UUID>",
"price": 0,
"points": 0,
"external_reference": "<external_reference>"
}
}
]
}
Modify a pass
Modify the expiration date or the status of a pass.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
passes.get- Type
- string
- Description
The scope required to access this endpoint.
Query parameters
- Name
email- Type
- string|Required
- Description
The email address of the member.
- Name
brand_id- Type
- string|Required
- Description
The UUID of the brand.
- Name
pass_code- Type
- string|Required
- Description
The code of the pass.
- Name
expiration_date- Type
- timestamp|Required
- Description
The new expiration date of the pass.
- Name
status- Type
- string|Required
- Description
The new status of a pass. Can be
['active', 'expired', 'redeemed', 'blocked']
Request
curl -X PUT https://api.walletapp.co/passes
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"brand_id": "<brand_id>",
"email": "<email>",
"pass_code": "<pass_id||qr_code>",
"expiration_date": "<timestamp>",
"status": "<status>"
}'
Response
{
"success": true,
"message": "Pass updated successfully",
"transaction_id": "<uuid>"
}
Remove a pass
Remove a pass from a member.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
passes.get- Type
- string
- Description
The scope required to access this endpoint.
Query parameters
- Name
email- Type
- string|Required
- Description
The email address of the member.
- Name
brand_id- Type
- string|Required
- Description
The UUID of the brand.
- Name
pass_code- Type
- string|Required
- Description
The code of the pass.
Request
curl -X DELETE https://api.walletapp.co/passes
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"brand_id": "<brand_id>",
"email": "<email>",
"pass_code": "<pass_id||qr_code>"
}'
Response
{
"success": true,
"message": "Pass removed"
}
Email a pass
Send a specific coupon pass to a member.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
passes.get- Type
- string
- Description
The scope required to access this endpoint.
Body parameters
- Name
email- Type
- string|Required
- Description
The email address of the member.
- Name
brand_id- Type
- string|Required
- Description
The UUID of the brand.
- Name
coupon_id- Type
- string|Required
- Description
The id of the coupon to send.
- Name
status- Type
- string|Required
- Description
The status of the pass. Can be:
['active', 'blocked', 'expired', 'redeemed']
- Name
pass_title- Type
- string
- Description
A custom title to display on this pass.
- Name
expiration_date- Type
- string
- Description
The expiration date of the pass.
Request
curl -X POST https://api.walletapp.co/passes
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
'email': '<email>',
'brand_id': '<brand_id>',
'coupon_id': '<coupon_id>',
'expiration_date': '<expiration_date>',
'pass_title': '<pass_title>',
'status': 'active'
}'
Response
{
"success": true,
"message": "Email has been send"
}
Create a pass link
This endpoint generates a new pass and returns the url to the download page.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
passes.get- Type
- string
- Description
The scope required to access this endpoint.
Body parameters
- Name
email- Type
- string|Required
- Description
The email address of the member.
- Name
brand_id- Type
- string|Required
- Description
The UUID of the brand.
- Name
coupon_id- Type
- string|Required
- Description
The id of the coupon to send.
- Name
status- Type
- string|Required
- Description
The status of the pass. Can be:
['active', 'blocked', 'expired', 'redeemed']
- Name
pass_title- Type
- string
- Description
A custom title to display on this pass.
- Name
expiration_date- Type
- string
- Description
The expiration date of the pass.
Request
curl -X POST https://api.walletapp.co/passes/url
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
'email': '<email>',
'brand_id': '<brand_id>',
'coupon_id': '<coupon_id>',
'expiration_date': '<expiration_date>',
'pass_title': '<pass_title>',
'status': 'active'
}'
Response
{
"success": true,
"url": "my.walletapp.co/pass/<pass_code>"
}
Modify points/balance
This api allows you to modify the amount of points and/or balance on a storecard. You can update points, balance, or both in a single request.
The endpoint accepts three optional fields that give the platform a richer picture of the transaction: description (what was charged), transaction_reference (idempotency key for safe retries), and vat_rate. Old integrations that don't send them continue to work unchanged — the platform falls back to a price-match heuristic against the organization's product catalogue, then to the terminal's name.
Required headers
- Name
Authorization- Type
- string
- Description
The scanner bearer token (device token). No specific abilities required.
Body parameters
- Name
points- Type
- numeric|Optional
- Description
A postive or negative number to add or subtract from the current points balance. At least one of
pointsorbalancemust be provided.
- Name
balance- Type
- numeric|Optional
- Description
A postive or negative number to add or subtract from the current monetary balance. At least one of
pointsorbalancemust be provided.
- Name
organization_identifier- Type
- string|Required
- Description
The identifier of the organization.
- Name
pass_code- Type
- string|Required
- Description
The pass code of the pass to modify.
- Name
external_reference- Type
- string|Optional
- Description
The external reference of the transaction. Echoed back as
transaction_idin the response.
- Name
description- Type
- string|Optional
- Description
Human-readable description of what was charged (e.g.
"Latte macchiato","Tier 1 punch"). Persisted to the storecard's transaction history and surfaced on the per-pass view in the dashboard. Maximum 191 characters. When omitted, the platform infers a description by matching the transaction amount against the organization's products, falling back to the terminal's name.
- Name
transaction_reference- Type
- string|Optional
- Description
Idempotency key. If a previous request for the same pass and storecard was POSTed with the same
transaction_reference, this request is treated as a retry: the balance and points are not changed a second time, no extra history row is written, and the response'swas_duplicatefield will betrue. Recommended for any device that retries on transient failures. Maximum 64 characters. When omitted, the platform generates a UUID server-side and returns it in the response so it can be reused for follow-up retries.
- Name
vat_rate- Type
- integer|Optional
- Description
VAT rate that applies to this line, expressed as a whole percentage between
0and21. Stored alongside the transaction for use by the platform's invoicing flows. Defaults apply when omitted.
Product-restricted storecards
Some storecards (typically postpaid / subscription / punch card categories) are configured by the organization to accept only a specific subset of products. When such a card is scanned, the platform tries to resolve the transaction to one of the allowed products using, in order: the request's description, the terminal's configured product, and a price-match against the catalogue.
If the resolved product is on the allowed list, the request proceeds as normal. Otherwise the request is refused with a 422 response — see the Restriction denied example on the right. Top-up scans (a positive balance value) always bypass the restriction.
Request
curl -X POST https://api.walletapp.co/passes/scan/storecard
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <scanner_device_token>"
-d "{
'points': 1,
'balance': 5.50,
'organization_identifier': '<organization_identifier>',
'pass_code': '<pass_code>',
'external_reference': '<external_reference>',
'description': 'Latte macchiato',
'transaction_reference': '<idempotency_key>',
'vat_rate': 21
}"
Response
{
"success": true,
"message": "Pass updated",
"transaction_id": "<transaction uuid>",
"transaction_reference": "<idempotency_key>",
"was_duplicate": false,
"points": 11,
"balance": 25.50
}
Response - Duplicate retry
{
"success": true,
"message": "Pass updated",
"transaction_id": "<transaction uuid>",
"transaction_reference": "<idempotency_key>",
"was_duplicate": true
}
Error - Restriction denied (product not allowed)
{
"message": "Product \"Latte macchiato\" is not allowed on this storecard. The card is restricted to: Espresso, Cappuccino.",
"error_code": "product_not_allowed",
"allowed_products": ["Espresso", "Cappuccino"],
"resolved_product_id": 42,
"resolved_description": "Latte macchiato"
}
Error - Restriction denied (cannot validate)
{
"message": "This card is restricted to specific products. The device did not provide enough information to validate the scan — set a description or transaction_reference on the request.",
"error_code": "cannot_validate_restriction",
"allowed_products": ["Espresso", "Cappuccino"],
"resolved_product_id": null,
"resolved_description": "Charged at: Counter-01"
}
