API-referentie
API-overzicht
De Puntjes API is een RESTful JSON API. Elk endpoint verwacht een OAuth2 bearer token en geeft alleen de gegevens van de handelaar waarvoor dat token is uitgegeven.
Basis-URL
https://puntjes.app/api/v1
Alle endpoints in deze referentie staan onder deze basis-URL.
Requestformaat
- Gebruik
Content-Type: application/jsonvoor request bodies - Stuur
Authorization: Bearer {token}mee bij elk request (zie Authenticatie) - Alle geldbedragen zijn in eurocenten (bv.
2500= EUR 25,00) - Alle puntwaarden zijn gehele getallen
Response-envelope
Elke geslaagde response zit in een data-envelope:
{
"data": {
"id": 1,
"first_name": "Jan",
"last_name": "De Vries"
}
}
Gepagineerde endpoints zetten de hele pagina binnen die envelope, dus de items staan twee
niveaus diep, in data.data, naast data.links en data.meta. GET /rewards is de enige
lijst zonder pagina's: daar is data meteen de array.
{
"data": {
"data": [...],
"links": {
"first": "...",
"last": "...",
"prev": null,
"next": "..."
},
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 72
}
}
}
Volg data.links.next zoals je die krijgt. Die bevat de queryparameters die je zelf
hebt meegestuurd (filters, sorteervolgorde en per_page), dus pagina 2 van een
gefilterde lijst heeft hetzelfde filter als pagina 1. Bouw je de URL zelf op uit
data.meta.current_page, dan raak je ze kwijt: een doorloop die met per_page=5
start, krijgt bij het tweede request stilzwijgend 15 rijen terug.
Foutresponses
Elke fout heeft dezelfde vorm:
{
"error": {
"code": "CUSTOMER_NOT_FOUND",
"message": "No customer found with the given identifier.",
"status": 404,
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Validatiefouten (422) bevatten een details-veld:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The given data was invalid.",
"status": 422,
"request_id": "...",
"details": {
"email": ["The email field must be a valid email address."],
"identifiers.0.type": ["The identifier type must be one of: email, loyalty_card."]
}
}
}
Zie Foutafhandeling voor de volledige lijst met foutcodes.
Idempotentie
Elk endpoint dat punten verplaatst vereist een idempotency_key (max. 255
tekens). Stuur je een request opnieuw met een sleutel die je al gebruikt hebt,
dan krijg je de oorspronkelijke resource terug en wordt er niets een tweede keer
verwerkt. Deze aanroepen zijn dus veilig te herhalen na een netwerkfout of een
time-out:
| Endpoint | Sleutel uniek per | Wat een herhaling teruggeeft |
|---|---|---|
POST /transactions | handelaar | De oorspronkelijke transactie; geen punten opnieuw toegekend |
POST /redemptions | handelaar | De oorspronkelijke verzilvering; geen punten opnieuw afgeschreven, voorraad ongewijzigd |
POST /customers/{customer}/wallet/adjust | wallet van de klant | De oorspronkelijke grootboekregel; saldo niet opnieuw verplaatst |
Gebruik een waarde die de handeling in jouw eigen systeem aanwijst (een order-ID, of een UUID die je één keer per afrekening genereert en bij elke retry hergebruikt). Willekeurige waarden die bij elke poging veranderen maken idempotentie zinloos.
Dat vangt netwerkproblemen op, en kassasystemen die hetzelfde request twee keer versturen.
Overzicht van endpoints
| Methode | Endpoint | Beschrijving |
|---|---|---|
GET | /me | Branding van de handelaar ophalen |
GET | /customers/lookup | Een klant opzoeken |
POST | /customers | Een klant registreren |
PUT PATCH | /customers/by-external-id/{externalId} | Een klant bijwerken |
POST | /customers/link-external-id | Een external ID koppelen |
POST | /customers/by-external-id/{externalId}/send-card | De klantenkaart versturen via je eigen id |
POST | /customers/{customer}/send-card | De klantenkaart naar de klant sturen |
GET | /customers/{customer} | Klantgegevens ophalen |
POST | /transactions | Een transactie indienen |
GET | /customers/{customer}/wallet | Wallet-saldo ophalen |
GET | /customers/{customer}/ledger | Grootboekregels opvragen |
GET | /customers/{customer}/redemptions | De verzilveringen van een klant opvragen |
GET | /customers/{customer}/vouchers | De open bonnen van een klant opvragen |
GET | /customers/{customer}/wallet-pass | Een wallet-pas downloaden |
GET | /customers/{customer}/transactions | Klanttransacties weergeven |
POST | /customers/{customer}/wallet/adjust | Wallet-saldo aanpassen |
GET | /campaigns | Campagnes weergeven |
GET | /branches | Actieve vestigingen ophalen |
GET | /rewards | Beloningen weergeven |
POST | /redemptions | Een beloning verzilveren |
GET | /redemptions/{code} | Een verzilvering opzoeken |
POST | /redemptions/{code}/verify | Een verzilvering verifiëren |
GET | /vouchers/{code} | Een bon opzoeken |
POST | /vouchers/{code}/verify | Een bon verifiëren |
GET | /products | Producten weergeven |
POST | /products | Een product aanmaken |
POST | /products/batch | Producten in bulk upserten |
POST | /products/{externalId}/reward | Een beloning maken van een product |
GET | /products/{externalId} | Een product ophalen |
PUT | /products/{externalId} | Een product aanmaken of bijwerken (upsert) |
PATCH | /products/{externalId} | Een product bijwerken |
DELETE | /products/{externalId} | Een product verwijderen |
Branding van de handelaar ophalen
GET /api/v1/me
Geeft de branding terug van de handelaar waar je token bij hoort. Kleur er een kassascherm of een webshopwidget mee zoals de klanten van die handelaar het al kennen, zonder per handelaar iets hard te coderen.
default_branch is de vestiging waar je API-client standaard op staat, als { "external_id", "name", "type" }.
Het is null als de API-client er geen heeft. Een vestiging die is gedeactiveerd, wordt nog steeds genoemd.
Een schrijfactie die op de standaard terugvalt, kan haar toch weigeren: een nieuwe transactie bij een
gedeactiveerde vestiging geeft BRANCH_INACTIVE.
Lees het veld om je eigen vestigingssleutel te kennen, in plaats van een kopie in je configuratie te bewaren.
Example request
curl https://puntjes.app/api/v1/me \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
{
"data": {
"display_name": "Koffiebar De Hoek",
"logo_url": "https://cdn.example.com/logo.png",
"brand_color_primary": "#4F46E5",
"brand_color_accent": "#06B6D4",
"default_branch": {
"external_id": "webshop",
"name": "Webshop",
"type": "online"
}
}
}
Actieve vestigingen ophalen
GET /api/v1/branches
Geeft de actieve vestigingen van je zaak terug, in de volgorde die jij aanhoudt. Een vestiging
die is gedeactiveerd, staat er niet bij. De lijst is niet gepagineerd: data is de kale array.
Vergelijk de vestigingssleutel die je hebt ingesteld met de external_id-waarden hier, of toon de
namen aan de kassier.
Example request
curl https://puntjes.app/api/v1/branches \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
{
"data": [
{
"external_id": "webshop",
"name": "Webshop",
"type": "online"
}
]
}