Skip to content
LoyaltyPending stamps

Loyalty

Pending stamps

Read and decide self-stamp requests.

Pilotv1

A customer who scans the shop's counter QR and taps Add my stamp leaves a pending stamp. It is not in the balance until someone confirms it, and it ends after 24 hours. Your service reads the queue and decides requests the way staff do on the scanner's Pending tab.

Paths are relative to https://app.revisit.cards/v1/developer.

Read the self-stamp queue

GET/pending-stamps

Scopeloyalty:read

Requires loyalty:read. A customer who scanned the shop's counter QR asked for a stamp; until it is decided it is a pending stamp: not in the balance, the visits or the scan count. The default is the waiting queue, oldest first (the counter's Pending tab). status reads the history instead (confirmed, rejected, expired, or all, newest first). A request past its 24 hours reads expired even before the clock wrote it down. Rows are limited to programs and branches the key may use. A customer is named by customerId, externalCustomerId (your id for them; null when you never synced them), the member code and the masked phone; the name, the whole number and the Order details a customer typed for staff are never returned.

Query

statusenum
One of pending, confirmed, rejected, expired, all. Default "pending".
programIduuid
branchIduuid
limitinteger
1 to 100. Default 50.
offsetinteger
Default 0.

Returns 200

hasMorebooleanRequired
itemsobject[]Required
items[].idstringRequired
items[].programIdstringRequired
items[].branchIdstringRequired
items[].branchNamestringRequired
The branch whose counter QR was scanned; a confirm credits the stamp here.
items[].customerIdstringRequired
items[].externalCustomerIdstring or nullRequired
Your id for the customer; null when your application never synced them.
items[].memberCodestringRequired
items[].maskedPhonestringRequired
Last four digits only (•••• 4821); empty for an erased customer.
items[].statusenumRequired
One of pending, confirmed, rejected, expired.
items[].requestedAtdate-timeRequired
items[].expiresAtdate-timeRequired
Twenty-four hours after the request.
items[].decidedAtdate-time or nullRequired
When it was decided; for an expired request, when its 24 hours ran out.
items[].decidedByenum or nullRequired
What kind of decider wrote the status, never who. One of integration, staff, expiry.
items[].transactionIdstring or nullRequired
The STAMP ledger row a confirm wrote.
limitintegerRequired
offsetintegerRequired
Request
curl "https://app.revisit.cards/v1/developer/pending-stamps" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": {
    "hasMore": false,
    "items": [
      {
        "branchId": "5eff65d7-d01c-4bd3-b26a-3d06b21fd005",
        "branchName": "Dhanmondi",
        "customerId": "eb83b9c0-5619-432d-b857-cef7fcf84edb",
        "decidedAt": "2026-11-03T08:41:12.000Z",
        "decidedBy": "integration",
        "expiresAt": "2026-11-03T08:41:12.000Z",
        "externalCustomerId": "user-42",
        "id": "d12cc02b-02fe-4a1f-83b0-5414e70fd99c",
        "maskedPhone": "•••• 4821",
        "memberCode": "K7M2QX",
        "programId": "d7595bbd-4342-41b4-9037-2e61a9f8403f",
        "requestedAt": "2026-11-03T08:41:12.000Z",
        "status": "pending",
        "transactionId": "add73925-4de9-412c-8cc2-582b074074ca"
      }
    ],
    "limit": 50,
    "offset": 0
  },
  "requestId": "69d43e88-e72c-4bc4-ae13-0f8d9362eab3",
  "success": true
}

Count the stamps waiting

GET/pending-stamps/count

Scopeloyalty:read

Requires loyalty:read. How many requests are waiting for a decision inside the key's limits (the number the scanner badge shows for those branches), optionally for one program or branch.

Query

programIduuid
branchIduuid

Returns 200

countintegerRequired
Request
curl "https://app.revisit.cards/v1/developer/pending-stamps/count" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": {
    "count": 12
  },
  "requestId": "4c508a8b-4530-47db-bb1b-1d5c2d683895",
  "success": true
}

Read one pending stamp and its status

GET/pending-stamps/{id}

Scopeloyalty:read

Requires loyalty:read. Any status. An id of another business, another environment or outside the key's limits is 404.

Path

iduuidRequired

Returns 200

idstringRequired
programIdstringRequired
branchIdstringRequired
branchNamestringRequired
The branch whose counter QR was scanned; a confirm credits the stamp here.
customerIdstringRequired
externalCustomerIdstring or nullRequired
Your id for the customer; null when your application never synced them.
memberCodestringRequired
maskedPhonestringRequired
Last four digits only (•••• 4821); empty for an erased customer.
statusenumRequired
One of pending, confirmed, rejected, expired.
requestedAtdate-timeRequired
expiresAtdate-timeRequired
Twenty-four hours after the request.
decidedAtdate-time or nullRequired
When it was decided; for an expired request, when its 24 hours ran out.
decidedByenum or nullRequired
What kind of decider wrote the status, never who. One of integration, staff, expiry.
transactionIdstring or nullRequired
The STAMP ledger row a confirm wrote.
Request
curl "https://app.revisit.cards/v1/developer/pending-stamps/e01b010d-2c65-48e1-83a0-acad79f8d3b4" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY"
Response
{
  "data": {
    "branchId": "5eff65d7-d01c-4bd3-b26a-3d06b21fd005",
    "branchName": "Dhanmondi",
    "customerId": "eb83b9c0-5619-432d-b857-cef7fcf84edb",
    "decidedAt": "2026-11-03T08:41:12.000Z",
    "decidedBy": "integration",
    "expiresAt": "2026-11-03T08:41:12.000Z",
    "externalCustomerId": "user-42",
    "id": "d12cc02b-02fe-4a1f-83b0-5414e70fd99c",
    "maskedPhone": "•••• 4821",
    "memberCode": "K7M2QX",
    "programId": "d7595bbd-4342-41b4-9037-2e61a9f8403f",
    "requestedAt": "2026-11-03T08:41:12.000Z",
    "status": "pending",
    "transactionId": "add73925-4de9-412c-8cc2-582b074074ca"
  },
  "requestId": "79d1a36e-b5de-46f8-aa16-68ac0c6f8c31",
  "success": true
}

Confirm a waiting stamp

POST/pending-stamps/{id}/confirm

Scopeloyalty:write

Requires loyalty:write and an Idempotency-Key. Runs the counter's own stamp earning for one stamp at the branch whose QR the customer scanned (row lock, plan gate, scan, visit, wallet banner, milestones); the stamp row has no user behind it and the audit row names your application and key. A request past its 24 hours is 409 PENDING_EXPIRED; one someone (staff, or any application) already decided is 409 PENDING_DECIDED and nothing changes; a card that no longer collects stamps is 409 NOT_A_STAMP_CARD; a full card is 409 REWARD_READY. Racing decisions apply one result. Retrying your own decision, under any key or after rotating the credential, answers the original with duplicate: true and writes nothing more.

Send an Idempotency-Key header. Safe to retry.

Path

iduuidRequired

Returns 200

idstringRequired
programIdstringRequired
branchIdstringRequired
branchNamestringRequired
The branch whose counter QR was scanned; a confirm credits the stamp here.
customerIdstringRequired
externalCustomerIdstring or nullRequired
Your id for the customer; null when your application never synced them.
memberCodestringRequired
maskedPhonestringRequired
Last four digits only (•••• 4821); empty for an erased customer.
statusenumRequired
One of pending, confirmed, rejected, expired.
requestedAtdate-timeRequired
expiresAtdate-timeRequired
Twenty-four hours after the request.
decidedAtdate-time or nullRequired
When it was decided; for an expired request, when its 24 hours ran out.
decidedByenum or nullRequired
What kind of decider wrote the status, never who. One of integration, staff, expiry.
transactionIdstring or nullRequired
The STAMP ledger row a confirm wrote.
balanceinteger or nullRequired
The card's stamp count right after a confirm; null for a reject.
duplicatebooleanRequired
True when your application had already made this decision; nothing changed and this is the original result.

Errors

  • 409PENDING_EXPIREDthe pending self-stamp was not decided within 24 hours, so it has ended. Nothing was stamped.
  • 409PENDING_DECIDEDsomeone (staff, or this or another application) already confirmed or rejected this pending self-stamp. The decision is final and nothing changed.
  • 409NOT_A_STAMP_CARDthe card no longer collects stamps, so a waiting stamp cannot be added. Nothing changed.
  • 409REWARD_READY
Request
curl -X POST "https://app.revisit.cards/v1/developer/pending-stamps/e01b010d-2c65-48e1-83a0-acad79f8d3b4/confirm" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8e6a9880"
Response
{
  "data": {
    "balance": 7,
    "branchId": "5eff65d7-d01c-4bd3-b26a-3d06b21fd005",
    "branchName": "Dhanmondi",
    "customerId": "eb83b9c0-5619-432d-b857-cef7fcf84edb",
    "decidedAt": "2026-11-03T08:41:12.000Z",
    "decidedBy": "integration",
    "duplicate": false,
    "expiresAt": "2026-11-03T08:41:12.000Z",
    "externalCustomerId": "user-42",
    "id": "d12cc02b-02fe-4a1f-83b0-5414e70fd99c",
    "maskedPhone": "•••• 4821",
    "memberCode": "K7M2QX",
    "programId": "d7595bbd-4342-41b4-9037-2e61a9f8403f",
    "requestedAt": "2026-11-03T08:41:12.000Z",
    "status": "pending",
    "transactionId": "add73925-4de9-412c-8cc2-582b074074ca"
  },
  "requestId": "b59b45d3-0e61-433c-b6f2-5908f9ede78a",
  "success": true
}

Reject a waiting stamp

POST/pending-stamps/{id}/reject

Scopeloyalty:write

Requires loyalty:write and an Idempotency-Key. Writes no stamp and no scan; the customer's one request for the day stays used. Same refusals and retries as confirm (balance is null).

Send an Idempotency-Key header. Safe to retry.

Path

iduuidRequired

Returns 200

idstringRequired
programIdstringRequired
branchIdstringRequired
branchNamestringRequired
The branch whose counter QR was scanned; a confirm credits the stamp here.
customerIdstringRequired
externalCustomerIdstring or nullRequired
Your id for the customer; null when your application never synced them.
memberCodestringRequired
maskedPhonestringRequired
Last four digits only (•••• 4821); empty for an erased customer.
statusenumRequired
One of pending, confirmed, rejected, expired.
requestedAtdate-timeRequired
expiresAtdate-timeRequired
Twenty-four hours after the request.
decidedAtdate-time or nullRequired
When it was decided; for an expired request, when its 24 hours ran out.
decidedByenum or nullRequired
What kind of decider wrote the status, never who. One of integration, staff, expiry.
transactionIdstring or nullRequired
The STAMP ledger row a confirm wrote.
balanceinteger or nullRequired
The card's stamp count right after a confirm; null for a reject.
duplicatebooleanRequired
True when your application had already made this decision; nothing changed and this is the original result.
Request
curl -X POST "https://app.revisit.cards/v1/developer/pending-stamps/e01b010d-2c65-48e1-83a0-acad79f8d3b4/reject" \
  -H "Authorization: Bearer $DEVELOPER_API_KEY" \
  -H "Idempotency-Key: 5f0c2a8e-7b1d-4c3e-9a6f-0d4b8e81c903"
Response
{
  "data": {
    "balance": 7,
    "branchId": "5eff65d7-d01c-4bd3-b26a-3d06b21fd005",
    "branchName": "Dhanmondi",
    "customerId": "eb83b9c0-5619-432d-b857-cef7fcf84edb",
    "decidedAt": "2026-11-03T08:41:12.000Z",
    "decidedBy": "integration",
    "duplicate": false,
    "expiresAt": "2026-11-03T08:41:12.000Z",
    "externalCustomerId": "user-42",
    "id": "d12cc02b-02fe-4a1f-83b0-5414e70fd99c",
    "maskedPhone": "•••• 4821",
    "memberCode": "K7M2QX",
    "programId": "d7595bbd-4342-41b4-9037-2e61a9f8403f",
    "requestedAt": "2026-11-03T08:41:12.000Z",
    "status": "pending",
    "transactionId": "add73925-4de9-412c-8cc2-582b074074ca"
  },
  "requestId": "38d21bb3-51ea-45c2-9fdd-b5eeae305205",
  "success": true
}