API de Luna Salud: llaves de acceso y documentación

Activa tu token de acceso, autentícate, consulta tus datos y agenda citas o registra pacientes con la API de Luna Salud.

🔑 API para desarrolladores

Conecta tus sistemas con la API de Luna Salud: activa tu token y haz tu primera consulta

✓Habilita el acceso, genera tu token y autentícate en minutos
✓Consulta tus datos, registra pacientes y agenda citas desde tu sistema
✓Ejemplos listos para copiar, límites y errores explicados
✓Escritura acotada: solo pacientes y citas, y solo con una clave con permiso de escritura
⏱️ Lectura de 10 minutos · Actualizado con cancelación de citas

La API de Luna Salud te permite consultar la información de tu cuenta de forma programática: citas, pacientes, notas clínicas, pagos, biomarcadores y resultados de laboratorio. Es una API REST principalmente de consulta, con escritura acotada: además de leer tus datos para reportes e integraciones, puedes registrar pacientes, actualizar sus datos de contacto, agendar citas y cancelarlas desde tu propio sistema. Nada se elimina por la API. Esta guía te lleva desde habilitar el acceso hasta tu primera solicitud exitosa.

🚀

¿Para qué sirve la API?

La API te da acceso directo a los datos de tu organización para usarlos fuera de Luna Salud. Algunos ejemplos:

📊

Reportes personalizados

Conecta los datos de tu clínica con Google Sheets, Excel o Power BI y arma reportes a tu medida.

💳

Conciliación de pagos

Consulta los pagos registrados con el endpoint /payments y concílialos con tu contabilidad o tu ERP.

📈

Dashboards en tiempo real

Construye tableros con las métricas de citas, pacientes e ingresos de tu organización.

🧪

Seguimiento de laboratorio

Lee resultados de laboratorio y biomarcadores para alimentar sistemas de monitoreo clínico, con webhooks que te avisan cuando hay datos nuevos.

📅

Agenda desde tu sistema

Consulta los horarios libres con /availability y agenda la cita con POST /appointments desde tu sitio web, app o CRM.

🧾

Registro de pacientes

Da de alta pacientes desde tu formulario o CRM con POST /patients y mantén su teléfono y dirección al día.

🔓

Antes de empezar: habilita el acceso a la API

El acceso a la API se habilita por organización y no viene activado de fábrica. Para poder generar tu token necesitas tres cosas:

  • Acceso a la API habilitado para tu organización. Lo activa el equipo de Luna Salud; pídelo por WhatsApp y te lo habilitamos.
  • Rol de Administrador. Solo los administradores pueden ver y generar el token de acceso.
  • Tu token. Cada administrador tiene el suyo y se genera al entrar a Herramientas de Desarrollo — te enseñamos dónde en la siguiente sección.
💡

¿No ves la pestaña «Herramientas de Desarrollo»?

Esa pestaña solo aparece cuando eres administrador y la API está habilitada para tu organización. Si eres administrador y no la ves en Cuenta → Organización, la API aún no está activada para tu clínica: escríbenos por WhatsApp y la habilitamos.

Si alguien de tu equipo intenta usar la API sin que esté habilitada, recibirá un error 403 con el mensaje «El acceso a la API no está habilitado para esta organización».

🔑

Activa tu token de acceso, paso a paso

1

Inicia sesión como administrador

Entra a account.lunahealth.app con una cuenta que tenga rol de Administrador.

2

Abre Herramientas de Desarrollo

Ve a Cuenta → Organización y entra a la pestaña Herramientas de Desarrollo. Ahí vive todo lo relacionado con la API: tu token, la documentación y la configuración de webhooks.

3

Ubica tu token

En la sección Token de Acceso de Luna Health ya está tu token: Luna Salud lo genera al abrir esta pestaña. Si ves el botón «Obtener Token de Acceso», púlsalo para generarlo.

4

Muéstralo y cópialo

Pulsa «Mostrar Token» y luego «Copiar al Portapapeles». Guárdalo en un lugar seguro (un gestor de secretos o las variables de entorno de tu servidor).

Cuenta › Organización ›Herramientas de Desarrollo
Token de Acceso de Luna Health

Utiliza esta clave para autorizar en el servicio API de Luna Health.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi••••••••••••••••••••••••••••
Mostrar Token Copiar al Portapapeles Regenerar Token de Acceso
Tu token aparece oculto por seguridad. «Copiar al Portapapeles» aparece después de pulsar «Mostrar Token». Si en lugar del token ves «Obtener Token de Acceso», púlsalo primero.
⏳

Tu token vence a los 90 días

Cada token es válido por 90 días. Cuando expira, tus solicitudes empiezan a devolver un error 401 ({"error":"Unauthorized"}). La solución es regenerarlo desde esta misma pantalla y actualizar tus integraciones con el token nuevo.

Regenerar invalida el token anterior al instante. Cualquier sistema que siga usando el token viejo dejará de funcionar en ese momento, así que planea el cambio.

🔐

Autentícate: tu primera solicitud

Todas las solicitudes van a la misma URL base:

URL base
https://account.lunahealth.app/api

Y todas requieren tu token en el encabezado Authorization con el prefijo Bearer. Esta solicitud lista tus pacientes y es perfecta para verificar que todo funciona:

GET /patients
# Tu primera solicitud: listar pacientes curl "https://account.lunahealth.app/api/patients?rowsPerPage=5&page=0" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO"

Si recibes un 200 OK con un JSON como este, ya estás dentro:

Respuesta
{ "items": [ { "id": "pat456", "first_name": "María", "last_name": "García", "email": "maria@ejemplo.com" } ], "meta": { "totalRowCount": 128, "page": 0, "rowsPerPage": 5 } }

Si en cambio recibes un 401 o un 403, salta a la sección de errores comunes más abajo: ahí está el significado exacto de cada mensaje y cómo resolverlo.

📋

Endpoints disponibles

La mayoría de los endpoints son de consulta (método GET); los que escriben datos están marcados con su método. Todos devuelven JSON y siempre están limitados a tu organización: nunca verás ni modificarás información de otra clínica, y los endpoints de pacientes jamás exponen cuentas del personal.

EndpointQué devuelveFiltros y parámetros
/appointments Citas de tu organización. from, to (fecha ISO), status (NEW, PENDING, CONFIRMED, COMPLETED, CANCELED), patientId, rowsPerPage (5–200), page, sortDir
/availability Horarios libres de un profesional de salud para un servicio en un día. staffId, serviceId, date (AAAA-MM-DD) obligatorios; locationId
POST /appointments Agenda una cita presencial para un paciente existente. Requiere permiso de escritura. patientId, staffId, serviceId, startTime obligatorios; locationId, reasonForVisit
POST /appointments/{id}/cancel Cancela una cita. No se puede cancelar una cita completada o marcada como inasistencia. Requiere permiso de escritura. notifyPatient (opcional, false por omisión)
/staff Profesionales de salud que se pueden agendar: ID, nombre, apellido y título. serviceId, rowsPerPage, page
/services Servicios de tu organización con su duración. staffId, rowsPerPage, page
/patients Directorio de pacientes. active, query (coincidencia exacta de nombre, apellido o correo), rowsPerPage (5–200), page, sortDir
POST /patients Registra un paciente nuevo. Requiere permiso de escritura. first_name, last_name obligatorios; phone, email, curp, birthdate, gender
PATCH /patients/{id} Actualiza el teléfono y la dirección de un paciente. Requiere permiso de escritura. phone, address (address_line1, address_line2, city, state, postal_code, country)
/patient Perfil básico de un paciente. id (obligatorio)
/patient-charts Notas clínicas y expediente estructurado: consultas, signos vitales, alergias, diagnósticos y procedimientos. patientId (obligatorio)
/biomarkers Biomarcadores de un paciente, con conteos por estado. patientId (obligatorio), start_date, end_date, status (OPTIMAL, ACCEPTABLE, CRITICAL, IN_VERIFICATION), page, limit (1–100)
/lab-tests Estudios de laboratorio de un paciente. patientId (obligatorio), start_date, end_date, page, limit (1–100)
/lab-test-biomarkers Biomarcadores de un estudio específico, con valores, unidades y rangos de referencia. labTestId (obligatorio)
/payments Pagos (recibos) de tu organización. from, to, status (PAID, PENDING, CANCELED, REFUNDED), paymentMethod (CARD, BANK, CASH, INSURANCE, OTHER), patientId, rowsPerPage (5–200), page, sortDir
/payment Un pago específico. id (obligatorio)
/webhooks/config La configuración de webhooks de tu organización (nunca incluye la clave secreta). —
📖

Referencia técnica completa

Cada endpoint tiene su esquema de respuesta detallado, todos los parámetros y ejemplos de código en Node.js y Python en docs.lunasalud.mx. Este artículo es la guía de arranque; la referencia es esa.

📅

Agenda citas desde tu sistema

Con dos solicitudes puedes ofrecer horarios reales y reservar la cita: primero consultas los horarios libres y luego agendas el que elija tu paciente. Las citas aparecen al instante en el calendario de tu clínica.

✍️

Necesitas una clave con permiso de escritura

Las claves generadas antes de que existiera la escritura son de solo lectura. Si al agendar recibes un 403 con el mensaje «Esta clave de API es de solo lectura», un administrador debe pulsar «Regenerar Token de Acceso» en Herramientas de Desarrollo. La clave nueva ya incluye permiso de escritura; recuerda actualizarla en tus integraciones.

1

Ten a la mano los IDs

Necesitas el ID del paciente, del profesional de salud y del servicio. Los encuentras con /patients, /staff y /services (o en las respuestas de /appointments: staffs[].id, service.id, location.id). Si el paciente es nuevo, regístralo antes con POST /patients.

2

Consulta los horarios libres

Pide a /availability los horarios de un día. Ya descuenta citas existentes, tiempo bloqueado y la anticipación mínima de tu clínica, y cada horario dura lo que dura el servicio.

3

Agenda el horario elegido

Envía el start_time del horario a POST /appointments. La hora de fin se calcula sola con la duración del servicio.

GET /availability
# Horarios libres del 20 de octubre de 2026 curl "https://account.lunahealth.app/api/availability?staffId=stf789&serviceId=srv001&date=2026-10-20" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO"
Respuesta
{ "date": "2026-10-20", "timezone": "America/Mexico_City", "slots": [ { "start_time": "2026-10-20T10:00:00-06:00", "end_time": "2026-10-20T10:30:00-06:00" }, { "start_time": "2026-10-20T10:30:00-06:00", "end_time": "2026-10-20T11:00:00-06:00" } ] }
POST /appointments
# Agenda el horario de las 10:00 curl -X POST "https://account.lunahealth.app/api/appointments" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO" \ -H "Content-Type: application/json" \ -d '{"patientId":"pat456","staffId":"stf789","serviceId":"srv001","startTime":"2026-10-20T10:00:00-06:00","reasonForVisit":"Revisión anual"}'

Si todo está bien recibes un 200 con la cita creada, en el mismo formato que /appointments y con estado CONFIRMED.

📌

Reglas al agendar por la API

  • Solo citas presenciales con un profesional de salud y un servicio.
  • La hora de inicio debe ser futura, estar dentro de la disponibilidad del profesional y estar libre. Si alguien la ocupó entre tu consulta y tu reserva, vuelve a pedir los horarios.
  • El profesional debe ofrecer el servicio y estar visible en el calendario interno.
  • No se envía confirmación ni recordatorios al paciente. Si tu sistema necesita avisarle, hazlo desde tu lado. Tu profesional de salud sí recibe la notificación en la plataforma.
❌

Cancela una cita

Envía POST /appointments/{id}/cancel con una clave con permiso de escritura. Por omisión no se avisa al paciente; si quieres que reciba el mensaje de cancelación según la configuración de tu clínica, envía {"notifyPatient": true}. Repetir la solicitud no duplica la cancelación, y una cita completada o marcada como inasistencia ya no se puede cancelar.

POST /appointments/{id}/cancel
# Cancela la cita y avisa al paciente curl -X POST "https://account.lunahealth.app/api/appointments/abc123/cancel" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO" \ -H "Content-Type: application/json" \ -d '{"notifyPatient":true}'
💻

Ejemplos prácticos

Citas de un mes, con su respuesta

GET /appointments
# Citas de agosto 2026, 50 por página curl "https://account.lunahealth.app/api/appointments?from=2026-08-01T00:00:00Z&to=2026-08-31T23:59:59Z&rowsPerPage=50&page=0" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO"
Respuesta
{ "items": [ { "id": "abc123", "status": "CONFIRMED", "title": "Consulta general", "start_time": "2026-08-15T10:00:00.000Z", "end_time": "2026-08-15T10:30:00.000Z", "telemedicine": false, "patient": { "id": "pat456", "first_name": "María", "last_name": "García" }, "staffs": [{ "id": "stf789", "first_name": "Ana", "last_name": "López" }], "service": { "id": "srv001", "name": "Consulta general" }, "location": { "id": "loc001", "name": "Consultorio Roma Norte" } } ], "meta": { "totalRowCount": 42, "page": 0, "rowsPerPage": 50 } }

Pagos con tarjeta del mes

GET /payments
# Pagos pagados con tarjeta en agosto 2026 curl "https://account.lunahealth.app/api/payments?from=2026-08-01T00:00:00Z&to=2026-08-31T23:59:59Z&status=PAID&paymentMethod=CARD" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO"

Biomarcadores críticos de un paciente

GET /biomarkers
# Solo los biomarcadores en estado crítico curl "https://account.lunahealth.app/api/biomarkers?patientId=pat456&status=CRITICAL" \ -H "Authorization: Bearer TU_TOKEN_DE_ACCESO"
📏

Límites y paginación

  • 120 consultas y 40 escrituras por minuto por usuario. Son límites independientes: tus consultas no consumen el cupo para agendar. Si te pasas, recibirás un 429; cada respuesta trae los encabezados X-RateLimit-Remaining y X-RateLimit-Reset, y un rechazo trae Retry-After con los segundos a esperar.
  • Paginación en todos los listados. Usa page (empieza en 0) con rowsPerPage (5–200 en citas, pacientes y pagos) o limit (1–100 en biomarcadores y estudios de laboratorio). El total viene en meta.
  • La paginación profunda está limitada. Si page × rowsPerPage supera 10,000, recibirás un 400. No es un capricho: en lugar de recorrer miles de páginas, acota con from/to o los filtros de fecha y recorre ventanas más pequeñas.
⚡

El patrón recomendado para sincronizar datos

Recorre por ventanas de fecha (por ejemplo, semana por semana con from y to) en lugar de paginar todo el histórico de golpe. Es más rápido, no choca con el límite de paginación y te permite reanudar donde te quedaste.

🚨

Errores comunes y cómo resolverlos

Los errores llegan con su código HTTP y un mensaje claro. Estos son los que verás con más frecuencia:

CódigoMensajeCómo resolverlo
401 {"error":"Unauthorized"} El token no es válido. Revisa, en este orden: que envías Authorization: Bearer TU_TOKEN (con el prefijo Bearer y un espacio); que no pasaron sus 90 días; que nadie lo regeneró después de que lo copiaste; y que su dueño sigue siendo administrador activo. En cualquiera de esos casos, copia o regenera el token en Herramientas de Desarrollo.
403 «El acceso a la API no está habilitado para esta organización.» Tu organización aún no tiene la API activada. Escríbenos por WhatsApp para habilitarla.
404 «Paciente no encontrado.» / «Recurso no encontrado.» El ID no existe o pertenece a otra organización. Verifica que el ID venga de una consulta previa a tu propia cuenta.
400 «El desplazamiento de paginación es demasiado grande.» Superaste el límite de 10,000 registros de profundidad. Acota con filtros de fecha en lugar de paginar tan profundo.
429 «Límite de solicitudes excedido.» Superaste el límite por minuto (120 consultas o 40 escrituras). Espera los segundos que indica Retry-After y reintenta.
403 «Esta clave de API es de solo lectura. Pide a un administrador que regenere la clave para habilitar la escritura.» Tu clave es anterior a la escritura. Un administrador debe regenerarla en Herramientas de Desarrollo.
400 «Esta cita ya no se puede cancelar porque se completó o se marcó como inasistencia.» Al cancelar con POST /appointments/{id}/cancel: la cita ya ocurrió. Si necesitas corregirla, hazlo desde la plataforma.
400 «Este horario está fuera de la disponibilidad del profesional. Por favor elige un horario disponible.» El horario no está en la disponibilidad o ya se ocupó. Vuelve a consultar /availability y elige otro.
400 «La hora de inicio de la cita debe ser en el futuro.» Enviaste una hora que ya pasó. Revisa la fecha y que startTime incluya el desfase horario, por ejemplo -06:00.
400 «Este profesional de salud no ofrece el servicio seleccionado.» El servicio no está asignado a ese profesional. Elige otro servicio o asígnaselo desde la plataforma.
409 «Ya existe un paciente con estos datos en tu organización.» Al registrar con POST /patients: ya hay un paciente con ese correo, o con el mismo nombre y fecha de nacimiento. Usa su ID existente.
🔔

Webhooks: entérate sin preguntar

Además de consultar la API, puedes configurar un webhook para que Luna Salud avise a tu servidor cuando haya datos nuevos, en lugar de estar consultando cada cierto tiempo. Hoy los avisos son de estudios de laboratorio: lab_test.processed cuando se procesa un estudio y lab_test.failed si su procesamiento falla.

🧪
Sucede algo en Luna Salud

Se procesa un estudio de laboratorio de un paciente

→
📤
Luna Salud te notifica

Enviamos un POST a la URL que configuraste, firmado con tu clave secreta

→
⚙️
Tu sistema reacciona

Consulta el detalle con la API y actualiza tus tableros o alertas

La configuración vive en la misma pestaña de Herramientas de Desarrollo, en la sección Configuración de Webhook:

Herramientas de Desarrollo ›Configuración de Webhook
URL del Webhook
https://tu-servidor.ejemplo.com/webhooks/luna
Clave Secreta
••••••••••••••••••••
☑️ Habilitar Webhooks Tipos de Eventos ☑️ Actualizaciones de Pruebas de Laboratorio
Guardar Configuración de Webhook Probar Webhook
La clave secreta debe tener al menos 16 caracteres. Cada aviso trae el encabezado X-Luna-Signature: la firma HMAC-SHA256 (hexadecimal) del cuerpo JSON con tu clave secreta. Calcúlala en tu servidor y compárala para confirmar que el aviso viene de Luna Salud. Cada aviso se envía una sola vez, sin reintentos: si tu servidor no responde, consulta los datos con la API. Usa «Probar Webhook» para mandar un evento de prueba antes de conectar nada en producción.

Puedes consultar tu configuración actual (URL, eventos suscritos y estado) con GET /webhooks/config. Por seguridad, ese endpoint nunca devuelve la clave secreta; los cambios de configuración se hacen siempre desde la plataforma, no por la API.

🛡️

Seguridad de tu token

Tu token da acceso a la información de toda tu organización, incluyendo datos clínicos de pacientes, y si tiene permiso de escritura también puede registrar pacientes y agendar o cancelar citas. Trátalo como una contraseña:

  • Nunca lo pongas en código del navegador, apps móviles ni repositorios públicos como GitHub.
  • Nunca lo compartas por WhatsApp, correo o chat, ni con proveedores que no lo necesiten.
  • Nunca lo escribas directo en el código: úsalo desde variables de entorno o un gestor de secretos en tu servidor.
🧯

¿Se filtró tu token?

Regenéralo de inmediato en Cuenta → Organización → Herramientas de Desarrollo con «Regenerar Token de Acceso». El token filtrado queda invalidado al instante y solo el nuevo seguirá funcionando.

Y si un administrador deja tu clínica, se archiva su cuenta o pierde el rol de Administrador, su token deja de funcionar solo. Otro administrador debe darle a tu integración un token nuevo.

❓

Preguntas frecuentes

¿Por qué no veo la pestaña Herramientas de Desarrollo en mi cuenta?+

El acceso a la API se habilita por organización y la pestaña solo aparece para administradores con la API activada. Si eres administrador y no la ves en Cuenta → Organización, la API aún no está habilitada para tu clínica: escríbenos por WhatsApp y la activamos.

¿Mi token de API expira?+

Sí. Cada token es válido por 90 días. Al expirar, tus solicitudes devuelven un error 401 (Unauthorized); genera uno nuevo con Regenerar Token de Acceso en Herramientas de Desarrollo y actualiza tus integraciones con el token nuevo.

¿Puedo crear o modificar citas y pacientes desde la API?+

Sí, de forma acotada. Puedes registrar pacientes (POST /patients), actualizar su teléfono y dirección (PATCH /patients/{id}), agendar citas presenciales (POST /appointments) y cancelarlas (POST /appointments/{id}/cancel). Necesitas una clave con permiso de escritura: si la tuya es anterior, regenérala en Herramientas de Desarrollo. Por ahora no se pueden reagendar ni eliminar citas o pacientes por la API; eso se hace desde la plataforma.

¿Cuántas solicitudes puedo hacer a la API?+

Hasta 120 consultas y 40 escrituras por minuto por usuario, con límites independientes. Si superas el límite recibirás un error 429 con el encabezado Retry-After; espera esos segundos y reintenta. Para volúmenes grandes, recorre los datos por ventanas de fecha con los filtros from y to en lugar de paginar todo el histórico de golpe.

¿Qué hago si mi token se filtró o alguien más lo conoce?+

Regenéralo de inmediato en Cuenta → Organización → Herramientas de Desarrollo con Regenerar Token de Acceso. El token anterior queda invalidado al instante y solo el nuevo funcionará; actualiza tus integraciones para no quedarte sin acceso.

👩‍💻

¿Listo para construir?

La referencia técnica completa tiene el esquema de cada endpoint con todos los parámetros y ejemplos de código en Node.js y Python.

FAQs

Preguntas Frecuentes

¿Por qué no veo la pestaña Herramientas de Desarrollo en mi cuenta?

El acceso a la API se habilita por organización y la pestaña solo aparece para administradores con la API activada. Si eres administrador y no la ves en Cuenta → Organización, la API aún no está habilitada para tu clínica: escríbenos por el chat de soporte y la activamos.

¿Mi token de API expira?

Sí. Cada token es válido por 90 días. Al expirar, tus solicitudes devuelven un error 401 (Unauthorized); genera uno nuevo con Regenerar Token de Acceso en Herramientas de Desarrollo y actualiza tus integraciones con el token nuevo.

¿Puedo crear o modificar citas y pacientes desde la API?

Sí, de forma acotada. Puedes registrar pacientes (POST /patients), actualizar su teléfono y dirección (PATCH /patients/{id}), agendar citas presenciales (POST /appointments) y cancelarlas (POST /appointments/{id}/cancel). Necesitas una clave con permiso de escritura: si la tuya es anterior, regenérala en Herramientas de Desarrollo. Por ahora no se pueden reagendar ni eliminar citas o pacientes por la API; eso se hace desde la plataforma.

¿Cuántas solicitudes puedo hacer a la API?

Hasta 120 consultas y 40 escrituras por minuto por usuario, con límites independientes. Si superas el límite recibirás un error 429 con el encabezado Retry-After; espera esos segundos y reintenta. Para volúmenes grandes, recorre los datos por ventanas de fecha con los filtros from y to en lugar de paginar todo el histórico de golpe.

¿Qué hago si mi token se filtró o alguien más lo conoce?

Regenéralo de inmediato en Cuenta → Organización → Herramientas de Desarrollo con Regenerar Token de Acceso. El token anterior queda invalidado al instante y solo el nuevo funcionará; actualiza tus integraciones para no quedarte sin acceso.

¿Listo para comenzar? Crea una cuenta hoy mismo

Empezar ahora
Luna Health incluyendo calendario de citas, formularios clínicos, expediente médico y métricas de desempeño