Alloovium

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 }
ChampTypeSignification
dataarrayItems in this page. Length is at most the request limit.
next_cursorstring | nullPass this back as ?cursor=... to fetch the next page. null means you have reached the end.
has_morebooleanTrue when a next page exists. Equivalent to (next_cursor !== null).

Paramètres de requête

ParamètrePar défautMaximumNotes
limit25100Clamped server-side. Values above 100 are silently capped; negative or zero values fall back to the default.
cursor(none)1024 bytesOpaque base64 payload. Do NOT decode or construct cursors manually — they are a server-owned contract.
bash
curl -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 at et id de 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

Le curseur est du base64 URL-safe d'un petit payload JSON, mais le format est un détail d'implémentation et peut changer sans préavis. Traitez-le comme un blob opaque. Ne construisez ni ne modifiez jamais un curseur manuellement.

Parcourir chaque page

python
import 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

Il est théoriquement possible qu'une page retourne moins que 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 at plus 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

CapabilityMéthodeChemin
vault.list_projectsGET/api/v2/vault/projects
vault.list_documentsGET/api/v2/vault/documents
chat.list_conversationsGET/api/v2/conversations
workflows.listGET/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.
  • Erreurscode et autres codes 4xx.