API de FlavosoWebhooks y eventosRecoger eventos

Recoger eventos

GET /events devuelve los mismos eventos que los webhooks, para recogerlos: para cajas sin dirección pública y para ponerse al día tras un fallo.

Cuándo recoger en lugar de recibir

  • Caja sin dirección pública: un programa en el local, detrás de un router, no puede recibir webhooks. En su lugar, recoge los eventos.
  • Ponerse al día: tras un fallo, un webhook desactivado o un error en tu procesamiento.
  • Conciliación: como segunda vía junto al webhook, que garantiza que no falte nada.

Los eventos se producen para cada conexión activa, aunque tu app no tenga ningún webhook.

Recoger

GET /events devuelve los eventos del negocio que tu conexión puede ver, además de los eventos app.* de esa conexión, en orden ascendente, el más antiguo primero, hasta 30 días atrás. app.disconnected nunca llega aquí: con la desconexión, los tokens de la conexión dejan de ser válidos. Reconoces una desconexión por un 401 seguido de invalid_grant al renovar.

ParámetroSignificado
afterUn identificador de evento (evt_…): solo lo que vino después. Sin after, empieza por el evento conservado más antiguo de los últimos 30 días, incluidos los eventos anteriores a la conexión. latest: ningún evento, solo la posición tras el más reciente, para empezar una conexión nueva. Con un identificador que este negocio no tiene (o ya no tiene), por ejemplo porque tiene más de 30 días, la lista sigue por el evento conservado más antiguo y devuelve gap: true.
typesTipos separados por comas, con * para un grupo entero: order.created,menu.*.
limitDe 1 a 100, por defecto 50.

La respuesta es una lista con data, has_more, next_after y gap. next_after es el valor para after con el que seguir leyendo desde ahí; siempre está presente, incluso cuando no hubo eventos. gap: true indica que tu after ya no se conservaba: puede que falten eventos, así que vuelve a sincronizar con GET /orders?updated_since=… y las demás listas que uses.

{
  "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
}

El bucle de consulta

  1. 1

    Dónde estás

    Lee el valor de after que guardaste para esta conexión. En una conexión nueva, usa latest: sin after recibirías los últimos 30 días, incluidos los eventos anteriores a la conexión.

  2. 2

    Obtener y procesar

    Obtén los eventos y procesa cada uno. El procesamiento reconoce los duplicados por el id.

  3. 3

    Avanzar

    Solo cuando hayas procesado la página entera, guarda next_after de forma permanente, por conexión.

  4. 4

    Seguir o esperar

    Si has_more es verdadero, pide enseguida la página siguiente. Si no, espera unos segundos.

# 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"

Consultar cada 5 a 30 segundos entra de sobra en el límite de 120 solicitudes por minuto y conexión.

Un solo evento

GET /events/{id} devuelve un evento, por ejemplo para consultar un identificador del registro de webhooks.

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

El mismo sobre

Un evento recogido es el mismo sobre que en el webhook: el mismo id, los mismos campos, el mismo data, congelado en la primera lectura o envío. Si usas ambos, reconoces los duplicados por el id. La firma solo existe en el webhook; al recoger, el token demuestra quién pregunta.

Conservación

Los eventos se conservan 30 días. Lo que sea más antiguo lo recuperas con las listas, por ejemplo GET /orders con updated_since. Un after más antiguo no es un error: la respuesta sigue por el evento conservado más antiguo e indica gap: true.

¿Algo no ha quedado claro? Escribe a support@flavoso.com e indica el identificador de X-Request-Id. Así podremos encontrar tu solicitud en el registro.