Développeurs
L'API Meevia
Lisez l'agenda, posez des rendez-vous et consultez le catalogue et la fiche du patient depuis votre propre système. Cette page vous mène de la première clé à la première réponse réussie.
Sur cette page
Ce que c'est et à qui ça sert
L'API ouvre à votre système les parties du cabinet qu'il est logique d'automatiser : l'agenda, le catalogue des professionnels et des actes, et la fiche de base du patient. Ce que vous faites par elle suit les mêmes règles que celles qui valent pour ceux qui font tourner le cabinet dans la plateforme.
C'est du HTTP avec du JSON, sans bibliothèque obligatoire et sans SDK à installer. Si votre environnement sait faire une requête et lire une réponse, il sait déjà parler à Meevia.
Cas courants
- Un site ou une application à vous, où le patient choisit l'horaire et prend rendez-vous tout seul.
- Un système que le cabinet utilise déjà et qui doit voir l'agenda du jour sans que personne ne saisisse deux fois.
- De l'automatisation interne : un tableau de bord à vous, un rapport, une routine qui confirme les présences.
Ce que le cabinet doit avoir
L'accès à l'API fait partie de la formule du cabinet. Si la formule en cours ne l'inclut pas, le tout premier appel revient déjà refusé, et aucun changement dans votre code n'y changera rien : c'est une conversation avec l'équipe commerciale.
Ce qui n'est pas encore là
Cette version lit et écrit l'agenda, et lit le catalogue et le patient. Que Meevia prévienne votre système quand quelque chose se passe au cabinet, ainsi que la facturation et les paiements, n'en fait pas partie.
Comment obtenir une clé
La clé naît dans le panneau développeur, qui se trouve sur developers.meevia.app et possède sa propre coque, hors du système du cabinet. C'est ainsi parce que celui qui construit l'intégration n'appartient souvent pas au cabinet. Il n'existe aucun chemin par l'API pour créer une clé. L'interface du panneau est en portugais du Brésil : les noms d'onglet et de rôle cités ci-dessous sont donc exactement ceux que vous lirez à l'écran.
- 1Ouvrez le panneau développeurL'adresse est developers.meevia.app. Ceux qui travaillent déjà dans le système du cabinet arrivent au même endroit par Integrações (Intégrations), dans la carte API e Webhooks, qui est une porte vers le panneau.
- 2Connectez-vous avec votre compte, ou demandez une invitationCelui qui administre le cabinet entre directement. Celui qui vient de l'extérieur doit être invité : dans l'onglet Acessos (Accès), celui qui administre le panneau invite par e-mail et choisit entre Somente ver (consultation seule), qui regarde sans agir, et Pode administrar (peut administrer), qui émet aussi des clés. Demander l'invitation vaut mieux que demander la clé toute faite, car une clé qui voyage par message a déjà fuité.
- 3Choisissez le cabinetLe panneau dessert tous les cabinets auxquels vous avez accès, et celui qui est choisi en haut possède tout ce que les onglets affichent. Si vous travaillez pour plusieurs, c'est ici que vous changez.
- 4Dans l'onglet Chaves (Clés), créez une clé neuveDonnez-lui un nom qui dise où elle va servir. Six mois plus tard, ce nom est le seul moyen de révoquer la bonne clé sans faire tomber la mauvaise intégration.
- 5Choisissez le mode et les portéesLe mode décide si la clé touche le vrai cabinet ou l'environnement de test. Les portées décident ce qu'elle a le droit de faire. Ne cochez que ce dont l'intégration a besoin.
- 6Copiez la clé avant de fermer la fenêtreLa clé complète n'apparaît qu'une seule fois, au moment de l'émission. Meevia garde le morceau qui l'identifie et jamais la partie secrète : fermer sans copier n'a donc aucun rattrapage. Révoquez la clé et émettez-en une autre.
Une clé, un cabinet
La clé vaut pour le cabinet qui l'a émise, et pour lui seul. Si vous servez plusieurs cabinets, cela fait plusieurs clés, chacune rangée à part et remplaçable sans toucher aux autres. Il n'existe pas de clé qui voie plus d'un cabinet.
Où la garder
Gardez la clé sur le serveur, dans le coffre à variables de votre environnement. Une clé posée dans le code d'une application ou d'une page est une clé publiée, parce que n'importe qui arrive à la lire.
Quand révoquer
La révocation prend effet sur-le-champ et ne se rattrape pas : la clé cesse de fonctionner et ses appels se mettent à revenir refusés. Faites-le en changeant de prestataire, en éteignant une intégration, et au moindre soupçon de fuite.
Qui peut quoi
Le rôle Pode administrar dans le panneau ouvre les deux choses qui modifient quelque chose : émettre et révoquer des clés, et réinitialiser l'environnement de test. Il s'obtient par invitation et vaut par cabinet, donc quelqu'un de l'extérieur fait les deux sans dépendre de personne. Réinitialiser a un second chemin : celui qui administre le cabinet réinitialise aussi. Celui qui n'a que Somente ver voit les clés et n'en émet aucune ; le panneau le dit à l'écran, au lieu de cacher le bouton.
Authentification
Chaque appel part authentifié. La clé voyage dans l'en-tête d'autorisation, selon le schéma que montre l'exemple, et c'est tout : pas de connexion, pas de session, pas de jeton qui expire en cours de route.
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"La clé est une valeur unique, et c'est cette valeur entière qui voyage dans l'en-tête. Elle a trois morceaux collés : le préfixe dit dans quel mode la clé se trouve, le morceau du milieu l'identifie et c'est celui qui apparaît dans l'onglet Chaves du panneau, et le dernier est la partie secrète. Cette dernière, Meevia ne la conserve jamais en clair : même le support n'arrive pas à lire la vôtre. Envoyez toujours la clé complète : n'envoyer que la partie secrète est la méprise qui produit le plus de refus d'autorisation.
Une clé absente, mal recopiée, révoquée ou expirée reçoivent toutes le même refus, sans dire lequel des quatre cas c'était. C'est voulu. Le dire, ce serait donner un indice à celui qui essaie de deviner.
Deux modes
Production
mv_live_
Touche le vrai cabinet. Un rendez-vous créé d'ici apparaît dans l'agenda de l'accueil et déclenche ce que le cabinet a réglé pour se déclencher.
Test
mv_test_
Touche un environnement à part, avec des données inventées, qui n'existe que pour vos essais. Rien de ce qui s'y passe n'effleure le vrai cabinet.
Le mode se décide à l'émission et ne change plus ensuite. En pratique vous gardez les deux clés et changez la variable d'environnement pour basculer d'un côté à l'autre.
La clé qui figure dans les exemples est inventée et ne fonctionne nulle part : elle n'est là que pour vous faire reconnaître la forme de la vôtre. Remarquez que son préfixe est un préfixe de production. Si vous faites le pas à pas en mode test, comme cette page le recommande, la vôtre commencera autrement.
Portées
Chaque portée ouvre une partie de l'API, et la clé ne fait que ce que ses portées permettent. L'absence d'une portée se voit au premier appel qui en a besoin, pas à l'émission.
appointments:read
Lire l'agenda
Lister les rendez-vous d'une période et en ouvrir un.
appointments:write
Toucher à l'agenda
Créer un rendez-vous, en changer le statut et annuler.
catalog:read
Lire le catalogue
Les professionnels, les actes et les créneaux libres d'une journée.
patients:read
Lire un patient
Ouvrir la fiche de base d'un patient que vous connaissez déjà par son identifiant. Il n'existe pas de recherche libre par nom dans cette version.
Accordez le minimum. Une intégration qui se contente d'afficher l'agenda sur un écran mural n'a pas à pouvoir poser des rendez-vous. Et une clé sobre, c'est un petit dégât le jour où elle fuite.
Les portées ne se modifient pas une fois la clé émise. Les élargir, c'est émettre une clé neuve avec ce qui manquait, la remplacer dans votre environnement et révoquer l'ancienne.
Environnement de test
Le cabinet reçoit un environnement de test rien qu'à lui, isolé du vrai cabinet. La première clé de test émise le crée déjà : il n'y a donc rien à provisionner ni à demander.
Ce qu'il y a déjà dedans
Il y a un patient, un acte et un professionnel d'exemple. Aucun des trois n'existe dans le vrai cabinet. Les listes de professionnels et d'actes renvoient les identifiants de ces deux-là : consulter le catalogue et les créneaux libres marche donc dès la première séance de travail. L'enregistrement des fiches appartient au cabinet ; par l'API, ce que l'on crée, ce sont des rendez-vous.
Ce qu'on ne peut pas tester ici
L'API écrit à trois endroits : créer un rendez-vous, changer sa situation et l'annuler. Aujourd'hui aucun des trois ne peut s'exercer ici, et la raison vient en chaîne. Créer a besoin de l'identifiant du patient, qui n'apparaît ni à l'écran ni dans le retour d'une consultation, parce qu'il n'y a pas de liste de patients. Changer la situation et annuler ont besoin de l'identifiant d'un rendez-vous, et il n'existerait que si créer avait fonctionné : la liste des rendez-vous naît vide ici. Ceux qui doivent tester l'écriture le font dans le vrai cabinet, avec le soin que cela demande : posez le rendez-vous sur un créneau vide et annulez dès que vous avez vu que ça marche.
Comment le réinitialiser
L'onglet Ambiente de teste (Environnement de test) du panneau a un bouton qui jette l'environnement actuel et en livre un autre, propre, avec les mêmes données de départ. Les clés de test déjà émises restent valables : elles sont liées au cabinet, pas à l'environnement qui a été jeté.
Réinitialiser efface tout ce que vous avez créé là, et il n'y a pas de retour en arrière. C'est ce que vous voulez quand un essai a sali l'environnement, et c'est exactement ce que vous ne voulez pas au milieu d'une série d'essais.
Réinitialiser appartient à qui détient Pode administrar dans le panneau, ou administre le cabinet. Quelqu'un de l'extérieur avec ce rôle réinitialise seul, sans personne à qui demander.
L'adresse de l'API
Chaque appel part vers la même adresse, et elle est unique pour tout le monde. Il n'y a pas une adresse par cabinet : ce qui sépare un cabinet d'un autre, c'est la clé, jamais l'URL.
https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1Vous verrez un morceau qui a l'air répété au milieu du chemin. C'est correct ainsi. L'un appartient à l'infrastructure qui héberge l'API et l'autre à la version de la nôtre. Recopiez l'adresse exactement telle qu'elle apparaît ici ; enlever la partie qui semble en trop renvoie une réponse d'adresse inexistante.
Premier appel, de zéro à la première réponse
Il faut cinq minutes, en comptant depuis la connexion. Faites-le en mode test : si quelque chose sort autrement que prévu, celui qui paie est un patient imaginaire.
- 1Émettez une clé de testSuivez le chemin décrit dans Comment obtenir une clé, en cochant le mode test et la portée de lecture du catalogue. Copiez la clé.
- 2Rangez la clé dans une variable d'environnementAinsi la clé ne reste ni dans l'historique du terminal ni collée au milieu de la commande que vous allez envoyer à un collègue.
- 3Demandez la liste des professionnelsC'est l'appel le plus simple d'ici : il ne reçoit aucun paramètre, et l'environnement de test arrive déjà avec un professionnel dedans. S'il répond, votre clé, votre portée et votre adresse sont bonnes d'un seul coup.
- 4Regardez ce qui est revenuUne réponse réussie ramène le professionnel de test. À partir de là, la recette est la même pour tout le reste : l'adresse change, l'en-tête reste identique.
Remplacez la clé d'exemple par la variable dans laquelle vous avez rangé la vôtre à l'étape précédente, ou par la clé entière. Celle qui figure ici est inventée, et revient refusée.
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"{
"data": [
{
"id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"name": "Dra. Helena Costa",
"specialty": "Dermatologia"
}
]
}Si ce n'est pas ce que vous attendiez
Comparez ce qui est revenu avec le catalogue des refus de cette page, qui dit ce qui s'est passé et quoi faire dans chaque cas. Il vaut aussi la peine de regarder l'onglet Requisições (Requêtes) du panneau, qui montre l'adresse appelée, la réponse et l'heure de chaque appel reçu. Il ne garde que ce résumé, jamais le contenu que vous avez envoyé.
La forme des réponses
Les réponses arrivent emballées toujours de la même façon, et chaque appel montre la forme de ce qu'il renvoie. Programmez contre l'emballage et ignorez ce que vous ne connaissez pas : avec le temps, des informations nouvelles apparaissent, et l'intégration qui ignore ce qu'elle n'attend pas y survit sans avoir besoin de vous.
Les emballages
- Un seul enregistrement, dans l'emballage standard.
data - Une liste, dans ce même emballage.
data - Une liste par pages, accompagnée du marqueur qui réclame la suivante.
datanext_cursorPeut arriver sans valeur - Cette réponse sort du modèle des autres : elle porte le jour consulté à côté des horaires.
dateslots - La forme de tout refus, sur n'importe quel appel.
error
Listes longues
Les listes arrivent par pages. La réponse porte un marqueur de continuation : tant qu'il revient rempli, renvoyez ce même marqueur à l'appel suivant pour obtenir la page d'après. Quand il revient sans valeur, c'est fini. N'essayez pas de deviner le total ni de monter la pagination vous-même.
Ce que porte chaque réponse
Rendez-vous
| Champ | Type |
|---|---|
id | uuid |
status | string |
starts_at | datetime |
ends_atPeut arriver sans valeur | datetime |
patient_idPeut arriver sans valeur | uuid |
professional_idPeut arriver sans valeur | uuid |
procedure_ids | array<uuid> |
created_at | datetime |
Patient
| Champ | Type |
|---|---|
id | uuid |
name | string |
phonePeut arriver sans valeur | string |
emailPeut arriver sans valeur | string |
Professionnel
| Champ | Type |
|---|---|
id | uuid |
namePeut arriver sans valeur | string |
specialtyPeut arriver sans valeur | string |
Acte
| Champ | Type |
|---|---|
id | uuid |
name | string |
price | number |
duration_minutes | integer |
Créneau libre
| Champ | Type |
|---|---|
time | string |
professional_id | uuid |
Refus
| Champ | Type |
|---|---|
code | string |
message | string |
detailsN'arrive pas toujours | object |
Les appels
Chacun apporte ce qu'il reçoit, ce qu'il renvoie et un exemple prêt à coller dans le terminal. Remplacez les identifiants de l'exemple par les vôtres.
MéthodeGETAdresse/v1/appointments
Liste les rendez-vous d'une période, par pages.
- Portée exigée
appointments:readLire l'agenda- Répétition
- Sans objet
- Réponse
- Rendez-vous
datanext_cursorPeut arriver sans valeur
| Paramètre | Type | Où il passe |
|---|---|---|
fromFacultatif
| date | query |
toFacultatif
| date | query |
statusFacultatif
| string | query |
professional_idFacultatif | uuid | query |
limitFacultatif
| integer | query |
cursorFacultatif
| string | query |
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments?from=2026-10-01&to=2026-10-31&limit=2"{
"data": [
{
"id": "9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7",
"status": "agendado",
"starts_at": "2026-10-03T14:30:00",
"ends_at": "2026-10-03T15:30:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
},
{
"id": "5e0b7a94-1d62-4c38-97af-8b41d2e6c03f",
"status": "confirmado",
"starts_at": "2026-10-03T16:00:00",
"ends_at": "2026-10-03T16:45:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
}
],
"next_cursor": "MjAyNi0xMC0wM3wxNDozMDowMHw5YzFmNGIyYS03ZTgzLTRkNjEtYjBhNS0yZjhjNmQzMWU0YTc="
}curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments?from=2026-10-01&to=2026-10-31&limit=2&cursor=MjAyNi0xMC0wM3wxNDozMDowMHw5YzFmNGIyYS03ZTgzLTRkNjEtYjBhNS0yZjhjNmQzMWU0YTc%3D"{
"data": [],
"next_cursor": null
}MéthodePOSTAdresse/v1/appointments
Pose un rendez-vous pour un patient, avec un professionnel, à un horaire.
- Portée exigée
appointments:writeToucher à l'agenda- Répétition
- Exige une valeur de répétition
- Réponse
- Rendez-vous
data
| Paramètre | Type | Où il passe |
|---|---|---|
Idempotency-KeyObligatoire | string | header |
patient_idObligatoire | uuid | body |
professional_idObligatoire | uuid | body |
procedure_idsObligatoire
| array<uuid> | body |
starts_atObligatoire
| datetime | body |
statusFacultatif
| string | body |
curl -X POST \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7f3c05a1-9b24-4e6d-8c17-0a5f3d92b4e8" \
-d '{
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"starts_at": "2026-10-03T14:30:00",
"status": "agendado"
}' \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments"{
"data": {
"id": "9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7",
"status": "agendado",
"starts_at": "2026-10-03T14:30:00",
"ends_at": "2026-10-03T15:30:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
}
}curl -X POST \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
-H "Content-Type: application/json" \
-d '{
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"starts_at": "2026-10-03T14:30:00"
}' \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments"{
"error": {
"code": "validation_failed",
"message": "Cabeçalho Idempotency-Key é obrigatório para criar agendamento."
}
}MéthodeGETAdresse/v1/appointments/{id}
Ouvre un rendez-vous précis.
- Portée exigée
appointments:readLire l'agenda- Répétition
- Sans objet
- Réponse
- Rendez-vous
data
| Paramètre | Type | Où il passe |
|---|---|---|
idObligatoire | uuid | path |
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments/9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7"{
"data": {
"id": "9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7",
"status": "agendado",
"starts_at": "2026-10-03T14:30:00",
"ends_at": "2026-10-03T15:30:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
}
}MéthodePATCHAdresse/v1/appointments/{id}/status
Change le statut d'un rendez-vous, dans les limites du permis.
- Portée exigée
appointments:writeToucher à l'agenda- Répétition
- Répétition sans danger
- Réponse
- Rendez-vous
data
| Paramètre | Type | Où il passe |
|---|---|---|
idObligatoire | uuid | path |
statusObligatoire
| string | body |
curl -X PATCH \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
-H "Content-Type: application/json" \
-d '{
"status": "confirmado"
}' \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments/9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7/status"{
"data": {
"id": "9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7",
"status": "confirmado",
"starts_at": "2026-10-03T14:30:00",
"ends_at": "2026-10-03T15:30:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
}
}curl -X PATCH \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
-H "Content-Type: application/json" \
-d '{
"status": "realizado"
}' \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments/9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7/status"{
"error": {
"code": "status_transition_not_allowed",
"message": "Transição de status não permitida por esta API.",
"details": {
"from": "agendado",
"to": "realizado"
}
}
}MéthodePOSTAdresse/v1/appointments/{id}/cancel
Annule un rendez-vous.
- Portée exigée
appointments:writeToucher à l'agenda- Répétition
- Répétition sans danger
- Réponse
- Rendez-vous
data
| Paramètre | Type | Où il passe |
|---|---|---|
idObligatoire | uuid | path |
curl -X POST \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments/9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7/cancel"{
"data": {
"id": "9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7",
"status": "cancelado",
"starts_at": "2026-10-03T14:30:00",
"ends_at": "2026-10-03T15:30:00",
"patient_id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"procedure_ids": [
"2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"
],
"created_at": "2026-09-28T11:04:22.517Z"
}
}MéthodeGETAdresse/v1/patients/{id}
Ouvre la fiche de base d'un patient.
- Portée exigée
patients:readLire un patient- Répétition
- Sans objet
- Réponse
- Patient
data
| Paramètre | Type | Où il passe |
|---|---|---|
idObligatoire | uuid | path |
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/patients/4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63"{
"data": {
"id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
"name": "Ana Ribeiro",
"phone": "+5511987654321",
"email": "ana.ribeiro@example.com"
}
}MéthodeGETAdresse/v1/practitioners
Liste les professionnels du cabinet.
- Portée exigée
catalog:readLire le catalogue- Répétition
- Sans objet
- Réponse
- Professionnel
data
Cet appel ne reçoit aucun paramètre.
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"{
"data": [
{
"id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
"name": "Dra. Helena Costa",
"specialty": "Dermatologia"
}
]
}MéthodeGETAdresse/v1/procedures
Liste les actes du catalogue.
- Portée exigée
catalog:readLire le catalogue- Répétition
- Sans objet
- Réponse
- Acte
data
Cet appel ne reçoit aucun paramètre.
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/procedures"{
"data": [
{
"id": "2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d",
"name": "Limpeza de pele profunda",
"price": 280,
"duration_minutes": 60
}
]
}MéthodeGETAdresse/v1/availability
Montre les créneaux libres d'une journée, et l'on peut restreindre à un professionnel ou à un acte.
- Portée exigée
catalog:readLire le catalogue- Répétition
- Sans objet
- Réponse
- Créneau libre
dateslots
| Paramètre | Type | Où il passe |
|---|---|---|
dateObligatoire
| date | query |
professional_idFacultatif | uuid | query |
procedure_idFacultatif | uuid | query |
curl -X GET \
-H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
"https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/availability?date=2026-10-03&procedure_id=2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d"{
"date": "2026-10-03",
"slots": [
{
"time": "09:00",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae"
},
{
"time": "10:00",
"professional_id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae"
}
]
}Répéter sans dupliquer
Le réseau tombe au milieu de l'appel, le délai expire, et vous restez sans savoir si le rendez-vous a été créé. Répéter de votre propre chef peut poser le même patient deux fois.
C'est pourquoi toute création voyage avec une valeur de répétition que vous inventez, une par opération. Si elle arrive de nouveau avec le même contenu, Meevia rend la réponse qu'elle avait déjà donnée, sans traiter une seconde fois.
Idempotency-Key
Comment choisir cette valeur
Générez une valeur unique par opération (un identifiant aléatoire fait l'affaire) et rangez-la avec votre tentative, pour réutiliser exactement la même au moment de répéter. En générer une nouvelle à chaque tentative revient à n'avoir aucune protection.
La réponse conservée revient telle quelle, y compris quand c'était un refus. Répéter avec la valeur d'une tentative qui a mal tourné rend la même erreur, pas une tentative neuve.
Réutiliser la même valeur avec un contenu différent est refusé, et ce refus trahit d'ordinaire deux opérations distinctes qui partagent une seule valeur. La même réponse apparaît quand un appel jumeau est encore en cours, et là, attendre quelques instants puis répéter règle l'affaire.
La valeur vaut une journée. Passé ce délai elle est oubliée, et une répétition se remet à être traitée pour de bon.
Une tentative restée sans réponse est donnée pour perdue au bout de quelques minutes, et l'appel suivant portant cette valeur prend sa place. Ainsi une requête morte en chemin ne vous bloque pas jusqu'au lendemain.
- Minutes d'attente avant de répéter une tentative restée sans réponse
5
Ce qui se passe quand on répète chaque appel
Sans objet
C'est une lecture, et une lecture ne change rien quand on la répète.
Exige une valeur de répétition
Sans elle l'appel est refusé. C'est la protection contre le fait de poser le même patient deux fois quand le réseau lâche en chemin.
Répétition sans danger
Répéter mène au même endroit : demander le statut dans lequel le rendez-vous se trouve déjà rend le rendez-vous tel qu'il est. Inutile d'envoyer une valeur de répétition ici.
Limites d'usage
Chaque clé a son propre plafond d'appels par minute. C'est par clé et non par cabinet. Deux intégrations dans le même cabinet ne se disputent pas la même limite, et celle qui a tiré trop d'appels ne fait pas tomber l'autre.
- Appels par minute, sur chaque clé
120
Le compteur repart à zéro au changement de chaque minute de l'horloge, et non sur une fenêtre qui glisse. En pratique, deux salves tirées de part et d'autre du changement tombent dans des minutes différentes : une pointe courte peut donc passer même en totalisant plus que le plafond. Ce n'est pas une marge sur laquelle compter ; ce qui tient une intégration debout, c'est le rythme moyen.
Quand vous dépassez, la réponse indique dans un en-tête dédié, et non dans le corps, combien de secondes attendre. Respectez ce nombre au lieu de réessayer aussitôt. Si cela devient une habitude, le problème n'est pas le plafond : espacez les appels, gardez une copie de ce qui change peu (le catalogue change peu) et cessez de demander en boucle.
Retry-After
Changements de statut autorisés
L'API accepte un ensemble fermé de changements, et le tableau montre lesquels : chaque statut de départ a les destinations qu'il autorise, et ce qui n'est pas dans le tableau est refusé. Marquer un rendez-vous comme effectué et enregistrer une absence restent dehors par décision de produit. Les deux engendrent une vente, une facturation et la consommation d'une séance de forfait. Ils restent entre les mains de ceux qui font tourner le cabinet.
| Statut actuel | Peut passer à |
|---|---|
pre_agendado | agendadoconfirmadocancelado |
agendado | confirmadocancelado |
confirmado | cancelado |
em_espera | cancelado |
Les statuts
pre_agendado- Posé, mais encore sans confirmation de personne. C'est le statut dans lequel naît un rendez-vous neuf quand vous n'en demandez pas un autre.
agendado- Il est dans l'agenda et le cabinet compte dessus.
confirmado- Le patient a confirmé sa venue. C'est ce que l'accueil regarde pour savoir sur quoi compter le jour même.
em_espera- Il est dans la file, en attente qu'une place se libère. L'API ne met personne ici, mais elle lit qui s'y trouve, et d'ici le seul changement possible est l'annulation.
cancelado- Annulé, et c'est un point final : d'ici l'API ne change plus rien.
realizado- La consultation a eu lieu. C'est le cabinet qui l'enregistre, parce que le changement engendre la vente. L'API le lit et ne l'écrit pas.
faltou- Le patient ne s'est pas présenté. Celui-ci aussi appartient au cabinet : il entre dans la facturation du rendez-vous manqué et dans la consommation d'une séance de forfait. L'API le lit et ne l'écrit pas.
Quand l'appel ne marche pas
Tout refus revient dans le même format, avec un code court qui ne change pas et un message en portugais. Dans votre programme, décidez toujours d'après le code, jamais d'après le message : le message existe pour votre journal et peut être réécrit à tout moment.
Certains refus apportent en plus le détail de ce qui n'est pas passé. Tous ne l'apportent pas, votre code ne peut donc pas en dépendre.
plan_requiredCode de statut 403
La clé est valable, mais la formule du cabinet n'inclut pas l'accès à l'API.
Aucun changement dans votre code n'y changera rien. Prévenez le cabinet, qui en parle au support de Meevia : c'est une affaire de formule.
scope_requiredCode de statut 403
La clé est valable, mais elle n'a pas la portée que cet appel exige.
Regardez, dans la fiche de l'appel, quelle portée il réclame, et comparez avec les portées de la clé dans l'onglet Chaves du panneau. Les portées ne se modifient pas : émettez une autre clé avec ce qui manquait, remplacez-la dans votre environnement et révoquez l'ancienne.
not_foundCode de statut 404
Deux situations différentes aboutissent ici : soit l'adresse ne correspond à rien, soit ce que vous avez demandé n'existe pas dans ce cabinet.
Vérifiez d'abord l'adresse, lettre par lettre, contre l'exemple de l'appel ; un pluriel de trop tombe dans ce cas. Si l'adresse est bonne, c'est l'enregistrement qui manque : il a pu être supprimé, ou appartenir à un autre cabinet. Rappelez-vous aussi que l'environnement de test a ses propres données. Un identifiant recopié du vrai cabinet n'existe pas là-dedans.
method_not_allowedCode de statut 405
L'adresse existe, mais elle ne répond pas à ce type de requête.
Vérifiez, dans la fiche de l'appel, quelle méthode il attend. C'est presque toujours une lecture tentée comme une écriture, ou l'inverse.
validation_failedCode de statut 422
Quelque chose dans ce que vous avez envoyé n'a pas passé le contrôle : il manque une donnée obligatoire, ou l'une d'elles est arrivée dans un format qui ne convient pas.
Le message du refus dit ce qui n'est pas passé. Comparez avec le tableau des paramètres de l'appel, avec une attention particulière au format de date et d'heure, qui est là où l'on se trompe le plus.
rate_limitedCode de statut 429
Vous avez dépassé le plafond d'appels par minute de cette clé.
Attendez les secondes qui arrivent dans l'en-tête d'attente de la réponse. Elles ne sont pas dans le corps. C'est pour cela que beaucoup ne trouvent pas le nombre et finissent par réessayer aussitôt, ce qui ne fait qu'enfoncer davantage. Si cela arrive souvent, réglez le rythme : espacez les appels, gardez une copie de ce qui change peu et ne demandez pas en boucle.
idempotency_conflictCode de statut 409
La valeur de répétition que vous avez envoyée a déjà servi à autre chose, ou un appel jumeau est encore en cours.
Si c'était autre chose, mettez-vous à générer une valeur neuve pour chaque opération neuve ; réemployer la même sur des opérations différentes, c'est ce qui provoque ceci. Si c'est le jumeau, attendez quelques instants et répétez avec la même valeur : dès que le premier aura fini, la réponse conservée vous sera rendue.
status_transition_not_allowedCode de statut 422
Le changement que vous avez demandé n'est pas autorisé depuis le statut dans lequel se trouve le rendez-vous.
Lisez le tableau des changements autorisés, qui montre où l'on peut aller depuis chaque statut. Marquer comme effectué et enregistrer une absence n'y sont pas, et restent du ressort du cabinet. Le refus arrive avec le statut actuel et celui que vous avez demandé, ce qui révèle souvent que le rendez-vous était déjà passé ailleurs.
sandbox_not_readyCode de statut 409
La clé est une clé de test et l'environnement de test du cabinet n'est pas encore debout.
Réessayez dans quelques instants. Si cela persiste, l'environnement doit être réinitialisé, ce qui le recrée de zéro, et vous le faites vous-même si vous détenez Pode administrar dans le panneau. Une clé de production ne tombe jamais dans ce cas.
internal_errorCode de statut 500
Quelque chose a cassé de notre côté.
Ce n'est pas votre code. Réessayez après un intervalle. Si cela persiste, parlez-en au support de Meevia en donnant l'heure et ce que vous avez appelé ; l'onglet Requisições du panneau aide à le retrouver.
Besoin d'un coup de main
Racontez-nous ce que vous avez appelé, ce que vous attendiez et ce qui est revenu. L'onglet Requisições du panneau montre ce qui nous est parvenu, et c'est par là que nous commençons à regarder.
Cette page et l'API
Si vous trouvez un écart entre ce qui est écrit ici et ce que l'API a répondu, c'est l'API qui a raison, et nous voulons le savoir. La date ci-dessous dit quand cette page a été vérifiée contre elle pour la dernière fois.