Quickstart
Create a receipt right after the customer pays. The API returns a short URL — encode it onto your puck (or let us provision the puck for you).
curl https://api.tapreceipt.com/v1/receipts \
-H "Authorization: Bearer sk_live_********" \
-H "Content-Type: application/json" \
-d '{
"merchant_id": "mer_018E7Q",
"currency": "EUR",
"total_minor": 940,
"lines": [
{ "name": "Filterkoffie", "qty": 1, "price_minor": 380 },
{ "name": "Kaneelbroodje", "qty": 1, "price_minor": 350 },
{ "name": "Bio sinaasappel","qty": 1, "price_minor": 210 }
]
}'You get back a receipt object with a public url. Write that URL onto the puck once at provisioning — every subsequent tap rotates the signature automatically.
Authentication
All requests use a Bearer token. Test keys begin with sk_test_, live keys with sk_live_. Rotate from the dashboard at any time — the previous key keeps working for ten minutes.
Authorization: Bearer sk_live_5p9d2a...
Webhooks
Subscribe to events at the moment they happen — taps, wallet saves, deletions, tamper alerts. Each event is signed with HMAC-SHA256.
POST /your-handler
{
"id": "evt_01HZRY9C...",
"type": "receipt.tapped",
"created": 1746200400,
"data": {
"receipt_id": "rcp_018E7Q...",
"puck_id": "pck_LDN_03",
"country": "NL"
}
}Verify by comparing the TapReceipt-Signature header against an HMAC of the raw request body.
SDKs
Node / TypeScript
npm i tapreceipt
Python
pip install tapreceipt
Go
go get github.com/tapreceipt/go
Ruby
gem install tapreceipt
Errors
The API returns conventional HTTP codes. The body always includes a type and human-readable message.
{
"error": {
"type": "validation_error",
"param": "total_minor",
"message": "must be a non-negative integer"
}
}