Desarrolladores

La API de Meevia

Lee la agenda, reserva citas y consulta el catálogo y la ficha del paciente desde tu propio sistema. Esta página te lleva de la primera clave a la primera respuesta con éxito.

En esta página

Qué es y para quién sirve

La API le abre a tu sistema las partes de la clínica que tiene sentido automatizar: la agenda, el catálogo de profesionales y procedimientos, y la ficha básica del paciente. Lo que haces a través de ella sigue las mismas reglas que valen para quien opera la clínica dentro de la plataforma.

Es HTTP con JSON, sin biblioteca obligatoria y sin SDK que instalar. Si tu entorno sabe hacer una petición y leer una respuesta, ya sabe hablar con Meevia.

Casos habituales

  • Una web o una app propia donde el paciente elige la hora y reserva por su cuenta.
  • Un sistema que la clínica ya usa y que necesita ver la agenda del día sin que nadie teclee dos veces.
  • Automatización interna: un panel propio, un informe, una rutina que confirma la asistencia.

Qué necesita tener la clínica

El acceso a la API forma parte del plan de la clínica. Si el plan actual no lo incluye, la primera llamada ya vuelve rechazada, y eso no lo arregla ningún cambio en tu código: es una conversación con el equipo comercial.

Qué no está aquí todavía

Esta versión lee y escribe agenda, y lee catálogo y paciente. Que Meevia avise a tu sistema cuando pasa algo en la clínica, la facturación y los pagos no forman parte de ella.

Cómo conseguir una clave

La clave nace en el panel de desarrollador, que está en developers.meevia.app y tiene carcasa propia, fuera del sistema de la clínica. Es así porque quien integra muchas veces no es de la clínica. No hay ningún camino por la API para crear una clave. La interfaz del panel está en portugués de Brasil, así que los nombres de pestaña y de permiso que se citan abajo son exactamente los que vas a leer en pantalla.

Abrir el panel de desarrollador

  1. 1Abre el panel de desarrolladorLa dirección es developers.meevia.app. Quien ya trabaja dentro del sistema de la clínica llega al mismo sitio por Integrações (Integraciones), en la tarjeta API e Webhooks, que es una puerta al panel.
  2. 2Entra con tu cuenta, o pide una invitaciónQuien administra la clínica entra directo. Quien viene de fuera necesita invitación: en la pestaña Acessos (Accesos), quien administra el panel invita por correo y elige entre Somente ver (solo ver), que consulta y no actúa, y Pode administrar (puede administrar), que además emite claves. Pedir la invitación es mejor que pedir la clave ya hecha, porque una clave que viaja por mensaje ya se ha filtrado.
  3. 3Elige la clínicaEl panel atiende todas las clínicas a las que tienes acceso, y la que elijas arriba es la dueña de todo lo que muestran las pestañas. Si trabajas para varias, aquí es donde cambias.
  4. 4En la pestaña Chaves (Claves), crea una clave nuevaPonle un nombre que diga dónde se va a usar. Seis meses después, ese nombre es la única forma de revocar la clave correcta sin tumbar la integración equivocada.
  5. 5Elige el modo y los ámbitosEl modo decide si la clave toca la clínica de verdad o el entorno de prueba. Los ámbitos deciden qué puede hacer. Marca solo lo que la integración necesita.
  6. 6Copia la clave antes de cerrar la ventanaLa clave completa aparece una sola vez, en el momento de emitirla. Meevia guarda el trozo que la identifica y nunca la parte secreta, así que cerrar sin copiar no tiene recuperación: revoca la clave y emite otra.

Una clave, una clínica

La clave vale para la clínica que la emitió, y solo para ella. Si atiendes a varias clínicas, son varias claves, cada una guardada por separado y sustituible sin tocar las demás. No existe una clave que vea más de una clínica.

Dónde guardarla

Guarda la clave en el servidor, en el almacén de variables de tu entorno. Una clave dentro del código de una aplicación o de una página es una clave publicada, porque cualquiera puede leerla.

Cuándo revocar

Revocar vale al instante y no tiene vuelta atrás: la clave deja de funcionar y sus llamadas pasan a ser rechazadas. Hazlo al cambiar de proveedor, al apagar una integración y a la mínima sospecha de filtración.

Quién puede qué

El permiso Pode administrar del panel abre las dos cosas que cambian algo: emitir y revocar claves, y reiniciar el entorno de prueba. Se recibe por invitación y vale por clínica, así que quien viene de fuera hace las dos sin depender de nadie. Reiniciar tiene un segundo camino: quien administra la clínica también reinicia. Quien solo tiene Somente ver ve las claves y no emite ninguna; el panel lo avisa en pantalla, en vez de esconder el botón.

Autenticación

Toda llamada va autenticada. La clave viaja en la cabecera de autorización, con el esquema que muestra el ejemplo, y no hay más: no hay inicio de sesión, ni sesión, ni token que caduque a mitad de camino.

Peticiónbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"

La clave es un valor único, y es ese valor entero el que viaja en la cabecera. Tiene tres trozos pegados: el prefijo dice en qué modo está la clave, el trozo del medio la identifica y es el que aparece en la pestaña Chaves del panel, y el último es la parte secreta. Esa última Meevia no la guarda nunca en claro, así que ni el soporte puede leer la tuya. Envía siempre la clave completa: mandar solo la parte secreta es el descuido que más rechazos de autorización produce.

Una clave ausente, mal escrita, revocada o caducada reciben todas el mismo rechazo, sin decir cuál de los cuatro casos fue. Es a propósito. Decir cuál es dar una pista a quien está intentando adivinar.

Dos modos

Producción

mv_live_

Toca la clínica de verdad. Una cita creada desde aquí aparece en la agenda de recepción y dispara lo que la clínica haya configurado disparar.

Prueba

mv_test_

Toca un entorno aparte, con datos inventados, que existe solo para que experimentes. Nada de lo que pasa ahí roza la clínica real.

El modo se decide al emitir la clave y no cambia después. En la práctica mantienes las dos claves y cambias la variable de entorno para pasar de un lado al otro.

La clave que aparece en los ejemplos es inventada y no funciona en ninguna parte: está ahí solo para que reconozcas la forma de la tuya. Fíjate en que su prefijo es de producción. Si haces el paso a paso en modo de prueba, como recomienda esta página, la tuya va a empezar distinta.

Ámbitos

Cada ámbito abre una parte de la API, y la clave solo hace lo que sus ámbitos permiten. La falta de un ámbito aparece en la primera llamada que lo necesita, no al emitir la clave.

appointments:read

Leer la agenda

Listar las citas de un periodo y abrir una de ellas.

appointments:write

Tocar la agenda

Crear una cita, cambiarle el estado y cancelar.

catalog:read

Leer el catálogo

Profesionales, procedimientos y los horarios libres de un día.

patients:read

Leer paciente

Abrir la ficha básica de un paciente que ya conoces por el identificador. No existe búsqueda abierta por nombre en esta versión.

Concede el mínimo. Una integración que solo muestra la agenda en una pantalla grande no tiene por qué poder reservar citas. Y una clave escueta es un destrozo pequeño el día en que se filtre.

Los ámbitos no se editan después de emitir la clave. Ampliarlos es emitir una clave nueva con lo que falta, cambiarla en tu entorno y revocar la antigua.

Entorno de prueba

La clínica recibe un entorno de prueba solo para ella, aislado de la clínica real. La primera clave de prueba que se emite ya crea ese entorno, así que no hay nada que aprovisionar ni que pedir.

Qué viene ya dentro

Viene un paciente, un procedimiento y un profesional de ejemplo. Ninguno de ellos existe en la clínica de verdad. Las listas de profesionales y de procedimientos devuelven los identificadores de esos dos, así que consultar catálogo y horarios libres funciona en la primera sesión. Dar de alta es de la clínica: por la API, lo que se crea son citas.

Qué no se puede probar aquí

La API escribe en tres lugares: crear una cita, cambiar su situación y cancelarla. Hoy no se puede ejercitar ninguno de los tres aquí, y el motivo viene en cadena. Crear necesita el identificador del paciente, que no sale en pantalla ni vuelve de ninguna consulta, porque no hay listado de pacientes. Cambiar la situación y cancelar necesitan el identificador de una cita, y solo existiría si crear hubiera funcionado: la lista de citas nace vacía aquí. Quien necesite probar la escritura lo hace en la clínica de verdad, con el cuidado que eso pide: reserva en un hueco vacío y cancela en cuanto confirmes que funcionó.

Cómo reiniciarlo

La pestaña Ambiente de teste (Entorno de prueba) del panel tiene un botón que descarta el entorno actual y entrega otro, limpio, con los mismos datos iniciales. Las claves de prueba ya emitidas siguen valiendo: están ligadas a la clínica, no al entorno que se descartó.

Reiniciar borra todo lo que hayas creado ahí, y no hay deshacer. Es lo que quieres cuando una prueba ha ensuciado el entorno, y es justo lo que no quieres en mitad de una tanda de pruebas.

Reiniciar es de quien tiene Pode administrar en el panel o administra la clínica. Quien viene de fuera con ese permiso lo reinicia por su cuenta, sin tener a quién pedírselo.

La dirección de la API

Toda llamada sale hacia la misma dirección, y es una sola para todo el mundo. No hay una dirección por clínica: lo que separa una clínica de otra es la clave, nunca la URL.

Ejemplotext
https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1

Vas a ver un trozo que parece repetido en mitad del camino. Está bien así. Uno es de la infraestructura que aloja la API y el otro es de la versión de la nuestra. Copia la dirección exactamente como aparece aquí; quitar la parte que parece sobrar devuelve una respuesta de dirección inexistente.

Primera llamada, de cero a la primera respuesta

Lleva cinco minutos, contando desde el inicio de sesión. Hazlo en modo de prueba: si algo sale distinto de lo esperado, quien lo paga es un paciente inventado.

  1. 1Emite una clave de pruebaSigue el camino descrito en Cómo conseguir una clave, marcando el modo de prueba y el ámbito de lectura del catálogo. Copia la clave.
  2. 2Guarda la clave en una variable de entornoAsí la clave no queda en el historial del terminal ni pegada en mitad del comando que le vas a mandar a un compañero.
  3. 3Pide la lista de profesionalesEs la llamada más sencilla de aquí: no recibe ningún parámetro, y el entorno de prueba ya viene con un profesional dentro. Si responde, tu clave, tu ámbito y tu dirección están bien de una sola vez.
  4. 4Mira lo que volvióUna respuesta con éxito trae al profesional de prueba. De ahí en adelante la receta es la misma para el resto: cambia la dirección, la cabecera sigue igual.

Cambia la clave de ejemplo por la variable en la que guardaste la tuya en el paso anterior, o por la clave entera. La que aparece aquí es inventada, y vuelve rechazada.

Peticiónbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"
Código de estado 200
Respuestajson
{
  "data": [
    {
      "id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
      "name": "Dra. Helena Costa",
      "specialty": "Dermatologia"
    }
  ]
}

Si no vino lo que esperabas

Compara lo que volvió con el catálogo de rechazos de esta página, que dice qué pasó y qué hacer en cada caso. Vale la pena mirar también la pestaña Requisições (Peticiones) del panel, que muestra la dirección llamada, la respuesta y la hora de cada llamada recibida. Solo guarda ese resumen, nunca el contenido que enviaste.

El formato de las respuestas

Las respuestas vienen envueltas siempre igual, y cada llamada muestra el formato de lo que devuelve. Programa contra el envoltorio e ignora lo que no conozcas: con el tiempo aparece información nueva, y la integración que ignora lo que no espera sobrevive a eso sin necesitarte.

Los envoltorios

  • Un solo registro, dentro del envoltorio estándar.data
  • Una lista, dentro de ese mismo envoltorio.data
  • Una lista en páginas, junto al marcador que pide la siguiente.datanext_cursorPuede venir sin valor
  • Esta respuesta se sale del patrón de las demás: trae el día consultado al lado de los horarios.dateslots
  • El formato de todo rechazo, en cualquier llamada.error

Listas largas

Las listas vienen en páginas. La respuesta trae un marcador de continuación: mientras venga con valor, manda ese mismo marcador en la llamada siguiente para pedir la página siguiente. Cuando venga vacío, se acabó. No intentes adivinar el total ni montar la paginación por tu cuenta.

Qué lleva cada respuesta

Cita

CampoTipo
iduuid
statusstring
starts_atdatetime
ends_at

Puede venir sin valor

datetime
patient_id

Puede venir sin valor

uuid
professional_id

Puede venir sin valor

uuid
procedure_idsarray<uuid>
created_atdatetime

Paciente

CampoTipo
iduuid
namestring
phone

Puede venir sin valor

string
email

Puede venir sin valor

string

Profesional

CampoTipo
iduuid
name

Puede venir sin valor

string
specialty

Puede venir sin valor

string

Procedimiento

CampoTipo
iduuid
namestring
pricenumber
duration_minutesinteger

Horario libre

CampoTipo
timestring
professional_iduuid

Rechazo

CampoTipo
codestring
messagestring
details

No siempre viene

object

Las llamadas

Cada una trae lo que recibe, lo que devuelve y un ejemplo listo para pegar en el terminal. Cambia los identificadores del ejemplo por los tuyos.

MétodoGETDirección/v1/appointments

Lista las citas de un periodo, en páginas.

Ámbito exigido
appointments:readLeer la agenda
Repetición
No se aplica
Respuesta
Citadatanext_cursorPuede venir sin valor
ParámetroTipoDónde va
fromOpcional
Formato
YYYY-MM-DD
Si no lo envías
el día de hoy, en el huso horario de la clínica
datequery
toOpcional
Formato
YYYY-MM-DD
Si no lo envías
treinta días después de la fecha inicial
datequery
statusOpcional
Valores aceptados
pre_agendadoagendadoconfirmadoem_esperacanceladorealizadofaltou
stringquery
professional_idOpcionaluuidquery
limitOpcional
Si no lo envías
50
Máximo
200
integerquery
cursorOpcional
Si no lo envías
el marcador de continuación que vino en la página anterior
stringquery
Petición · Salió bienbash
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"
Código de estado 200
Respuesta · Salió bienjson
{
  "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="
}
Petición · Pidiendo la página siguientebash
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"
Código de estado 200
Respuesta · Pidiendo la página siguientejson
{
  "data": [],
  "next_cursor": null
}

MétodoPOSTDirección/v1/appointments

Reserva una cita para un paciente, con un profesional, a una hora.

Ámbito exigido
appointments:writeTocar la agenda
Repetición
Exige valor de repetición
Respuesta
Citadata
ParámetroTipoDónde va
Idempotency-KeyObligatoriostringheader
patient_idObligatoriouuidbody
professional_idObligatoriouuidbody
procedure_idsObligatorio
Mínimo de elementos
1
array<uuid>body
starts_atObligatorio
Formato
YYYY-MM-DDTHH:MM[:SS][Z|±HH:MM]
datetimebody
statusOpcional
Valores aceptados
pre_agendadoagendado
Si no lo envías
pre_agendado
stringbody
Petición · Salió bienbash
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"
Código de estado 201
Respuesta · Salió bienjson
{
  "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"
  }
}
Petición · Sin el valor de repeticiónbash
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"
Código de estado 422
Respuesta · Sin el valor de repeticiónjson
{
  "error": {
    "code": "validation_failed",
    "message": "Cabeçalho Idempotency-Key é obrigatório para criar agendamento."
  }
}

MétodoGETDirección/v1/appointments/{id}

Abre una cita concreta.

Ámbito exigido
appointments:readLeer la agenda
Repetición
No se aplica
Respuesta
Citadata
ParámetroTipoDónde va
idObligatoriouuidpath
Petición · Salió bienbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/appointments/9c1f4b2a-7e83-4d61-b0a5-2f8c6d31e4a7"
Código de estado 200
Respuesta · Salió bienjson
{
  "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étodoPATCHDirección/v1/appointments/{id}/status

Cambia el estado de una cita, dentro de lo permitido.

Ámbito exigido
appointments:writeTocar la agenda
Repetición
Seguro repetir
Respuesta
Citadata
ParámetroTipoDónde va
idObligatoriouuidpath
statusObligatorio
Valores aceptados
agendadoconfirmadocancelado
stringbody
Petición · Salió bienbash
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"
Código de estado 200
Respuesta · Salió bienjson
{
  "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"
  }
}
Petición · Cambio de estado rechazadobash
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"
Código de estado 422
Respuesta · Cambio de estado rechazadojson
{
  "error": {
    "code": "status_transition_not_allowed",
    "message": "Transição de status não permitida por esta API.",
    "details": {
      "from": "agendado",
      "to": "realizado"
    }
  }
}

MétodoPOSTDirección/v1/appointments/{id}/cancel

Cancela una cita.

Ámbito exigido
appointments:writeTocar la agenda
Repetición
Seguro repetir
Respuesta
Citadata
ParámetroTipoDónde va
idObligatoriouuidpath
Petición · Salió bienbash
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"
Código de estado 200
Respuesta · Salió bienjson
{
  "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étodoGETDirección/v1/patients/{id}

Abre la ficha básica de un paciente.

Ámbito exigido
patients:readLeer paciente
Repetición
No se aplica
Respuesta
Pacientedata
ParámetroTipoDónde va
idObligatoriouuidpath
Petición · Salió bienbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/patients/4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63"
Código de estado 200
Respuesta · Salió bienjson
{
  "data": {
    "id": "4d7e2c19-5a6b-4f30-9e81-c2a5b7d04f63",
    "name": "Ana Ribeiro",
    "phone": "+5511987654321",
    "email": "ana.ribeiro@example.com"
  }
}

MétodoGETDirección/v1/practitioners

Lista los profesionales de la clínica.

Ámbito exigido
catalog:readLeer el catálogo
Repetición
No se aplica
Respuesta
Profesionaldata

Esta llamada no recibe parámetros.

Petición · Salió bienbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/practitioners"
Código de estado 200
Respuesta · Salió bienjson
{
  "data": [
    {
      "id": "1f6d5c84-3b92-4a07-8e15-d6c3f9b204ae",
      "name": "Dra. Helena Costa",
      "specialty": "Dermatologia"
    }
  ]
}

MétodoGETDirección/v1/procedures

Lista los procedimientos del catálogo.

Ámbito exigido
catalog:readLeer el catálogo
Repetición
No se aplica
Respuesta
Procedimientodata

Esta llamada no recibe parámetros.

Petición · Salió bienbash
curl -X GET \
  -H "Authorization: Bearer mv_live_a1b2c3d49f8e7d6c5b4a39281706f5e4d3c2b1a0" \
  "https://wnricobmssysbwfhbmsm.supabase.co/functions/v1/api-v1/v1/procedures"
Código de estado 200
Respuesta · Salió bienjson
{
  "data": [
    {
      "id": "2a9f8b31-6c74-4e05-9d28-a3f1e7b5c06d",
      "name": "Limpeza de pele profunda",
      "price": 280,
      "duration_minutes": 60
    }
  ]
}

MétodoGETDirección/v1/availability

Muestra los horarios libres de un día, y se puede acotar a un profesional o a un procedimiento.

Ámbito exigido
catalog:readLeer el catálogo
Repetición
No se aplica
Respuesta
Horario libredateslots
ParámetroTipoDónde va
dateObligatorio
Formato
YYYY-MM-DD
datequery
professional_idOpcionaluuidquery
procedure_idOpcionaluuidquery
Petición · Salió bienbash
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"
Código de estado 200
Respuesta · Salió bienjson
{
  "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"
    }
  ]
}

Repetir sin duplicar

La red se cae en mitad de la llamada, se agota el tiempo, y te quedas sin saber si la cita se creó. Repetir por tu cuenta puede reservar al mismo paciente dos veces.

Por eso toda creación viaja con un valor de repetición inventado por ti, uno para cada operación. Si vuelve a llegar con el mismo contenido, Meevia devuelve la respuesta que ya había dado, sin procesar otra vez.

Idempotency-Key

Cómo elegir ese valor

Genera un valor único por operación (un identificador aleatorio sirve) y guárdalo junto a tu intento, para reutilizar exactamente el mismo a la hora de repetir. Generar uno nuevo en cada intento es lo mismo que no tener ninguna protección.

La respuesta guardada vuelve tal como vino, incluso cuando fue un rechazo. Repetir con el valor de un intento que salió mal devuelve el mismo error, no un intento nuevo.

Reutilizar el mismo valor con contenido distinto se rechaza, y ese rechazo suele delatar dos operaciones distintas compartiendo un mismo valor. La misma respuesta aparece cuando una llamada gemela sigue en marcha, y ahí esperar unos instantes y repetir lo resuelve.

El valor vale un día. Después se olvida, y una repetición vuelve a procesarse de verdad.

Un intento que se quedó sin respuesta se da por perdido a los pocos minutos, y la llamada siguiente con ese valor ocupa su lugar. Así una petición que murió a mitad no te bloquea hasta el día siguiente.

Minutos de espera antes de repetir un intento sin respuesta
5

Qué pasa al repetir cada llamada

No se aplica

Es lectura, y una lectura no cambia nada al repetirse.

Exige valor de repetición

Sin él la llamada se rechaza. Es la protección contra reservar al mismo paciente dos veces cuando la red falla a mitad.

Seguro repetir

Repetir lleva al mismo sitio: pedir el estado en el que la cita ya está devuelve la cita tal como está. Aquí no hace falta enviar valor de repetición.

Límites de uso

Cada clave tiene su propio tope de llamadas por minuto. Es por clave y no por clínica. Dos integraciones en la misma clínica no se pelean por el mismo límite, y una que disparó llamadas de más no tumba a la otra.

Llamadas por minuto, en cada clave
120

La cuenta se pone a cero al cambiar cada minuto del reloj, y no en una ventana que se desliza. En la práctica, dos ráfagas disparadas justo en el cambio caen en minutos distintos, así que un pico corto puede pasar aunque sumado quede por encima del tope. No es holgura con la que se pueda contar: lo que sostiene una integración es el ritmo medio.

Cuando te pases, la respuesta trae en una cabecera propia, y no en el cuerpo, cuántos segundos esperar. Respeta ese número en vez de reintentar al momento. Si esto se vuelve rutina, el problema no es el tope: espacia las llamadas, guarda una copia de lo que cambia poco (el catálogo cambia poco) y deja de preguntar en bucle.

Retry-After

Cambios de estado permitidos

La API acepta un conjunto cerrado de cambios, y la tabla muestra cuáles: cada estado de origen tiene los destinos que permite, y lo que no está en la tabla se rechaza. Dar por realizada una cita y registrar una ausencia quedan fuera por decisión de producto. Los dos generan venta, cobro y consumo de sesión de bono. Siguen en manos de quien opera la clínica.

Estado actualPuede cambiar a
pre_agendadoagendadoconfirmadocancelado
agendadoconfirmadocancelado
confirmadocancelado
em_esperacancelado

Los estados

pre_agendado
Reservada, pero todavía sin confirmación de nadie. Es el estado en el que nace una cita nueva cuando no pides otro.
agendado
Está en la agenda y la clínica cuenta con ella.
confirmado
El paciente confirmó que viene. Es lo que mira recepción para saber con qué contar ese día.
em_espera
Está en la cola, esperando a que se abra un hueco. La API no pone a nadie aquí, pero sí lee a quien está, y desde aquí el único cambio posible es cancelar.
cancelado
Cancelada, y punto final: desde aquí la API ya no cambia nada.
realizado
La consulta ocurrió. Quien lo graba es la clínica, porque el cambio genera la venta. La API lo lee y no lo escribe.
faltou
El paciente no apareció. También es de la clínica: entra en el cobro por ausencia y en el consumo de sesión de bono. La API lo lee y no lo escribe.

Cuando la llamada no sale bien

Todo rechazo vuelve en el mismo formato, con un código corto que no cambia y un mensaje en portugués. En tu programa, decide siempre por el código, nunca por el mensaje: el mensaje existe para tu registro y puede reescribirse en cualquier momento.

Algunos rechazos traen además el detalle de lo que no pasó. No todos lo traen, así que tu código no puede depender de él.

unauthorizedCódigo de estado 401

La clave no fue aceptada. Puede no haber llegado, haber llegado mal, haber sido revocada o estar caducada, y la respuesta es la misma en los cuatro casos.

Empieza por aquí, porque es lo que más confunde: una llamada rechazada por clave no reconocida no aparece en la pestaña Requisições, ya que sin clave válida no hay forma de saber de qué clínica era. No encontrarla ahí no quiere decir que no llegara. Dicho eso, comprueba que la cabecera se esté enviando de verdad y que el valor sea la clave completa, no solo la parte secreta, sin espacios de más ni salto de línea en medio (copiar desde un editor de texto suele traer uno). Comprueba también que no sea la clave de ejemplo de esta página, que es inventada. Si la clave es antigua, mira en la pestaña Chaves del panel si sigue activa. Si persiste, emite otra: es más rápido que investigar.

plan_requiredCódigo de estado 403

La clave es válida, pero el plan de la clínica no incluye el acceso a la API.

Ningún cambio en tu código lo arregla. Avisa a la clínica, que habla con el soporte de Meevia: es asunto de plan.

scope_requiredCódigo de estado 403

La clave es válida, pero no tiene el ámbito que esta llamada exige.

Mira en la ficha de la llamada qué ámbito pide, y compáralo con los ámbitos de la clave en la pestaña Chaves del panel. Los ámbitos no se editan: emite otra clave con lo que falta, cámbiala en tu entorno y revoca la antigua.

not_foundCódigo de estado 404

Aquí llegan dos situaciones distintas: o la dirección no corresponde a nada, o lo que pediste no existe en esta clínica.

Comprueba primero la dirección, letra a letra, contra el ejemplo de la llamada; un plural de más cae en este caso. Si la dirección está bien, lo que falta es el registro: puede haber sido borrado, o ser de otra clínica. Acuérdate también de que el entorno de prueba tiene datos propios. Un identificador copiado de la clínica real no existe ahí dentro.

method_not_allowedCódigo de estado 405

La dirección existe, pero no atiende ese tipo de petición.

Comprueba en la ficha de la llamada qué método espera. Casi siempre es una lectura intentada como escritura, o al revés.

validation_failedCódigo de estado 422

Algo de lo que enviaste no pasó la comprobación: falta un dato obligatorio, o uno de ellos vino en un formato que no sirve.

El mensaje del rechazo dice qué no pasó. Compáralo con la tabla de parámetros de la llamada, con atención especial al formato de fecha y hora, que es donde más se falla.

rate_limitedCódigo de estado 429

Te pasaste del tope de llamadas por minuto de esa clave.

Espera los segundos que vienen en la cabecera de espera de la respuesta. No están en el cuerpo. Por eso mucha gente no encuentra el número y acaba reintentando al momento, lo que solo hunde más. Si pasa a menudo, ajusta el ritmo: espacia las llamadas, guarda una copia de lo que cambia poco y no preguntes en bucle.

idempotency_conflictCódigo de estado 409

El valor de repetición que enviaste ya se usó para otra cosa, o una llamada gemela sigue en marcha.

Si fue otra cosa, pasa a generar un valor nuevo para cada operación nueva; reaprovechar el mismo en operaciones distintas es lo que causa esto. Si es la gemela, espera unos instantes y repite con el mismo valor: en cuanto termine la primera, se devuelve la respuesta guardada.

status_transition_not_allowedCódigo de estado 422

El cambio que pediste no está permitido desde el estado en el que está la cita.

Lee la tabla de cambios permitidos, que muestra hacia dónde se puede ir desde cada estado. Dar por realizada una cita y registrar una ausencia no están ahí, y siguen siendo de la operación de la clínica. El rechazo viene con el estado actual y el pedido, lo que suele revelar que la cita ya estaba en otro.

sandbox_not_readyCódigo de estado 409

La clave es de prueba y el entorno de prueba de la clínica todavía no está en pie.

Repite en unos instantes. Si persiste, hay que reiniciar el entorno, lo que lo recrea desde cero, y eso lo haces tú mismo si tienes Pode administrar en el panel. Una clave de producción nunca cae en este caso.

internal_errorCódigo de estado 500

Algo se rompió de nuestro lado.

No es tu código. Inténtalo otra vez tras un intervalo. Si persiste, habla con el soporte de Meevia diciendo la hora y qué llamaste; la pestaña Requisições del panel ayuda a localizarlo.

Volver arriba

¿Necesitas ayuda?

Cuéntanos qué llamaste, qué esperabas y qué volvió. La pestaña Requisições del panel muestra lo que nos llegó, y es por ahí por donde empezamos a mirar.

Esta página y la API

Si encuentras una diferencia entre lo que está escrito aquí y lo que respondió la API, la API tiene razón, y queremos saberlo. La fecha de abajo dice cuándo se comprobó esta página contra ella por última vez.

Habla por WhatsApp