Documentation / Concepts / Pagination

Pagination

L'API utilise une pagination par offset. Chaque page coûte des crédits — planifiez votre itération en conséquence.

Endpoints concernés

La pagination est disponible sur les endpoints qui retournent des listes :

  • GET /v1/transactions — transactions DVF (limite max 200)
  • GET /v1/portfolio — biens du portefeuille (limite max 100)
  • GET /v1/alerts — alertes webhook (limite max 50)

Paramètres

ParamètreDéfautDescription
limit50Nombre de résultats par page. Plage : 1–200 pour /v1/transactions.
offset0Index de départ (0-based). Passez la valeur de next_cursor de la page précédente.

Le champ next_cursor

Chaque réponse paginée inclut un champ next_cursor :

  • Valeur non-nulle (number) : il y a d'autres résultats. Utilisez cette valeur comme offset pour la prochaine requête.
    next_cursor = offset + nombre de résultats retournés
  • Valeur null : vous êtes sur la dernière page.
{
  "transactions": [ /* 50 objets */ ],
  "total_found": 312,
  "next_cursor": 50,
  "_credits": { "used": 5, "remaining": 95 },
  "query_time_ms": 143
}

// Dernière page :
{
  "transactions": [ /* 12 objets */ ],
  "total_found": 312,
  "next_cursor": null,
  "_credits": { "used": 5, "remaining": 90 },
  "query_time_ms": 121
}

Exemple — parcourir toutes les pages

curl "https://mcp.normi.fr/v1/transactions?code_postal=75011&type_local=Appartement&limit=50&offset=0" \
  -H "X-API-Key: normi_votre_token"
# Utiliser next_cursor comme offset pour la page suivante
curl "https://mcp.normi.fr/v1/transactions?code_postal=75011&type_local=Appartement&limit=50&offset=50" \
  -H "X-API-Key: normi_votre_token"
import requests

def fetch_all(code_postal, type_local, api_key, limit=50):
    url = "https://mcp.normi.fr/v1/transactions"
    headers = {"X-API-Key": api_key}
    offset = 0
    all_results = []

    while True:
        r = requests.get(url, headers=headers, params={
            "code_postal": code_postal,
            "type_local": type_local,
            "limit": limit,
            "offset": offset,
        })
        data = r.json()
        all_results.extend(data["transactions"])

        if data.get("next_cursor") is None:
            break
        offset = data["next_cursor"]

    return all_results
Chaque page coûte des crédits
Chaque appel paginé à GET /v1/transactions coûte 5 crédits, quelle que soit la taille de la page. Affinez vos filtres (type_local, prix, surface, date) pour réduire le nombre de pages nécessaires et éviter de consommer inutilement votre quota.

total_found vs résultats retournés

Le champ total_found indique le nombre total de résultats correspondant à vos filtres (avant pagination). Cela vous permet de calculer le nombre de pages :

total_pages = ceil(total_found / limit)
// ex. 312 résultats / 50 par page = 7 pages (dont la dernière avec 12 résultats)
Stabilité des résultats
Les transactions DVF sont rarement mises à jour (ajout annuel, pas de modification). L'ordre des résultats est stable entre les pages, mais pas garanti si de nouvelles données sont importées pendant votre itération.