POS Integration Overview
Connect your point-of-sale system, e-commerce platform, or any backend service to Loyalite using the POS API. All endpoints use simple API key authentication — no OAuth flows, no JWTs.
Base URL
https://{your-slug}.loyalite.appReplace {your-slug} with your organization's subdomain (e.g. kahveci.loyalite.app).
Authentication
Every request must include your secret key in the X-Api-Key header.
X-Api-Key: sk_live_xxxxxxxxxxxxxxxxYou can find your secret key in Merchant App → Settings → Integrations.
Keep it secret. Treat your API key like a password. If it's ever exposed, rotate it immediately from the Integrations settings page.
Alternatively, you can pass the key as a Bearer token:
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxRate Limits
| Endpoint group | Limit |
|---|---|
/webhook/pos, /webhook/redeem, /webhook/coupons/redeem | 60 requests / minute |
/webhook/customer | 30 requests / minute |
When the limit is exceeded the server returns HTTP 429 with {"error": "too many requests"}.
Error Format
All errors follow a consistent JSON shape:
{
"error": "machine_readable_code"
}Common error codes:
| Code | HTTP | Meaning |
|---|---|---|
invalid or missing API key | 401 | Wrong or missing X-Api-Key |
customer_not_found | 404 | No customer with that code in your org |
insufficient_balance | 422 | Not enough stamps or points to redeem |
email_required | 422 | email field missing on enrollment |
consent_terms_required | 422 | Customer must consent to terms |
subscription_required | 402 | Your subscription has expired |
Endpoints at a Glance
| Method | Path | Purpose |
|---|---|---|
GET | /webhook/customer | Look up a customer by customer_code or QR payload |
POST | /webhook/customer | Enroll a new customer (or look up existing) |
POST | /webhook/pos | Earn stamps or points for a purchase |
POST | /webhook/redeem | Redeem stamps or points |
POST | /webhook/coupons/redeem | Redeem a reward coupon (stamp campaigns) |
Key asymmetries
card_type defaults differ by endpoint:
/webhook/pos(earn) —card_typedefaults to"point"when omitted/webhook/redeem—card_typedefaults to"stamp"when omitted
Always pass card_type explicitly to avoid surprises.
Subscription gating:
/webhook/pos(earn) — not subscription-gated; always works regardless of subscription status/webhook/redeem— subscription-gated; returns402 subscription_requiredif the subscription is expired or cancelled