POS API
A server-to-server API so a cash register / POS can award loyalty points for a sale and look up a customer's balance. Give your POS provider this page plus an API key (Dashboard → Settings → Integrations → POS API).
Authentication
Send the API key as a Bearer token. The full key is shown once at creation; only a hash is stored and keys can be revoked anytime. Every request is scoped to the key's organization.
Authorization: Bearer lp_live_xxxxxxxxxxxxxxxx
Base URL: https://vazolo.com/api/v1Errors return a JSON body and an HTTP status code. Basic rate limiting applies (HTTP 429 when exceeded).
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key." } }POST/api/v1/transactions
Award points for a purchase. Points = amount × earn-rate × any active bonus × the customer's tier multiplier (same as the in-store scan). Idempotent via external_ref: retrying with the same value never awards points twice.
curl -X POST https://vazolo.com/api/v1/transactions \
-H "Authorization: Bearer lp_live_…" \
-H "Content-Type: application/json" \
-d '{
"identifier": { "type": "loyalty_code", "value": "F55EA00D" },
"amount_cents": 2500,
"external_ref": "order-12345"
}'identifier.type is loyalty_code or email. amount_cents is the total in cents. Response:
{
"customer": { "loyalty_code": "F55EA00D", "name": "Sophie", "points_balance": 1265 },
"points_added": 25,
"duplicate": false,
"bonus_applied": "Happy hour"
}Errors: 400 invalid request · 401 bad key · 404 customer not found · 422 amount too low · 429 rate limited.
GET/api/v1/customers/:code
Look up a customer's balance by loyalty code.
curl https://vazolo.com/api/v1/customers/F55EA00D \
-H "Authorization: Bearer lp_live_…"
{
"customer": {
"loyalty_code": "F55EA00D",
"name": "Sophie",
"points_balance": 1265,
"lifetime_points": 4300
}
}GET/api/v1/rewards
List the business's active rewards (id, name, description, points cost, icon).
{
"rewards": [
{ "id": "…", "name": "Free coffee", "description": null, "points_cost": 50, "icon": "☕" }
]
}POST/api/v1/redemptions
Redeem a reward for a customer. Validates balance, tier and the reward offer atomically.
curl -X POST https://vazolo.com/api/v1/redemptions \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{
"identifier": { "type": "loyalty_code", "value": "F55EA00D" },
"reward_id": "…"
}'
{ "customer": { "loyalty_code": "F55EA00D", "name": "Sophie", "points_balance": 1215 },
"reward_id": "…" }Errors: 404 customer/reward not found · 422 insufficient_points · 422 tier_locked.
POST/api/v1/customers
Create (register) a customer. If the email already exists, the existing customer is returned with existing: true.
curl -X POST https://vazolo.com/api/v1/customers \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{ "name": "Sophie", "email": "sophie@example.com", "birthday": "1990-05-01" }'
{ "customer": { "loyalty_code": "A1B2C3D4", "name": "Sophie", "email": "sophie@example.com", "points_balance": 0 },
"existing": false }GET/api/v1/customers?email=…
Look up a customer by email or loyalty_code query parameter.
POST/api/v1/orders
Award points for an order with line items. Points = base (order total × earn-rate × bonus × tier) plus any matching product earn rules (bulk / category / specific product, configured in the dashboard). Idempotent via external_ref.
curl -X POST https://vazolo.com/api/v1/orders \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{
"identifier": { "type": "loyalty_code", "value": "F55EA00D" },
"external_ref": "order-12345",
"line_items": [
{ "name": "Cappuccino", "category": "drinks", "quantity": 2, "unit_price_cents": 350 },
{ "name": "Cake", "category": "food", "quantity": 1, "unit_price_cents": 450 }
]
}'
{ "customer": { "loyalty_code": "F55EA00D", "name": "Sophie", "points_balance": 1300 },
"points_added": 26, "base_points": 11, "product_points": 15,
"rules_applied": ["2 cappuccinos = 15 pts"], "duplicate": false }name and category are matched case-insensitively against your earn rules. If amount_centsis omitted, it's summed from the line items.
GET/api/v1/discounts
Read the redemption configuration (rate, minimum, step, currency), so a webshop can show “your points = €x” before redeeming.
{ "enabled": true, "points_per_unit": 100, "min_points": 100,
"step_points": 100, "currency": "EUR" }POST/api/v1/discounts
Convert points into a one-time discount voucher (a code plus an amount), so a webshop can apply the discount at checkout. Deducts the points immediately and validates the rate, minimum and step of your flexible redemption settings. Enable flexible redemption in the dashboard first.
curl -X POST https://vazolo.com/api/v1/discounts \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{
"identifier": { "type": "email", "value": "sophie@example.com" },
"points": 300
}'
{ "customer": { "loyalty_code": "F55EA00D", "name": "Sophie", "points_balance": 1000 },
"discount": { "voucher_id": "…", "code": "A1B2C3", "amount_cents": 300, "points_spent": 300 } }Each successful call deducts points and issues a new voucher — call it on a deliberate redeem action, not in a retry loop. Errors: 404 customer_not_found · 422 flex_disabled · 422 invalid_amount · 422 insufficient_points.
POST/api/v1/discounts/refund
Refund the points of a discount voucher — e.g. when the order it was redeemed on is cancelled or refunded. Idempotent (a second refund returns points_refunded: 0).
curl -X POST https://vazolo.com/api/v1/discounts/refund \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{ "code": "A1B2C3" }'
{ "points_refunded": 300, "new_balance": 390 }POST/api/v1/points
Award a flat number of points — a bonus, a reward for a review, or a campaign. Counts as earned points (so it feeds tier progress). Idempotent via external_ref.
curl -X POST https://vazolo.com/api/v1/points \
-H "Authorization: Bearer lp_live_…" -H "Content-Type: application/json" \
-d '{
"identifier": { "type": "email", "value": "sophie@example.com" },
"points": 50, "note": "Product review", "external_ref": "review-123"
}'
{ "customer": { "loyalty_code": "F55EA00D", "name": "Sophie", "points_balance": 1300 },
"points_added": 50, "duplicate": false }Webhooks
Get notified in real time when something happens. Add an endpoint in Dashboard → Settings → Integrations → Webhooks and pick the events. Each delivery is a POST with a JSON body, signed with HMAC-SHA256 in the X-Vazolo-Signature header (HMAC of the raw body using your signing secret), with retries on temporary failures. Works great with a Zapier / Make “Catch Hook”.
Events: customer.created, transaction.created, reward.redeemed, discount.created.
POST https://your-endpoint.example.com
X-Vazolo-Event: transaction.created
X-Vazolo-Signature: 9f86d081884c7d65…
{ "event": "transaction.created",
"created_at": "2026-06-24T12:00:00.000Z",
"organization_id": "…",
"data": { "loyalty_code": "F55EA00D", "name": "Sophie",
"points_added": 26, "points_balance": 1300 } }To verify: compute the HMAC-SHA256 of the raw request body with your signing secret and compare it to the signature header.