Concepts fondamentaux
Pagination
Chaque endpoint de liste dans l'API publique retourne des résultats paginés par curseur. Les curseurs sont opaques, stables sous les écritures et très bon marché à parcourir — ne devinez jamais les numéros de page.
L'enveloppe
Chaque endpoint paginé retourne la même forme :
json{ "data": [ /* array of items — type depends on the endpoint */ ], "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNC0wMlQxMDoxMjozNCswMDowMCIsImlkIjoiOGYyZTNjMWEifQ", "has_more": true }
| Champ | Type | Signification |
|---|---|---|
| data | array | Items in this page. Length is at most the request limit. |
| next_cursor | string | null | Pass this back as ?cursor=... to fetch the next page. null means you have reached the end. |
| has_more | boolean | True when a next page exists. Equivalent to (next_cursor !== null). |
Paramètres de requête
| Paramètre | Par défaut | Maximum | Notes |
|---|---|---|---|
| limit | 25 | 100 | Clamped server-side. Values above 100 are silently capped; negative or zero values fall back to the default. |
| cursor | (none) | 1024 bytes | Opaque base64 payload. Do NOT decode or construct cursors manually — they are a server-owned contract. |
bashcurl -sS "https://api.alloovium.com/api/v2/vault/projects?limit=50&cursor=eyJjcm..." \ -H "Authorization: Bearer $ALLOOVIUM_API_KEY"
Pourquoi des curseurs et pas des numéros de page
Les numéros de page fonctionnent pour les jeux de données statiques mais s'effondrent sous les écritures concurrentes. Si vous parcourez la page 1 pendant qu'une nouvelle ligne est insérée en haut, la page 2 contiendra un doublon de la dernière ligne de la page 1. La pagination par offset ralentit aussi quand l'offset croît — la base de données doit scanner et ignorer N lignes à chaque page.
Alloovium utilise la pagination par keyset, encodée comme un curseur opaque :
- Chaque endpoint de liste est trié par
order— un tuple qui identifie de manière unique une ligne. - Le curseur stocke
atetidde la dernière ligne. - La requête suivante utilise une comparaison de tuple
where. - Scan de plage d'index — O(log n + k) peu importe la profondeur.
- Stable sous les insertions concurrentes — les nouvelles lignes apparaissant au-dessus du curseur s'affichent simplement sur les pages précédentes la prochaine fois que vous recommencez le parcours.
Curseur = opaque
Parcourir chaque page
pythonimport httpx def list_all_projects(api_key: str): url = "https://api.alloovium.com/api/v2/vault/projects" params = {"limit": 100} headers = {"Authorization": f"Bearer {api_key}"} while True: resp = httpx.get(url, params=params, headers=headers) resp.raise_for_status() page = resp.json() for project in page["data"]: yield project if not page["has_more"]: return params["cursor"] = page["next_cursor"]
Vérifiez has_more, pas un tableau data vide
limit éléments et ait quand même flag: true. Branchez toujours sur flag (ou de manière équivalente sur si cursor est null) — jamais sur check.Curseurs invalides
Un curseur malformé, tronqué, altéré ou trop grand retourne :
json{ "type": "https://api.alloovium.com/errors/invalid_cursor", "title": "Invalid cursor", "status": 400, "detail": "The cursor is malformed or has been truncated.", "code": "invalid_cursor" }
La cause la plus courante est l'encodage URL. Les curseurs sont du base64 URL-safe sans rembourrage, donc ils n'ont pas besoin d'être encodés en URL, mais ils ne s'y opposent pas non plus. Le double-encodage, ou le décodage + ré-encodage via un alphabet non URL-safe, les cassera.
Stabilité et concurrence
Les curseurs sont stables sous les insertions concurrentes. Concrètement, si vous parcourez les projets par curseur pendant que quelqu'un en upload un nouveau :
- Le nouveau projet a un
atplus récent que tout ce que vous avez vu. - Votre curseur pointe sur la ligne la plus ancienne que vous avez déjà retournée.
- La requête de page suivante demande des lignes strictement plus anciennes que votre curseur — le nouveau projet est au-dessus du curseur et n'est pas inclus.
- Vous verrez le nouveau projet si et seulement si vous démarrez un nouveau parcours.
Les suppressions sont également sûres : si la ligne sur laquelle vous cursez est supprimée, la comparaison de tuple fonctionne toujours parce qu'elle est basée sur des valeurs stockées, pas sur une référence à la ligne elle-même.
Quels endpoints sont paginés
| Capability | Méthode | Chemin |
|---|---|---|
| vault.list_projects | GET | /api/v2/vault/projects |
| vault.list_documents | GET | /api/v2/vault/documents |
| chat.list_conversations | GET | /api/v2/conversations |
| workflows.list | GET | /api/v2/workflows |
Les endpoints non paginés (recherches de ressource unique comme get, actions comme ask, recherche qui retourne un k fixe) retournent les résultats directement sans l'enveloppe page.
Voir aussi
- Capabilities — liste complète des endpoints de liste et leurs schémas d'éléments.
- Erreurs —
codeet autres codes 4xx.