Conventions de l'API partenaires
Règles communes à toutes les routes : identifiants, site, dates, montants, listes et curseurs, modification partielle, champs inconnus, idempotence, fichiers, compatibilité.
Conventions
Toutes les routes de /api/partner/v1 suivent les mêmes règles. La référence ne les répète pas route par route.
Identifiants
- Toute ressource a un
idUUID. C’est lui qu’on passe dans les chemins et les filtres. - Les clients, animaux, consultations et rendez-vous ont aussi un
publicIdlisible (cli_…,pat_…,cns_…,apt_…), à afficher ou à recopier, pas à stocker comme clé. - Un identifiant de chemin qui n’est pas un UUID, ou qui désigne une ressource hors des sites ouverts à votre application, répond
404.
Site
- Une lecture couvre tous les sites ouverts. Beaucoup de listes acceptent
site_idpour n’en lire qu’un. - Une écriture porte sur un site : paramètre
site_idou en-têteTreats-Site-Id(le paramètre l’emporte). Avec un seul site ouvert, il est implicite ; avec plusieurs, l’oublier répond400 SITE_ID_REQUIRED. - Le vocabulaire est celui du logiciel : une organisation (la clinique ou le groupe) a des sites. Un client est le propriétaire, un animal (
patient) lui appartient.
Dates
- Un instant est en ISO 8601 UTC :
2026-10-20T08:30:00Z. Un jour estAAAA-MM-JJ, au fuseau de la clinique (Europe/Paris). - Années acceptées de 1900 à 9999. Au-delà,
400 INVALID_FIELD.
Les filtres de dates suivent deux familles.
| Paramètres | Routes | Format | Bornes |
|---|---|---|---|
updated_since | toutes les listes synchronisables | instant | inclusive (≥) |
from, to | /appointments, /availability/slots | instant | from inclus, to exclu ; to après from |
from, to | /payments | jour | jours inclus, du début de from à la fin de to |
issued_from, issued_to | /invoices, /credit-notes | jour | jours inclus (date d’émission) |
since | /patients/{id}/history | jour | inclus |
Montants
Tout montant est un entier en centimes, avec sa devise (currency, EUR). Hors taxes et toutes taxes comprises sont toujours nommés (…HtCents, …TtcCents). Aucun calcul de TVA n’est à refaire de votre côté : les totaux rendus sont ceux de la pièce.
Listes
Toute liste a la même forme, même quand elle tient en une page :
{ "items": [ … ], "nextCursor": "…" }
limit: de 1 à 200, 50 par défaut. Une valeur plus grande est ramenée à 200.nextCursor: à repasser tel quel danscursorpour la page suivante.null: c’est la dernière page. Le curseur est opaque ; ne le construisez pas.- L’ordre est stable : date de dernière modification, puis identifiant. Une liste ne se « décale » pas quand une ligne est ajoutée pendant le parcours.
- Une écriture apparaît dans les listes au plus 60 secondes après. La lecture par identifiant est immédiate. Voir Synchronisation.
- Les filtres de statut ne tiennent pas compte de la casse.
Écritures
Champs inconnus refusés. Tout champ de corps que la route ne connaît pas est refusé (400 INVALID_FIELD, un détail par champ, chemins imbriqués compris comme address.ville). Une faute de frappe n’est jamais ignorée en silence.
Modification partielle (PATCH). Un champ absent ne change pas. Un champ à null est vidé, quand il peut l’être (la référence dit lesquels). Envoyez seulement ce qui change.
Idempotence. Tout POST exige un en-tête Idempotency-Key, une valeur unique par opération (un UUID), de 255 caractères au plus. Deux exceptions, des lectures : POST /availability/evaluate et POST /clients/duplicate-check.
- Renvoyé avec la même clé et le même corps dans les 24 heures, l’appel n’est pas rejoué : vous recevez la réponse d’origine, avec l’en-tête
Idempotent-Replayed: true. - La même clé avec un autre corps répond
422 IDEMPOTENCY_KEY_REUSED. - Pendant que le premier appel est en cours, la même clé répond
409 IDEMPOTENCY_IN_PROGRESS: réessayez une seconde plus tard.
PATCH et PUT sont idempotents par nature : les renvoyer donne le même résultat.
Fichiers
- Dépôt en
multipart/form-data. Documents et comptes rendus en PDF ; images d’imagerie en JPEG ou PNG. Le type déclaré ET le contenu du fichier sont vérifiés : un fichier dont les octets ne correspondent pas à son type est refusé. Taille maximale indiquée sur chaque route ; au-delà,400 FILE_TOO_LARGE. - Une
Idempotency-Keypar dépôt : un même envoi est reconnu à son type et à sa taille, pas à son contenu. - Un fichier déposé reste interne à la clinique : c’est elle qui décide de le montrer à son client.
- Téléchargement : la route rend le fichier lui-même (
application/pdf…), ou un lien de téléchargement à durée limitée selon la route.
Compatibilité
Dans /v1, Treats peut ajouter des routes, des paramètres facultatifs, des champs de réponse et de nouvelles valeurs dans une liste de valeurs. Votre code doit ignorer un champ inconnu et traiter une valeur inconnue comme « autre ». Un changement cassant (retrait, renommage, changement de type ou de sens) n’arrive que dans une nouvelle version, annoncée à l’avance.