Pagination

Certaines routes de l'API HelloAsso renvoient de grands volumes de données. Pour garantir des performances optimales, ces résultats sont paginés.

Nos API utilisent un système de continuationToken.

💡 À savoir : Nos réponses paginées ne fournissent pas le nombre total d'éléments (totalCount vaut souvent -1) ni le nombre de pages. Vous devez parcourir les pages les unes après les autres. Le signal de fin n'est pas l'absence de Continuationtoken, mais l'absence de résultats.

Ce mécanisme est courant dans les APIs pouvant servir de gros volume de données.


🔁 Fonctionnement du flux

Le continuationTokensert de curseur pour demander la page suivante. Cependant, il peut être présent même si vous avez atteint la fin des données.

La règle d'or pour s'arrêter : Tant que le tableau items(ou data) contient des données, continuez. Dès que le tableau est vide, la pagination est terminée.

Algorithme logique

  1. Appeler l'API (sans token pour la 1ère page).
  2. Lire le champ de données (itemsou data).
  3. Si la liste est vide 🛑 : Arrêter la boucle, tout a été récupéré.
  4. Si la liste n'est pas vide ✅ :
  • Stocker/Traiter les résultats.
  • Récupérer le continuationToken de la réponse.
  • Relancer l'appel avec ce nouveau token.

📦 Structure de la réponse (JSON)

Voici un exemple de réponse sur une route V5 (ex: /items). Notez que le continuationToken est encapsulé dans un objet paginationet que les résultats sont dans data.

Route : GET /v5/organizations/{organizationSlug}/forms/{formType}/{formSlug}/items

{
  "data": [
    {
      "payer": {
        "email": "[email protected]",
        "firstName": "Jean",
        "lastName": "Durant"
      },
      "items": [
        {
          "id": 8868440,
          "amount": 4599,
          "type": "Registration",
          "state": "Processed"
        }
      ],
      "amount": { "total": 4599, "vat": 0 },
      "id": 8868440,
      "date": "2025-09-30T11:20:55.8062172+02:00"
    }
    // ... autres résultats ...
  ],
  "pagination": {
    "pageSize": 20,
    "totalCount": -1,
    "pageIndex": 1,
    "totalPages": -1,
    "continuationToken": "20250625141032499204_1234567"
  }
}

💻 Exemple d'implémentation (Python)

Ce script montre comment parcourir toutes les pages. Il gère l'extraction du token situé dans l'objet pagination.

import requests

def get_all_form_items(api_url, headers):
    all_items = []
    token = None
    
    while True:
        # Prepare parameters
        params = {}
        if token:
            params['continuationToken'] = token
        
        # API Call
        response = requests.get(api_url, headers=headers, params=params)
        response.raise_for_status()
        body = response.json()
        
        # 1. Retrieve results from the current page
        # Note: Depending on the endpoint, this field might be 'data' or 'items'
        current_page_data = body.get('data', []) 
        
        # 2. STOP CONDITION: If the list is empty, we have reached the end
        if not current_page_data:
            break
            
        # 3. Store items
        all_items.extend(current_page_data)
        
        # 4. Retrieve the token for the next iteration
        # In V5, the token is often nested inside a 'pagination' object
        pagination_info = body.get('pagination', {})
        token = pagination_info.get('continuationToken')
        
        # Safety check: if for some reason the token is missing, stop
        if not token:
            break
            
    return all_items

🧪 Bonnes pratiques

  • Toujours vérifier si le champ items (ou data) existe et est une liste.
  • Ne pas stocker ou manipuler les tokens.
  • Compteur manuel : Si vous avez besoin d'afficher un nombre total d'éléments, vous ne pourrez l'obtenir qu'à la fin de cette boucle (ex: len(all_items)).
  • Ne devinez pas le token : Le format du token est opaque. Contentez-vous de renvoyer la chaîne de caractères exacte reçue lors de l'appel précédent.