Une API partenaire qui tient son SLA se conçoit autour de la promesse, elle ne s'y adapte pas après coup. Le contrat couvre bien plus que la disponibilité : stabilité du format d'erreur, politique écrite de versionnement et de dépréciation, limites de débit annoncées dans les en-têtes, webhooks qui livrent réellement. Vous tenez la promesse en mesurant des SLO internes plus stricts que ce que vous signez, et en sachant quel partenaire est dégradé avant qu'il n'ouvre un ticket. Voici la méthode que nous appliquons quand nous concevons des API partenaires.
Pourquoi une API partenaire est-elle un contrat, pas un simple endpoint ?
Parce que des partenaires bâtissent du chiffre d'affaires dessus. Dès qu'un tiers écrit du code contre votre API, tout ce qui est observable devient le contrat : forme des réponses, format des erreurs, codes de statut, limites de débit, latence. La disponibilité n'est qu'une clause parmi d'autres. Une API qui change le sens d'un champ casse les intégrations aussi sûrement qu'une panne.
Trois règles non négociables en découlent. Les évolutions sont additives : nouveaux champs, nouveaux endpoints, nouvelles valeurs d'énumération derrière une version, jamais un type modifié ni un champ réutilisé pour autre chose. Les dépréciations ont une fenêtre écrite (douze mois sont un plancher courant pour des endpoints exposés à des partenaires), avec des rappels fondés sur l'usage réel, pas un billet de blog et un haussement d'épaules. Et la politique de versionnement se publie avant la signature du premier partenaire, car il est bien plus difficile de l'introduire après. Cette discipline est au cœur de notre travail de développement d'API : les clauses ennuyeuses du contrat sont celles qui le maintiennent en vie.
SLO avant SLA : que faut-il vraiment promettre ?
Promettez moins que ce que vous mesurez. Définissez des objectifs de niveau de service (SLO) internes sur la disponibilité, la latence et le taux d'erreur, observez-les pendant au moins un trimestre complet, puis signez un SLA un cran en dessous. Si votre plateforme tient un niveau donné en interne, promettre légèrement moins laisse la place à une mauvaise semaine sans rupture de contrat.
L'écart entre les deux chiffres constitue votre budget d'erreur, et il doit guider les décisions d'ingénierie : quand le budget brûle vite, les déploiements risqués attendent. Faites le calcul avant de signer : les grandes API publiques affichent souvent des engagements mensuels autour de 99,9 %, et même ce chiffre autorise environ 43 minutes d'indisponibilité par mois. Les partenaires lisent les clauses de compensation ; lisez surtout les clauses de mesure, car la façon dont la disponibilité est mesurée compte autant que le chiffre lui-même.
| SLO (interne) | SLA (contractuel) | |
|---|---|---|
| Audience | Vos ingénieurs | Les partenaires et leurs juristes |
| Rôle | Alerte précoce, budget d'erreur | Compensations et avoirs |
| Exigence | Plus strict que le SLA | Plus souple, avec de la marge |
| Mesuré par | Votre télémétrie, par partenaire | Une méthode écrite dans le contrat |
| En cas d'échec | Gel des changements risqués | Avoirs, escalade, départ du partenaire |
Comment rendre les erreurs prévisibles ?
Chaque erreur qu'un partenaire peut recevoir doit pouvoir être énumérée dans votre documentation : un code typé, une enveloppe stable, un signal lisible par une machine indiquant si une nouvelle tentative a du sens. Les 500 bruts avec un corps HTML sont le plus court chemin pour perdre la confiance : l'astreinte du partenaire ne peut pas distinguer votre bug du sien.
Choisissez une enveloppe et ne changez plus jamais sa forme. La RFC 9457 (problem details pour les API HTTP) est une bonne base ; une enveloppe maison convient aussi, tant qu'elle est versionnée avec l'API. Utilisez les codes de statut HTTP pour la vérité côté transport et votre code typé pour la vérité côté métier :
{
"error": {
"type": "invalid_request",
"code": "AMOUNT_BELOW_MINIMUM",
"message": "amount must be at least 100 minor units",
"retryable": false,
"request_id": "req_9f2c81d4",
"doc_url": "https://api.example.com/docs/errors#AMOUNT_BELOW_MINIMUM"
}
}
Deux détails se rentabilisent vite : un request_id renvoyé dans chaque réponse raccourcit les échanges avec le support, et un en-tête Retry-After sur les réponses 429 et 503 transforme les tempêtes de retries en attente polie.
Votre API partenaire promet-elle plus qu'elle ne mesure ? Décrivez votre API : diagnostic d'une page sous 48 h.
Recevoir mon diagnostic →Limites de débit, délestage et équité entre partenaires
Publiez le budget, annoncez la consommation dans les en-têtes, et isolez les partenaires les uns des autres. Une limite de débit que personne ne peut observer est un piège. Un pool partagé où un partenaire peut affamer les autres est pire. Des quotas par partenaire et un seuil global de délestage empêchent une intégration bruyante de dégrader toute la plateforme.
La convention X-RateLimit-* reste la plus répandue ; l'IETF travaille à standardiser des champs RateLimit, encore à l'état de brouillon au moment où nous écrivons. Quel que soit votre choix, envoyez ces en-têtes sur chaque réponse, pas seulement sur les 429 :
# Envoyé sur chaque réponse, pas seulement sur les 429
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 480
X-RateLimit-Reset: 1767225600
# Quand le budget est épuisé
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Derrière une passerelle managée, utilisez ses mécanismes natifs : Amazon API Gateway, par exemple, propose des plans d'usage par clé d'API, qui se transposent proprement en quotas par partenaire. En cas de surcharge réelle, délestez délibérément : rejetez tôt avec un 429 ou un 503 accompagné de Retry-After, et protégez d'abord les partenaires qui respectent leur quota.
Idempotence et pagination qui survivent à la croissance
Acceptez une clé d'idempotence sur chaque endpoint mutateur, et paginez chaque endpoint de liste par curseur dès le premier jour. Les partenaires réessaient : les réseaux tombent, les files redélivrent, les frameworks expirent et renvoient. Sans clé d'idempotence, un POST rejoué crée un doublon ; sans curseur, la pagination par offset se dégrade et saute des lignes quand les tables grossissent.
La mécanique est bien connue : le client envoie une clé unique, le serveur stocke la première réponse associée et la rejoue pour toute nouvelle tentative pendant une fenêtre de rétention. La documentation Stripe sur les requêtes idempotentes décrit bien ce motif. Pour la pagination, renvoyez un curseur opaque, documentez la taille de page maximale, et garantissez que les filtres restent stables d'une page à l'autre d'une même requête.
Qui est dégradé ? L'observabilité par partenaire
Des tableaux de bord globaux peuvent montrer une API saine pendant que votre partenaire le plus important est en échec. Étiquetez chaque requête avec l'identifiant du partenaire et dérivez, par partenaire, taux d'erreur, percentiles de latence et consommation de quota. Votre supervision ne doit pas répondre à « l'API est-elle en ligne » mais à « quel partenaire passe une mauvaise heure, et pourquoi ».
Les vues par partenaire changent la gestion d'incident : vous alertez sur la rupture du SLO au niveau du partenaire, vous prévenez les partenaires touchés avant qu'ils ne s'en aperçoivent, et votre page de statut reflète la réalité plutôt qu'un mur vert. Publiez les chronologies d'incident et des synthèses après résolution ; les partenaires pardonnent bien plus facilement une panne qu'un silence.
Les webhooks font partie du produit
Les webhooks sortants ont le même poids contractuel que les endpoints entrants : charges signées, calendrier de retries documenté avec backoff, catalogue d'événements qui ne fait que grandir, et un outil de relivraison que les partenaires peuvent déclencher eux-mêmes. Si le SLA couvre votre API mais que vos webhooks perdent des événements en silence, le SLA est une fiction.
Traitez la livraison comme un pipeline asynchrone, avec une file entre la production de l'événement et son envoi, afin qu'un endpoint partenaire lent ne bloque jamais les autres : c'est le raisonnement que nous détaillons dans notre article sur l'architecture événementielle avec Lambda et SQS. La documentation webhooks de Stripe est une bonne référence publique sur les fenêtres de retry, les signatures et les limites d'ordonnancement, quelle que soit votre stack.
Checklist de conception d'une API partenaire
- Politique de versionnement et de dépréciation écrite et publiée avant la première intégration.
- Évolutions additives uniquement ; le type ou le sens d'un champ n'est jamais modifié en place.
- SLO internes plus stricts que le SLA contractuel, mesurés par partenaire.
- Une seule enveloppe d'erreur, codes typés, identifiants de requête, aucun 500 brut.
Retry-Aftersur les 429 et 503 ; en-têtes de limite de débit sur chaque réponse.- Clés d'idempotence sur tous les endpoints mutateurs, fenêtre de rétention documentée.
- Pagination par curseur et filtres stables dès la première version.
- Tableaux de bord par partenaire et alertes sur rupture de SLO partenaire.
- Page de statut, communication d'incident et synthèses après résolution.
- Webhooks signés, réessayés avec backoff, relivrables à la demande.