Aller au contenu
Floweet
Accès pro

Pagination par curseur

Les listes répondent { data, nextCursor, hasMore } : comment passer d'une page à l'autre, lire une liste entière et ce que renvoient les recherches.

api.floweet.com/v1 · Contrat 1.0.0-beta.1 · Bêta

Sections · Pagination

Les listes (stations carburant, bornes de recharge, prospects, simulations) sont paginées par curseur. Chaque page répond { data, nextCursor, hasMore }.

Paramètres

  • limit : éléments par page, de 1 à 100 (20 par défaut).
  • cursor : le nextCursor de la page précédente ; absent pour la première page.

La page

GET/v1/fuel-stationsScope fuel-stations:read
Requête
curl "https://api.floweet.com/v1/fuel-stations?fuels=B7%2CE85&country=FR" \
  -H "Authorization: Bearer $FLOWEET_API_KEY"
Réponse 200
{
  "data": [
    {
      "id": "28898708-4170-48bb-a3f5-e9b0d5d7ee53",
      "name": "Carrefour",
      "brand": "Carrefour",
      "city": "Rambouillet",
      "postalCode": "78120",
      "country": "FR",
      "fuels": [
        "B7",
        "GPL",
        "SP95",
        "SP95_E10",
        "SP98"
      ],
      "services": [],
      "open24h": true,
      "prices": {
        "B7": {
          "price": 2409,
          "updatedAt": "2026-10-24T20:51:00+00:00"
        },
        "GPL": {
          "price": 1102,
          "updatedAt": "2026-10-24T20:51:00+00:00"
        },
        "SP95": {
          "price": 2159,
          "updatedAt": "2026-10-24T20:51:00+00:00"
        },
        "SP98": {
          "price": 2225,
          "updatedAt": "2026-10-24T20:51:00+00:00"
        },
        "SP95_E10": {
          "price": 2119,
          "updatedAt": "2026-10-24T20:51:00+00:00"
        }
      }
    }
  ],
  "nextCursor": "eyJwIjoyLCJzIjoxfQ",
  "hasMore": true
}

hasMore vaut true tant qu'une page suit ; nextCursor est alors à passer dans cursor. Sur la dernière page, nextCursor vaut null.

Règles

  • Un curseur est opaque : ne le décodez pas, ne le fabriquez pas. Son contenu peut changer sans préavis.
  • Il porte la position et la taille de la page : avec un cursor, la taille de la page est celle du curseur, quel que soit limit. Gardez les mêmes filtres (q, fuels…) d'une page à l'autre.
  • Le curseur repère une position dans la liste, pas un élément : si des éléments sont ajoutés ou supprimés pendant votre parcours, un élément peut apparaître deux fois ou être sauté. Dédupliquez par id, et relancez un parcours complet plutôt que de garder un curseur pour plus tard.
  • Un curseur illisible répond 400 invalid_cursor : reprenez à la première page, sans cursor.
  • Les recherches ne sont pas paginées : la recherche d'entreprises (limit de 1 à 100), les stations les moins chères (10) et le géocodage (5 au plus) répondent { results }.

Curseur invalide

Réponse 400
{
  "error": {
    "code": "invalid_cursor",
    "message": "Ce curseur de pagination est invalide. Reprenez la liste depuis le début, sans « cursor »."
  }
}

Parcourir toute une liste

// Toutes les stations d'une ville, page par page (100 par page).
async function listAll(query) {
  const all = [];
  let cursor;
  do {
    const params = new URLSearchParams({ ...query, limit: "100", ...(cursor ? { cursor } : {}) });
    const res = await fetch(`https://api.floweet.com/v1/fuel-stations?${params}`, {
      headers: { Authorization: `Bearer ${process.env.FLOWEET_API_KEY}` },
    });
    if (!res.ok) throw new Error((await res.json()).error.code);
    const page = await res.json();
    all.push(...page.data);
    cursor = page.hasMore ? page.nextCursor : undefined;
  } while (cursor);
  // Dédupliquer par id : une station ajoutée pendant le parcours peut décaler les pages.
  return [...new Map(all.map((s) => [s.id, s])).values()];
}

const stations = await listAll({ q: "Rambouillet" });

La même boucle en Python

import os
import requests

def list_all(query):
    """Toutes les stations d'une ville, page par page (100 par page)."""
    items, cursor = [], None
    while True:
        params = {**query, "limit": 100, **({"cursor": cursor} if cursor else {})}
        res = requests.get(
            "https://api.floweet.com/v1/fuel-stations",
            params=params,
            headers={"Authorization": f"Bearer {os.environ['FLOWEET_API_KEY']}"},
            timeout=30,
        )
        res.raise_for_status()
        page = res.json()
        items.extend(page["data"])
        if not page["hasMore"]:
            break
        cursor = page["nextCursor"]
    # Dédupliquer par id : une station ajoutée pendant le parcours peut décaler les pages.
    return list({s["id"]: s for s in items}.values())

stations = list_all({"q": "Rambouillet"})