DentiSoft

Gateway API

DentiSoft Gateway API

API Gateway centralizado para integraciones externas y el portal de pacientes.

Activo

Flujo de integración

Tu aplicación
Web / Mobile / Backend
HTTPS + X-API-Key
DentiSoft API
api.dentisoft.app
Procesamiento seguro
Clínica dental
Datos aislados por clínica

API Key Auth

Rate limiting por plan: 200 / 1 000 / 5 000 req por 15 min.

Aislamiento de datos

Cada clínica solo accede a sus propios datos. Nunca se mezcla información entre organizaciones.

Alta disponibilidad

Infraestructura con tolerancia a fallos y recuperación automática para garantizar continuidad del servicio.

Autenticación

X-API-Key Clave de acceso de la integración

Requerida en todos los endpoints protegidos. Se obtiene desde el panel de administración de DentiSoft.

# Header requerido
X-API-Key: ds_live_tu_clave_aqui
X-Patient-Token JWT del paciente (portal)

JWT con expiración de 24 h obtenido en el flujo OTP. Se necesita en todos los endpoints /patient/ protegidos.

Flujo de autenticación

1 POST /patient/auth/request-otp — envia OTP al email
2 POST /patient/auth/verify-otp — retorna { token }
3 Usar token como X-Patient-Token en cada request

Rate Limits

Plan Requests / 15 min Uso típico
free 200 Pruebas, desarrollo
pro 1 000 Integraciones de producción
enterprise 5 000 Grandes volúmenes, cadenas de clínicas

Cuando se excede el límite se retorna 429 Too Many Requests con el header Retry-After.

Health

GET
/health

Verifica el estado operativo del servicio.

Público

Respuesta 200 — Servicio operativo

{
  "status":    "ok",
  "ts":        "2026-04-02T18:00:00.000Z",
  "requestId": "req_abc123"
}

Respuesta 503 — Mantenimiento

{
  "status":  "unavailable",
  "message": "Service temporarily unavailable"
}
GET
/health/ready

Readiness probe para monitoreo de infraestructura.

Público
{ "status": "ready" }

Patient Portal

Endpoints para la app móvil / portal web de pacientes. Los endpoints de auth (/patient/auth/*) no requieren X-API-Key.

POST
/patient/auth/request-otp

Envía un OTP de 6 dígitos al email del paciente.

Público

Body (JSON)

{
  "email":      "paciente@example.com",
  "clinicSlug": "mi-clinica"
}

Parámetros

emailstringRequeridoEmail del paciente
clinicSlugstringRequeridoIdentificador único de la clínica

Respuesta 200

{
  "success": true,
  "message": "OTP sent to your email"
}

Respuesta 404

{
  "success": false,
  "error":   "Patient not found"
}
POST
/patient/auth/verify-otp

Verifica el OTP y retorna un JWT de paciente (24 h).

Público

Body (JSON)

{
  "email":      "paciente@example.com",
  "otp":        "123456",
  "clinicSlug": "mi-clinica"
}

Respuesta 200 — Token emitido

{
  "success": true,
  "token":   "eyJhbGciOiJIUzI1NiIs..."
}

Respuesta 401

{
  "success": false,
  "error":   "Invalid or expired OTP"
}
GET
/patient/me

Retorna el perfil del paciente autenticado.

X-API-Key X-Patient-Token

Respuesta 200

{
  "id":          "uuid",
  "firstName":   "Ana",
  "lastName":    "García",
  "email":       "ana@example.com",
  "phone":       "+521234567890",
  "dateOfBirth": "1990-05-15",
  "address":     "Av. Principal 123"
}
PUT
/patient/me

Actualiza campos mutables del perfil (teléfono, domicilio).

X-API-Key X-Patient-Token

Body (JSON)

{
  "phone":   "+521234567890",
  "address": "Nueva dirección 456"
}

Respuesta 200

{
  "success": true,
  "patient": { "phone": "+521234567890", … }
}
GET
/patient/appointments

Lista las citas del paciente autenticado.

X-API-Key X-Patient-Token

Query Params

statusstringupcoming | past | all
limitnumberMáx por página (default 20)

Respuesta 200

{
  "appointments": [{
    "id":       "uuid",
    "date":     "2026-04-10",
    "time":     "10:00",
    "dentist":  "Dr. Martínez",
    "status":   "scheduled"
  }]
}
POST
/patient/appointments

Agenda una nueva cita para el paciente autenticado.

X-API-Key X-Patient-Token

Body (JSON)

{
  "dentistId": "uuid-del-dentista",
  "date":      "2026-04-10",
  "time":      "10:00",
  "reason":    "Limpieza dental"
}

Respuesta 201

{
  "success":     true,
  "appointment": {
    "id":     "uuid",
    "status": "scheduled"
  }
}
GET
/patient/treatments

Lista todos los tratamientos del paciente autenticado.

X-API-Key X-Patient-Token
{
  "treatments": [{
    "id":     "uuid",
    "name":   "Extracción simple",
    "status": "completed",
    "date":   "2026-03-15",
    "price":  800.00
  }]
}
GET
/patient/invoices

Lista todas las facturas del paciente autenticado.

X-API-Key X-Patient-Token
{
  "invoices": [{
    "id":     "uuid",
    "number": "INV-0042",
    "date":   "2026-03-15",
    "total":  800.00,
    "status": "paid"
  }]
}

Connect API

API de integración B2B para sistemas de terceros. Todos los endpoints requieren X-API-Key. Los datos están aislados por clínica.

GET
/connect/v1/patients

Lista paginada de pacientes de la clínica.

X-API-Key

Query Params

pagenumberPágina (default 1)
limitnumberPor página (max 100, default 20)
searchstringFiltro por nombre o email

Respuesta 200

{
  "patients": [{ … }],
  "pagination": {
    "page":  1,
    "limit": 20,
    "total": 150
  }
}
GET
/connect/v1/patients/:id

Obtiene un paciente por UUID.

X-API-Key
{
  "id":          "uuid",
  "firstName":   "Ana",
  "lastName":    "García",
  "email":       "ana@example.com",
  "dateOfBirth": "1990-05-15"
}
POST
/connect/v1/patients

Crea un nuevo paciente en la clínica.

X-API-Key

Body (JSON)

{
  "firstName":   "Ana",        // ✅ requerido
  "lastName":    "García",     // ✅ requerido
  "email":       "ana@ex.com", // ✅ requerido
  "phone":       "+52123456",
  "dateOfBirth": "1990-05-15"
}

Respuesta 201

{
  "success": true,
  "patient": {
    "id":        "new-uuid",
    "firstName": "Ana"
  }
}

409 Conflict si el email ya existe en la clínica.

GET
/connect/v1/appointments

Citas en un rango de fechas de la clínica.

X-API-Key

Query Params

fromYYYY-MM-DDFecha inicio
toYYYY-MM-DDFecha fin (default hoy)
dentistIdUUIDFiltrar por dentista

Respuesta 200

{
  "appointments": [{
    "id":          "uuid",
    "patientName": "Ana García",
    "dentistName": "Dr. Martínez",
    "date":        "2026-04-10",
    "status":      "scheduled"
  }]
}
POST
/connect/v1/appointments

Crea una nueva cita desde un sistema externo.

X-API-Key

Body (JSON)

{
  "patientId": "uuid-paciente",   // ✅
  "dentistId": "uuid-dentista",   // ✅
  "date":      "2026-04-10",       // ✅
  "time":      "10:00",           // ✅
  "reason":    "Revisión general" // ✅
}

Respuesta 201

{
  "success":     true,
  "appointment": {
    "id":     "new-uuid",
    "status": "scheduled"
  }
}
GET
/connect/v1/webhooks

Lista los webhooks registrados para la API Key.

X-API-Key
{
  "webhooks": [{
    "id":       "uuid",
    "url":      "https://myapp.com/hooks/dentisoft",
    "events":   ["appointment.created", "invoice.paid"],
    "isActive": true
  }]
}
POST
/connect/v1/webhooks

Registra un nuevo endpoint para recibir eventos.

X-API-Key

Body (JSON)

{
  "url": "https://myapp.com/hooks/ds",
  "events": [
    "appointment.created",
    "appointment.updated",
    "appointment.cancelled",
    "patient.created",
    "invoice.paid"
  ]
}

Respuesta 201

{
  "success": true,
  "webhook": {
    "id":     "uuid",
    "url":    "https://myapp.com/hooks/ds",
    "secret": "whsec_abc123xyz"
  }
}

Guarda secret — solo se muestra una vez. Se usa para verificar firmas HMAC.

Connect API — Invoices

GET /connect/v1/invoices Auth: X-API-Key

Returns all invoices for the clinic. Optional query params: status (pending | paid | partial | overdue | cancelled), patientId.

GET /connect/v1/invoices?status=pending
X-API-Key: sk_live_...
GET /connect/v1/invoices/overdue Auth: X-API-Key

Returns all unpaid invoices whose due date has passed.

GET /connect/v1/invoices/:id Auth: X-API-Key

Returns a single invoice with its line items.

PATCH /connect/v1/invoices/:id/status Auth: X-API-Key

Updates the payment status of an invoice. When marking as paid, include paidAmount.

PATCH /connect/v1/invoices/:id/status
Content-Type: application/json
X-API-Key: sk_live_...

{
  "status": "paid",
  "paidAmount": 350.00
}

Connect API — Treatments

GET /connect/v1/treatments Auth: X-API-Key

Returns treatments for the clinic. Filter by patientId or status (pending | in_progress | completed | cancelled).

GET /connect/v1/treatments/:id Auth: X-API-Key

Returns a single treatment record.

PATCH /connect/v1/treatments/:id/status Auth: X-API-Key

Updates the status of a treatment.

PATCH /connect/v1/treatments/:id/status
Content-Type: application/json
X-API-Key: sk_live_...

{
  "status": "completed"
}

Connect API — Inventory

GET /connect/v1/inventory Auth: X-API-Key

Returns all inventory items. Optional query params: search (name), category.

GET /connect/v1/inventory/low-stock Auth: X-API-Key

Returns items whose current quantity is at or below their minimum stock threshold.

POST /connect/v1/inventory/:id/movement Auth: X-API-Key

Records a stock movement for an item. type: in (stock received) or out (stock consumed).

POST /connect/v1/inventory/:id/movement
Content-Type: application/json
X-API-Key: sk_live_...

{
  "type": "out",
  "quantity": 5,
  "reason": "Used in procedure"
}

Connect API — Dentists

GET /connect/v1/dentists Auth: X-API-Key

Returns all active dentists (users with appointment access) for the clinic.

GET /connect/v1/dentists/:id/availability?date=YYYY-MM-DD Auth: X-API-Key

Returns the booked appointment slots for a dentist on a given date. Use this to show availability before booking.

GET /connect/v1/dentists/:id/availability?date=2025-08-15
X-API-Key: sk_live_...

// Response
{
  "success": true,
  "data": {
    "dentistId": "uuid",
    "date": "2025-08-15",
    "bookedSlots": [
      { "appointmentId": "uuid", "time": "09:00", "durationMinutes": 30, "status": "Confirmada" }
    ]
  }
}

Connect API — Stats

GET /connect/v1/stats/overview Auth: X-API-Key

Returns a summary of clinic metrics: total patients, appointment counts, and revenue.

GET /connect/v1/stats/overview
X-API-Key: sk_live_...

// Response
{
  "success": true,
  "data": {
    "patients": { "total": 120, "active": 95 },
    "appointments": { "today": 8, "this_month": 52, "pending": 14 },
    "revenue": { "revenue_this_month": 12500.00, "revenue_all_time": 98400.00 }
  }
}

Códigos de Error

Código Significado Causa común
200OKSolicitud exitosa
201CreatedRecurso creado exitosamente
400Bad RequestBody inválido o parámetros faltantes
401UnauthorizedOTP inválido, token expirado o ausente
403ForbiddenAPI Key sin permisos para este recurso
404Not FoundRecurso no existe o no pertenece a tu clínica
409ConflictEmail duplicado u otro conflicto de unicidad
429Too Many RequestsRate limit del plan excedido
500Internal ErrorError inesperado — reportar con requestId
503Service UnavailableCircuit breaker abierto (Core no responde)

Formato de error estándar

{
  "success":   false,
  "error":     "Mensaje de error legible",
  "requestId": "req_abc123xyz"   // incluir en reportes de soporte
}

Webhook Events

Los webhooks se entregan como POST a tu URL con el header X-DentiSoft-Signature (HMAC-SHA256 del body usando tu secret).

Evento Disparado cuando…
appointment.createdSe agenda una nueva cita
appointment.updatedSe modifica fecha, hora o dentista
appointment.cancelledLa cita es cancelada
patient.createdSe registra un paciente nuevo
invoice.paidUna factura es marcada como pagada

Ejemplo de payload — appointment.created

{
  "event":     "appointment.created",
  "ts":        "2026-04-10T10:00:00.000Z",
  "requestId": "req_xyz789",
  "data": {
    "id":          "uuid-cita",
    "patientId":   "uuid-paciente",
    "patientName": "Ana García",
    "dentistId":   "uuid-dentista",
    "dentistName": "Dr. Martínez",
    "date":        "2026-04-10",
    "time":        "10:00",
    "reason":      "Limpieza dental",
    "status":      "scheduled"
  }
}