ComProPass / Developer Docs

ComProPass API

v1

API pública de ComProPass para acceder a la base de conocimiento, gestión de pacientes y eventos. Diseñada para integrarse con sistemas externos, agentes de IA y plataformas de soporte.

Knowledge Base
Artículos de soporte por audiencia. Acceso público sin autenticación para contenido public.
Care API
CRUD de pacientes y registro de visitas. Requiere credenciales de tenant.
Events API
Gestión de boletos y check-in en eventos. Requiere credenciales de tenant.

URLs base

# Producción
https://compropass.app/v1

# Futuro (subdominio dedicado)
https://api.compropass.app/v1

Todas las rutas documentadas aquí son relativas a la URL base. Actualmente servidas desde compropass.app/v1.


Autenticación

Los endpoints públicos (audience=public) no requieren autenticación. El resto requiere tres headers con las credenciales del tenant.

Header Descripción Requerido en
x-client-id ID del cliente en ComProPass audience ≠ public
x-tenant-id ID del programa / tenant audience ≠ public
x-compro-key API Key del tenant audience ≠ public

Obtén tus credenciales en el portal: Configuración → API & Webhooks.

Excepción — API de lealtad (lealtadApi): su credencial no sale del portal. La emite el equipo de ComPro y se entrega al integrador junto con los tres valores (x-compro-key, x-client-id, x-tenant-id); además usa su propia URL base, distinta de compropass.app/v1 (ver la sección de lealtad).


Códigos de error

Código HTTP code Causa
400 BAD_REQUEST Parámetros inválidos o faltantes
401 INVALID_API_KEY Credenciales incorrectas o ausentes
403 AUDIENCE_NOT_ALLOWED Audiencia no accesible con las credenciales actuales
404 — Recurso no encontrado
405 — Método HTTP no permitido (solo GET)
500 — Error interno del servidor

Knowledge Base API

público sin key

Acceso a los artículos de soporte de ComProPass. Útil para agentes de IA, chatbots y sistemas de soporte que necesitan responder preguntas de usuarios.

GET /v1/kb Listar y buscar artículos

Parámetros de query

Parámetro Tipo Default Descripción
q string — Búsqueda por texto en título y contenido
audience string public Audiencia: public | manager | cashier
category string — Filtrar por categoría (ej: wallet, lealtad, vcard)
limit number 20 Máximo de resultados (máx 50)

Ejemplos

Buscar artículos públicos sobre Google Wallet:

curl https://compropass.app/v1/kb?q=google+wallet

Artículos para manager con credenciales:

curl https://compropass.app/v1/kb?audience=manager \
  -H "x-client-id: {client_id}" \
  -H "x-tenant-id: {tenant_id}" \
  -H "x-compro-key: {api_key}"

Respuesta

{
  "articles": [
    {
      "id": "pub_03",
      "title": "Cómo agregar tu tarjeta a Google Wallet",
      "content": "Para agregar tu tarjeta digital...",
      "category": "wallet",
      "audience": "public",
      "updated_at": "2026-04-15T10:23:00Z"
    }
  ],
  "total": 1,
  "audience": "public"
}
GET /v1/kb/:id Artículo individual

Ejemplo

curl https://compropass.app/v1/kb/pub_03

Respuesta

{
  "article": {
    "id": "pub_03",
    "title": "Cómo agregar tu tarjeta a Google Wallet",
    "content": "Para agregar tu tarjeta digital...",
    "category": "wallet",
    "audience": "public",
    "updated_at": "2026-04-15T10:23:00Z"
  }
}

Marcaje (HR / Student)

LIVE

Registra asistencia/acceso sin persona detrás — un torniquete, un lector de garita o el sistema de un cliente, por credencial de tenant (x-compro-key / x-client-id / x-tenant-id, ver Autenticación). Vive en hrApi, no bajo /v1 — base https://us-central1-compro-saas-core.cloudfunctions.net/hrApi.

Es registro operativo de acceso, no control de nómina: el producto registra quién pasó y cuándo; el cálculo de horas y turnos es del sistema del cliente. Hay que habilitarlo por programa desde ComPro antes de usarlo — ver el código MARCAJE_NO_HABILITADO más abajo.

Método Ruta Descripción
POST /employees/:employee_code/scan Un marcaje, veredicto síncrono. Acepta wallet_token en el body como alternativa al código.
POST /scans Lote de hasta 500 marcajes ({"scans":[...]}). No transaccional: results[] fila por fila.
GET /scans?from=&to=&limit=&cursor= Historial del tenant, incluidos los marcajes de la PWA de staff. Sigue respondiendo aunque el marcaje esté apagado.

Campos opcionales del body (los dos endpoints POST — en /scans, uno por fila):

Campo Para qué sirve
labelTexto libre que identifica el origen físico (ej. "Torniquete garita 2") — queda firmado en el marcaje junto al tag de tu fuente declarada.
external_idEl id de este evento en tu propio sistema, para conciliar sin depender del scan_id que devolvemos.
occurred_atCuándo pasó de verdad (ISO 8601) — útil si tu lector sincroniza diferido. Si falta, se toma la hora del servidor. No puede ser futuro ni tener más de 7 días.
locationEtiqueta libre de dónde ocurrió (ej. "Planta 2").
device_idIdentificador libre del dispositivo/lector que lo registró.

Ejemplo — un marcaje:

curl -X POST https://us-central1-compro-saas-core.cloudfunctions.net/hrApi/employees/EMP001/scan \
  -H "x-compro-key: {api_key}" -H "x-client-id: {client_id}" -H "x-tenant-id: {tenant_id}" \
  -H "Content-Type: application/json" -d '{"type":"attendance"}'
{ "success": true, "scan_id": "…", "verdict": "allowed",
  "person": { "person_code": "EMP001", "name": "María García" } }

Códigos propios de esta sección:

HTTP code Causa
403MARCAJE_NO_HABILITADOEl programa tiene la API activa pero el marcaje sigue apagado — pedile a ComPro que lo habilite.
409PROGRAMA_NO_SOPORTA_MARCAJEEl tenant no es un carnet de persona (hr/student).
404PERSONA_NO_ENCONTRADAEl código o el token no resuelven a nadie DE ESTE tenant.

Lealtad (Pass-through)

LIVE

Para comercios que ya tienen su propio motor de lealtad (acumulación, canje, reglas de negocio) y solo necesitan la capa de wallet + notificación de ComProPass. Credencial de tenant (x-compro-key / x-client-id / x-tenant-id, ver Autenticación). Vive en lealtadApi, no bajo /v1 — base https://us-central1-compro-saas-core.cloudfunctions.net/lealtadApi.

Pass-through, no motor de lealtad: ComProPass refleja el saldo que tu sistema le manda — sin anti-fraude, sin techos, sin lógica de acumulación propia. Tenés que traer vos el saldo ya calculado. Hay que habilitarlo por programa desde ComPro antes de usarlo (credencial + api_access del plan) — ver el código API_NO_HABILITADA más abajo.

Método Ruta Descripción
POST /members Alta idempotente de un miembro por member_id (upsert — si ya existe, devuelve el registro sin duplicar).
POST /members/batch Emisión masiva, hasta 200 filas ({"members":[...]}). No transaccional: results[] fila por fila.
GET /members/:member_id Detalle: saldo vigente, estado y artefactos de wallet.
GET /members/:member_id/pass-link Solo los artefactos de entrega (links para embeber el botón oficial de Apple/Google en tu propia app).
PUT /members/:member_id/state update pass-through: fijás el saldo actual, nosotros lo reflejamos. Cuenta como MAU siempre (por la acción, no por si la tarjeta está instalada).
POST /members/:member_id/deactivate Baja (soft-delete) — el registro nunca se borra, solo queda inactivo, y se intenta revocar la tarjeta en ambos SO. Si algún SO no se pudo revocar (ej. Google no respondió), la respuesta es 207 con success:false, code:"REVOCACION_INCOMPLETA" y el detalle en pass.problems — el registro ya quedó inactivo (idempotente: reintentar es seguro), solo falta la revocación del pase.
POST /members/:member_id/push · /push Reservadas — 501 por ahora, push proactivo/marketing llega en una próxima versión.

Flujo de integración recomendado:

0. Antes de empezar. ComPro debe haber emitido tu credencial y encendido el modo pass-through del programa. Con el modo apagado, toda la API responde 409 PASSTHROUGH_NO_ACTIVO. Con el modo encendido, la caja y las campañas propias de ComPro para ese programa quedan cerradas (409): el saldo lo decide solo tu sistema, por esta API.

1. Alta. POST /members (o /members/batch) con member_id y name. Un miembro tiene que existir antes de poder actualizarlo: PUT /state sobre un member_id que no diste de alta responde 404. Es idempotente, repetirla no duplica.

2. Entrega. La respuesta del alta trae apple_pass_url y google_save_url. Si los necesitás de nuevo, GET /members/:member_id/pass-link.

3. Actualizar el saldo. PUT /members/:member_id/state con el saldo actual (no un delta). Es silencioso: la tarjeta se actualiza en el teléfono, pero no suena ninguna notificación.

4. Consultar. GET /members/:member_id devuelve el saldo vigente y el estado de cada tarjeta.

5. Baja. POST /members/:member_id/deactivate. Después, actualizar o consultar el link responde 409 MIEMBRO_INACTIVO.

Notificaciones. Hoy esta API no envía notificaciones (/push responde 501). El push proactivo y de marketing es parte de la próxima versión.

Campos del body (alta — POST /members y cada fila de /members/batch):

Campo ¿Obligatorio? Para qué sirve
member_idrequeridoLa llave que usa TU sistema (NIT, DPI, código propio) — opaca para nosotros, no se valida ni se interpreta. Nunca es el id del documento ni viaja en ningún endpoint público.
namerequeridoNombre real de la persona — sin esto la tarjeta muestra el genérico "Cliente" en vez del nombre, así que lo exigimos en la alta (no en el update, que nunca lo toca).
balanceopcionalSaldo inicial, entero. Default 0 si no lo mandás.
display_codeopcionalCódigo corto que se imprime en la tarjeta. Si no lo mandás, generamos uno — nunca es el member_id.
emailopcionalSolo se guarda — pass-through no manda ningún correo propio (ni de bienvenida, ni de nada).
phoneopcionalSolo se guarda.
fieldsopcionalArreglo [{label, value}] para el dorso de la tarjeta — mismo contrato que PUT /pass-fields de hrApi.
as_ofopcionalTimestamp ISO 8601 del dato. Si mandás actualizaciones fuera de orden, la más vieja se descarta sola (STALE).

Base y credenciales de esta API:

URL basehttps://us-central1-compro-saas-core.cloudfunctions.net/lealtadApi
Cabecerasx-compro-key, x-client-id y x-tenant-id — las tres, siempre.
Quién emite la credencialEl equipo de ComPro (no se autogestiona desde el portal). La clave se entrega una sola vez; si se pierde, se rota y la anterior deja de servir.
EntornoNo existe un entorno de pruebas separado: esta API opera sobre datos reales. Para probar, usa miembros de prueba con un member_id claramente identificable (p. ej. PRUEBA-001).

Ejemplo — alta y actualización de saldo:

curl -X POST https://us-central1-compro-saas-core.cloudfunctions.net/lealtadApi/members \
  -H "x-compro-key: {api_key}" -H "x-client-id: {client_id}" -H "x-tenant-id: {tenant_id}" \
  -H "Content-Type: application/json" \
  -d '{"member_id":"CF1234567","name":"María García","balance":150}'
{ "success": true, "created": true,
  "data": { "id": "…", "member_id": "CF1234567", "name": "María García",
    "balance": 150, "status": "active",
    "apple_pass_url": "https://…", "google_save_url": "https://…",
    "wallet_state": { "google": "unknown", "apple": "unknown" } } }
curl -X PUT https://us-central1-compro-saas-core.cloudfunctions.net/lealtadApi/members/CF1234567/state \
  -H "x-compro-key: {api_key}" -H "x-client-id: {client_id}" -H "x-tenant-id: {tenant_id}" \
  -H "Content-Type: application/json" -d '{"balance":275}'
{ "applied": true, "member_id": "CF1234567", "balance": 275, "counted_mau": true,
  "delivery": { "google": "patched", "apple": "not_installed" } }

delivery muestra qué SO recibió el aviso de verdad — not_installed significa que ese miembro todavía no agregó la tarjeta en ESE SO, así que no se intentó nada ahí (no es un error). El saldo se actualiza igual y cuenta MAU sin importar el estado de instalación.

Límites de uso:

Tamaño de lote200 filas por llamada
Emisión masivahasta 15,000 filas/hora
RecomendaciónLlamadas secuenciales, no en paralelo — no hay un intervalo mínimo obligatorio, pero evita contención innecesaria en tu propio balde de rate limit.

Códigos propios de esta sección:

HTTP code Causa
403API_NO_HABILITADAEl plan de este programa no incluye acceso por API — pedile a ComPro que lo habilite.
400FILA_INVALIDAFalta un campo obligatorio (member_id, name, balance) o tiene un formato inválido.
400LOTE_VACIO / LOTE_DEMASIADO_GRANDEmembers vacío, o más de 200 filas en un solo lote.
404NO_ENCONTRADOEl member_id no resuelve a nadie DE ESTE tenant.
409PASSTHROUGH_NO_ACTIVOEl modo pass-through del programa está apagado. Pedile a ComPro que lo encienda — mientras tanto, ninguna ruta de esta API responde.
409MIEMBRO_INACTIVOEl miembro está dado de baja — no se puede actualizar ni consultar el link de pase.
409PROGRAMA_NO_SOPORTADOEl tenant no es de tipo points (único tipo soportado por ahora).
409UMBRAL_BAJASSe alcanzó el tope de bajas por hora — protección contra un middleware con un bug dando de baja la base entera en cadena.
429RATE_LIMITTope de peticiones por hora alcanzado para este tenant — nunca se comparte con otro cliente.
501NO_IMPLEMENTADOPush proactivo/marketing — reservado, disponible en una próxima versión.

Students API

LIVE

Verificación de identidad y control de asistencia/acceso para programas de tipo student (carné de estudiante). El QR del carné abre el validador; el mismo token se consume por API para verificar o marcar asistencia.

Método Ruta Auth Descripción
GET /v1/students/:token/verify público Verifica el carné y devuelve identidad + atributos que la institución expone.
POST /v1/students/:token/scan sesión staff Registra un evento de asistencia/acceso (scan_event).

Ejemplo — verificar un carné (público):

curl https://compropass.app/api/v1/students/<token>/verify
{
  "verified": true,
  "student": {
    "name": "María Rodríguez",
    "status": "active",
    "institution": "Universidad Latinoamericana",
    "attributes": [
      { "label": "Carrera",  "value": "Ing. en Computación" },
      { "label": "Facultad", "value": "Facultad de Ingeniería" },
      { "label": "Carné",    "value": "B12345" }
    ]
  },
  "verified_at": "2026-07-24T..."
}

Webhooks del programa student:

Evento Se dispara cuando…
student.scannedSe registra una asistencia/acceso con el carné.
student.enrolledSe emite un nuevo carné de estudiante.
student.suspendedSe da de baja/suspende un carné (deja de validar).
comunicado.acknowledgedUn estudiante acusa recibo de un comunicado.

Entrega con firma HMAC (X-Compro-Signature) y reintentos; registro en webhook_logs. Configuración por tenant desde el portal: Configuración → API & Webhooks.


Care API

requiere key

Gestión de pacientes y registro de visitas para programas de tipo patient. Documentación detallada disponible en el portal: Configuración → API & Webhooks.

Método Ruta Descripción
GET /v1/care/patients Listar pacientes
POST /v1/care/patients Crear paciente
GET /v1/care/patients/:id Detalle de paciente
POST /v1/care/patients/:id/visits Registrar visita

Events API

requiere key

Gestión de boletos y check-in para programas de tipo event. Documentación detallada disponible en el portal.

Método Ruta Descripción
GET /v1/events/tickets Listar boletos
POST /v1/events/tickets Crear boleto
GET /v1/events/tickets/:id Detalle de boleto
POST /v1/events/tickets/:id/checkin Check-in de boleto

Guía: Agente Claude con KB API

Patrón recomendado para conectar un agente de soporte basado en Claude API con la Knowledge Base de ComProPass usando tool use.

1. Definir el tool en Claude API

{
  "name": "search_knowledge_base",
  "description": "Busca artículos en la base de conocimiento de ComProPass para responder preguntas de soporte L1. Úsalo cuando el usuario pregunte sobre Wallet, puntos, sellos, vCard o acceso al portal.",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "Término de búsqueda relevante a la pregunta del usuario"
      },
      "audience": {
        "type": "string",
        "enum": ["public", "manager", "cashier"],
        "description": "Audiencia del artículo según el rol del usuario"
      }
    },
    "required": ["query"]
  }
}

2. Implementar el tool handler

// Node.js — cuando Claude llama search_knowledge_base
async function handleToolCall(toolName, toolInput) {
  if (toolName === 'search_knowledge_base') {
    const { query, audience = 'public' } = toolInput;
    const url = new URL('https://compropass.app/v1/kb');
    url.searchParams.set('q', query);
    url.searchParams.set('audience', audience);
    url.searchParams.set('limit', '5');
    const res = await fetch(url.toString());
    const data = await res.json();
    return data.articles.map(a => `## ${a.title}\n${a.content}`).join('\n\n');
  }
}

3. Flujo completo

1 Usuario envía pregunta → Claude recibe con el tool search_knowledge_base disponible
2 Claude decide si necesita buscar en KB y llama el tool con un query relevante
3 Tu backend llama GET /v1/kb?q=... y devuelve los artículos a Claude como tool_result
4 Claude sintetiza una respuesta clara usando el contenido real del KB