API FlavosoWebhooks et événementsRécupérer les événements

Récupérer les événements

GET /events renvoie les mêmes événements que les webhooks, mais c'est vous qui les récupérez : pour les caisses sans adresse publique et pour rattraper le retard après une panne.

Quand récupérer plutôt que recevoir

  • Caisse sans adresse publique : un programme dans l'établissement, derrière un routeur, ne peut pas recevoir de webhooks. Il récupère donc lui-même les événements.
  • Rattrapage : après une panne, un webhook désactivé ou une erreur dans votre traitement.
  • Rapprochement : comme seconde voie, en complément du webhook, pour s'assurer que rien ne manque.

Les événements sont créés pour chaque connexion active, même si votre application n'a aucun webhook.

Récupérer

GET /events renvoie les événements de l'établissement que votre connexion peut voir, ainsi que les événements app.* de cette connexion, par ordre croissant, le plus ancien d'abord, jusqu'à 30 jours en arrière. app.disconnected n'apparaît jamais ici : les jetons de la connexion cessent de fonctionner dès la déconnexion. Vous reconnaissez une déconnexion à un 401 suivi de invalid_grant au rafraîchissement.

ParamètreSignification
afterUn identifiant d'événement (evt_…) : seulement les événements postérieurs. Sans after, la lecture commence au plus ancien événement conservé des 30 derniers jours, y compris des événements antérieurs à la connexion. latest : aucun événement, seulement la position qui suit le plus récent, pour démarrer avec une nouvelle connexion. Avec un identifiant que cet établissement ne connaît pas (ou plus), par exemple parce qu'il date de plus de 30 jours, la lecture reprend au plus ancien événement conservé, avec gap: true.
typesTypes séparés par des virgules, avec * pour tout un groupe : order.created,menu.*.
limit1 à 100, 50 par défaut.

La réponse est une liste avec data, has_more, next_after et gap. next_after est la valeur de after qui permet de poursuivre la lecture à partir de là ; elle est toujours renseignée, même quand il n'y a eu aucun événement. gap: true indique que votre after n'était plus conservé : des événements ont pu être manqués, resynchronisez avec GET /orders?updated_since=… et les autres listes que vous utilisez.

{
  "object": "list",
  "data": [
    {
      "id": "evt_2bf5a9b06b75442a9244e884a1acfc57",
      "object": "event",
      "type": "reservation.updated",
      "created_at": "2026-10-04T17:45:10.410Z",
      "api_version": "2026-10-08",
      "livemode": true,
      "tenant_id": "7d0e5b8a-3c41-4f2e-9a6b-1e2d3c4b5a69",
      "connection_id": "4b3f7c1e-9a2d-4e8b-b5f6-0c1d2e3f4a5b",
      "data": {
        "object": {
          "object": "reservation",
          "id": "9c8b7a6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
          "code": "R7K2Q9",
          "status": "confirmed",
          "starts_at": "2026-10-10T17:30:00.000Z",
          "duration_minutes": 120,
          "party_size": 4,
          "table_ids": [
            "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e"
          ],
          "source": "staff",
          "guest_name": "Alex Example",
          "note": "Window seat if possible",
          "created_at": "2026-10-04T12:00:00.000Z",
          "updated_at": "2026-10-04T12:00:00.000Z"
        },
        "previous_status": "pending",
        "changed": [
          "status"
        ]
      }
    }
  ],
  "has_more": false,
  "next_after": "evt_2bf5a9b06b75442a9244e884a1acfc57",
  "gap": false
}

La boucle d'interrogation

  1. 1

    Où vous en êtes

    Lisez la valeur after enregistrée pour cette connexion. Pour une nouvelle connexion, utilisez latest : sans after, vous recevriez les 30 derniers jours, y compris des événements antérieurs à la connexion.

  2. 2

    Récupérer et traiter

    Récupérez les événements et traitez chacun d'eux. Le traitement repère les doublons par id.

  3. 3

    Avancer

    N'enregistrez durablement next_after (par connexion) qu'une fois la page entière traitée.

  4. 4

    Continuer ou attendre

    Si has_more est vrai, récupérez immédiatement la page suivante. Sinon, attendez quelques secondes.

# A new connection starts now: no events, only next_after. Store it for this connection.
# (Without after you would get the last 30 days, also events from before the connection.)
curl "https://api.flavoso.com/v1/events?after=latest" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Then always from where you stopped: after = next_after of the previous page.
# "gap": true means that after was no longer kept: resync with GET /orders.
curl "https://api.flavoso.com/v1/events?types=order.*,menu.*,store.*,app.*&limit=100&after=evt_2bf5a9b06b75442a9244e884a1acfc57" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Une interrogation toutes les 5 à 30 secondes reste largement dans la limite de 120 requêtes par minute et par connexion.

Un événement précis

GET /events/{id} renvoie un seul événement, par exemple pour consulter un identifiant vu dans le journal des webhooks.

curl https://api.flavoso.com/v1/events/evt_2bf5a9b06b75442a9244e884a1acfc57 \
  -H "Authorization: Bearer $ACCESS_TOKEN"

La même enveloppe

Un événement récupéré est la même enveloppe que dans le webhook : le même id, les mêmes champs, le même data, figé à la première lecture ou au premier envoi. Si vous utilisez les deux, vous repérez les doublons par id. La signature n'existe que pour les webhooks ; lors de la récupération, c'est le jeton qui prouve qui demande.

Conservation

Les événements sont conservés 30 jours. Pour les données plus anciennes, passez par les listes, par exemple GET /orders avec updated_since. Un after plus ancien n'est pas une erreur : la réponse reprend au plus ancien événement conservé et indique gap: true.

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.