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.

Le curseur ne conserve pas les filtres. Renvoyez les mêmes filtres pour chaque page, sinon vous parcourez une autre liste.
# 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.

ListeFiltresOrdre
GET /ordersstatus, type, paid, acknowledged, updated_since, created_since, created_until, external_idLes plus récemment modifiées d'abord ; avec updated_since, par updated_at croissant.
GET /reservationsstatus, updated_since, starts_from, starts_untilLes plus récemment modifiées d'abord ; avec starts_from ou starts_until, par starts_at croissant.
GET /menu/productscategory_id (un identifiant ou none), available, external_id, updated_sinceToujours par updated_at croissant.
GET /menu/categories, GET /menu/option-groups, GET /menu/optionsexternal_id, updated_sinceToujours par updated_at croissant.
GET /eventsafter (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.

Prévoyez une minute de chevauchement (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.