API FlavosoFondamentauxPagination et filtres
Pagination et filtres
Les listes sont paginées avec un curseur. Grâce aux filtres, à updated_since et à acknowledged, vous ne récupérez de façon fiable que les nouveautés.
Listes
Chaque liste a le même format : object: "list", les entrées dans data, ainsi que has_more et next_cursor. limit fixe le nombre d'entrées par page, de 1 à 100 (25 par défaut). Pour GET /events, le curseur s'appelle after et la valeur par défaut est 50.
S'il reste des entrées, la réponse indique has_more: true. Renvoyez alors next_cursor dans cursor jusqu'à ce que has_more soit faux. Le curseur est opaque : renvoyez-le tel quel, ne le construisez pas vous-même, ne le stockez pas.
# First page: the filters go along on every page
curl "https://api.flavoso.com/v1/orders?created_since=2026-10-03T22:00:00Z&created_until=2026-10-04T22:00:00Z&limit=100" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# has_more is true: pass next_cursor back, with the SAME filters
curl "https://api.flavoso.com/v1/orders?created_since=2026-10-03T22:00:00Z&created_until=2026-10-04T22:00:00Z&limit=100&cursor=NEXT_CURSOR" \
-H "Authorization: Bearer $ACCESS_TOKEN"Filtres
Pour donner plusieurs valeurs à un filtre, séparez-les par des virgules : status=pending,confirmed.
| Liste | Filtres | Ordre |
|---|---|---|
GET /orders | status, type, paid, acknowledged, updated_since, created_since, created_until, external_id | Les plus récemment modifiées d'abord ; avec updated_since, par updated_at croissant. |
GET /reservations | status, updated_since, starts_from, starts_until | Les plus récemment modifiées d'abord ; avec starts_from ou starts_until, par starts_at croissant. |
GET /menu/products | category_id (un identifiant ou none), available, external_id, updated_since | Toujours par updated_at croissant. |
GET /menu/categories, GET /menu/option-groups, GET /menu/options | external_id, updated_since | Toujours par updated_at croissant. |
GET /events | after (aussi latest), types (aussi menu.*) | Ordre croissant, le plus ancien d'abord. |
Un filtre inconnu de la liste renvoie 400 invalid_request avec param. acknowledged se rapporte à votre application : acknowledged=false désigne les commandes que votre application n'a pas encore prises en charge, sans limite dans le temps (voir plus bas). Une autre application voit son propre état.
Modèle : tout depuis le dernier passage
Sans webhooks, updated_since est la voie à suivre. Retenez le updated_at de la dernière commande traitée et interrogez régulièrement avec cette valeur ; elle est en UTC et convient telle quelle (un horodatage sans fuseau renvoie 400). Avec updated_since, les entrées arrivent par ordre croissant, le changement le plus ancien d'abord. Il en va de même pour les réservations et les listes de la carte, GET /menu/options compris.
updated_since une minute avant la dernière valeur) et repérez les doublons par id et updated_at. Sinon, un changement survenu dans la même seconde qu'un autre peut passer inaperçu entre deux interrogations.// Everything that changed since the last run, oldest change first. listAll() as above.
const OVERLAP_MS = 60_000;
export async function pollOrders(accessToken, state) {
const since = new Date(Date.parse(state.since) - OVERLAP_MS).toISOString();
for await (const order of listAll(accessToken, "/orders", { updated_since: since })) {
if (state.seen[order.id] === order.updated_at) continue; // handled in the overlap already
await handleOrder(order); // your code; must tolerate seeing an order again
state.seen[order.id] = order.updated_at;
if (order.updated_at > state.since) state.since = order.updated_at;
}
// Forget what lies before the overlap, then persist the state for the next run
for (const [id, at] of Object.entries(state.seen)) {
if (Date.parse(at) < Date.parse(state.since) - OVERLAP_MS) delete state.seen[id];
}
await saveState(state);
}Le plus sûr est de combiner les deux : le webhook est rapide, l'interrogation régulière rattrape ce qui s'est perdu. Plus simple encore, GET /events livre tout dans l'ordre.
Modèle : seulement ce qui n'est pas encore pris en charge
Pour une caisse, la question est rarement « qu'est-ce qui a changé ? » mais plutôt « qu'est-ce que je n'ai pas encore enregistré ? ». C'est exactement ce que renvoie GET /orders?acknowledged=false. Après l'enregistrement, vous marquez la commande comme prise en charge avec POST /orders/{id}/acknowledge, avec votre numéro de ticket comme external_id ; elle sort alors de la liste.
acknowledged=false n'a pas de limite dans le temps : la liste contient toutes les commandes que votre application n'a jamais prises en charge, y compris celles antérieures à la connexion, les commandes terminées et les commandes annulées. Limitez-la donc toujours avec created_since, par exemple avec le created_at de la connexion tiré de GET /me.Ce modèle résiste aux plantages : ce qui n'est pas pris en charge revient au passage suivant. Pour cela, votre enregistrement doit être idempotent par commande. Prenez en charge chaque commande que vous avez traitée, y compris une commande annulée que vous n'enregistrez pas : sinon, elle reste dans la liste et revient à chaque passage.
# The orders your app has not taken over yet, since the connection was made
# (created_at from GET /me). Without created_since the list has no time limit.
curl "https://api.flavoso.com/v1/orders?acknowledged=false&created_since=2026-10-04T17:40:00.000Z&limit=50" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# Booked into your system as receipt R-2026-000123: acknowledge it
curl -X POST https://api.flavoso.com/v1/orders/ORDER_ID/acknowledge \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ack-ORDER_ID" \
-d '{"external_id": "R-2026-000123"}'
# Not booked, for example because it was cancelled already: acknowledge it all the same,
# otherwise it stays in the list
curl -X POST https://api.flavoso.com/v1/orders/OTHER_ORDER_ID/acknowledge \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: ack-OTHER_ORDER_ID"Périodes
created_since et created_until limitent les commandes selon leur arrivée, par exemple pour un export quotidien ; starts_from et starts_until limitent les réservations selon leur début, par exemple pour le carnet de réservations d'une soirée. Ce sont dans les deux cas des horodatages en UTC : la journée de l'établissement commence à minuit dans son fuseau horaire, soit, à Berlin en été, à 22:00:00Z la veille. Le début est inclus, la fin non : created_since et starts_from incluent l'instant, created_until et starts_until l'excluent. Ainsi, les journées s'enchaînent sans trou.
Ce qui n'apparaît jamais dans une liste
- Les commandes en ligne non payées. Une commande avec paiement en ligne n'existe pour l'API qu'une fois le paiement confirmé, exactement comme dans le tableau de bord.
- Les réservations supprimées. Leur suppression est signalée par un dernier
reservation.updated.
Une question reste ouverte ? Écrivez à support@flavoso.com en indiquant l'identifiant de X-Request-Id. Il nous permet de retrouver votre requête dans le journal.