OdyOdy Aide

Pagination, idempotence et gestion des erreurs

Mis à jour le Sun Aug 16 2026 00:00:00 GMT+0000 (Coordinated Universal Time)

L'API Ody utilise une pagination par curseur opaque sur ses points de terminaison de liste, un en-tête Idempotency-Key pour des tentatives d'envoi de messages sécurisées, et une enveloppe d'erreur uniforme avec un ID de requête sur chaque réponse — ce guide couvre les trois.

Pagination par curseur

GET /v1/api/contacts et GET /v1/api/conversations paginent avec ?limit= et ?cursor= :

curl "https://api.ody.co/v1/api/contacts?limit=100" \
  -H "Authorization: Bearer ody_live_…"

La réponse inclut un nextCursor — repassez-le comme ?cursor= pour récupérer la page suivante, et arrêtez-vous quand il est null :

{ "contacts": [ … ], "nextCursor": "eyJ…" }
  • Les curseurs sont opaques — passez-les toujours tels quels ; un curseur modifié ou périmé renvoie 400 invalid_argument.
  • Limites de taille de page : contacts par défaut 50, max 200 ; conversations par défaut 50, max 100. GET /v1/api/messages/search (par défaut 25, max 100) et GET /v1/api/calls (par défaut 50, max 200) prennent ?limit= uniquement, sans curseurs.
  • Les SDK officiels suivent nextCursor pour vous avec listAll() / list_all() — voir Démarrage rapide des SDK : TypeScript et Python.

Envois de messages idempotents

Une défaillance réseau après un POST /v1/api/messages vous laisse sans savoir si le message a été envoyé — retenter aveuglément risque un double envoi. Envoyez un en-tête Idempotency-Key (toute chaîne de caractères jusqu'à 200 caractères, unique par envoi logique) et les tentatives deviennent sûres :

curl https://api.ody.co/v1/api/messages \
  -H "Authorization: Bearer ody_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042-shipped" \
  -d '{"to":"+15125550123","body":"Your order shipped!"}'
  • La première réponse réussie est stockée pendant 24 heures ; toute nouvelle tentative avec la même clé dans cette fenêtre la rejoue textuellement au lieu de l'envoyer à nouveau, avec un en-tête de réponse Idempotency-Replayed: true.
  • Dérivez la clé de votre propre événement commercial ("order-1042-shipped"), et non d'une valeur aléatoire par tentative — l'objectif est que les tentatives la partagent.

L'enveloppe d'erreur

Chaque réponse d'erreur utilise la même forme :

{ "error": { "code": "permission_denied", "message": "This API key is missing the 'messages:send' scope", "requestId": "req_…" } }
Statut Code Que faire
400 invalid_argument Corrigez la requête — le message indique ce qui ne va pas
401 unauthenticated La clé est manquante, invalide ou révoquée. Ne réessayez pas ; alertez le propriétaire de l'intégration
403 permission_denied Le message nomme la portée manquante — créez une clé qui la possède
404 not_found La ressource n'existe pas dans cet espace de travail
409 failed_precondition L'espace de travail ne peut pas encore faire cela (par exemple, pas de numéro actif pour envoyer). Affichez-le, ne réessayez pas
429 resource_exhausted Limite de débit atteinte — attendez Retry-After secondes, puis réessayez avec un délai exponentiel
500 internal Réessayez avec un délai exponentiel et un jitter ; limitez les tentatives

ID de requête

Chaque réponse — succès ou erreur — contient un en-tête X-Request-Id, répercuté comme requestId dans les corps d'erreur. Enregistrez-le avec vos propres journaux de requêtes, et citez-le lorsque vous contactez le support : il permet de localiser la requête exacte de notre côté. Vous pouvez également fournir votre propre X-Request-Id (jusqu'à 64 caractères, lettres/chiffres/_/-) et Ody le renverra, ce qui facilite la corrélation des tentatives.

Articles connexes

Questions fréquemment posées

Comment obtenir la page de résultats suivante ?

Passez le nextCursor de la réponse précédente comme ?cursor= sur la requête suivante. Un nextCursor nul signifie que vous avez atteint la fin.

Que se passe-t-il si je réessaie un envoi avec la même Idempotency-Key ?

Dans les 24 heures, Ody rejoue la première réponse stockée au lieu de l'envoyer à nouveau, et ajoute un en-tête Idempotency-Replayed: true.

Que dois-je envoyer au support en cas d'échec ?

Le requestId du corps de l'erreur (également l'en-tête de réponse X-Request-Id) — il nous permet de trouver la requête exacte dans nos journaux.

Plus dans API développeur