Primeros pasos
Obtén tus credenciales. El equipo Conntodo te entrega la X-App-Key de tu
aplicación (identidad pública, no es un secreto de autenticación), un usuario de la plataforma y un
workspace sandbox con datos sintéticos para integrar sin tocar producción.
Headers obligatorios. Todas las llamadas llevan:
| Header | Valor | Cuándo |
|---|---|---|
X-App-Key | clave pública de tu aplicación | siempre (incluye validate/login) |
Accept | application/json | siempre |
Authorization | Bearer {token} | tras el login |
X-Workspace-ID | id del workspace activo | en todos los recursos de negocio |
Autentícate en dos pasos — valida el email (devuelve los workspaces de tu app) y luego haz login sobre uno:
curl -X POST https://api.conntodo.com/api/v1/validate \
-H "Content-Type: application/json" -H "X-App-Key: $APP_KEY" \
-d '{"email":"integrador@tuempresa.com"}'
curl -X POST https://api.conntodo.com/api/v1/login \
-H "Content-Type: application/json" -H "X-App-Key: $APP_KEY" \
-H "X-Workspace-ID: 42" \
-d '{"email":"integrador@tuempresa.com","password":"…"}'
# → data.token (Bearer, 15 días; renovable)
Entiende el contrato de respuesta. Un único envelope en éxito y error; el
error_code es estable — discrimina causas por él, nunca parseando message:
// Éxito // Error
{ {
"status": "success", "status": "error",
"code": 200, "code": 403,
"data": { … }, "error_code": "MODULE_NOT_IN_PLAN",
"message": "…" "message": "…"
} }
Importa la colección Postman
(con el environment sandbox): 178 requests con los
headers ya inyectados. Variables a fijar: baseUrl, app_key, bearerToken,
workspace_id.
/api/v1. Las rutas legacy /api/*
responden con headers Deprecation: true y Sunset: 2027-07-31. Política: los cambios
breaking solo llegan con versión mayor y un mínimo de 6 meses de deprecación anunciada en el
changelog.
Listas y paginación
Toda lista sigue el mismo contrato: los elementos van en data (array) y la
paginación en meta. Controla el tamaño con ?per_page (default 20,
máximo 100) y la página con ?page.
{
"status": "success",
"code": 200,
"data": [ { … }, { … } ],
"meta": {
"current_page": 1, "last_page": 5, "per_page": 20,
"total": 92, "has_more": true, "from": 1, "to": 20
}
}
Conceptos de la plataforma
La unidad de aislamiento multitenant: cada empresa opera en su workspace con sus usuarios, roles, datos y
configuración. Todo recurso de negocio exige X-Workspace-ID y la membresía se valida en el servidor.
El producto/front desde el que se consume (Confiable, Summit, …). Se identifica con X-App-Key:
filtra los workspaces visibles en el login y define branding y correo de los envíos.
Las capacidades (procesos, clientes, agenda, calidad, formularios…) son módulos con alcance
system (siempre), business (según plan/modo) o addon (comprables). Si un módulo no está
en el plan del workspace la API responde 403 MODULE_NOT_IN_PLAN.
Plantillas de operación por workspace (multipruebas, calendario, ips, iptc…): definen vistas, secciones visibles y tema. Solo afectan presentación/configuración — los datos viven en las mismas tablas.
Los catálogos y etiquetas de campos se adaptan por industria del workspace (p. ej. «prueba» vs «proceso», «poligrafista» vs «evaluador»). Los keys de la API no cambian; solo los labels.
Catálogos configurables por workspace (servicios, estados, sedes, checklist de calidad…). Los endpoints devuelven los valores adoptados por el workspace, no listas globales.
Integración server-to-server
Para sistemas que consumen la API sin un usuario interactivo (ERP, middleware), Conntodo emite client credentials (OAuth2). Cada credencial queda atada a un workspace: sus tokens solo operan ese workspace, con los scopes que se le autoricen — el integrador nunca declara el workspace en los headers, lo resuelve el servidor desde la credencial.
Solicita tu credencial al equipo Conntodo indicando el workspace y los
scopes necesarios. Recibirás un client_id y un client_secret
(este último se muestra una sola vez).
Obtén un token con el grant client_credentials:
curl -X POST https://api.conntodo.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "TU_CLIENT_ID",
"client_secret": "TU_CLIENT_SECRET",
"scope": "processes.read"
}'
# → { "access_token": "…", "token_type": "Bearer", "expires_in": … }
Consume la superficie /api/v1/m2m con el Bearer. Sin headers de
workspace — el binding de la credencial manda:
curl https://api.conntodo.com/api/v1/m2m/processes \
-H "Authorization: Bearer {access_token}"
Scopes disponibles
| Scope | Permite |
|---|---|
processes.read | Leer procesos del workspace |
processes.write | Crear y actualizar procesos |
clients.read | Leer clientes/empresas del workspace |
forms.read | Leer formularios y sus envíos |
webhooks.manage | Gestionar webhooks salientes |
Un token puede pedir menos scopes de los
autorizados, nunca más. Pedir un scope fuera de lo permitido devuelve
403 PERMISSION_DENIED.
Webhooks salientes
Conntodo puede notificar a tu sistema cuando ocurren eventos en un workspace. Registra un endpoint (HTTPS) desde Ajustes → API/Webhooks o pídelo al equipo; recibirás un secreto de firma (se muestra una sola vez).
Eventos
| Evento | Se emite cuando… |
|---|---|
process.created | se crea un grupo de procesos |
process.status_changed | un proceso cambia de estado |
form.submission.created | se inicia un envío de formulario |
payment.confirmed | se aprueba un pago |
Formato de entrega
Cada evento llega como POST con este cuerpo y headers:
POST https://tu-endpoint/hook
X-Conntodo-Event: process.status_changed
X-Conntodo-Signature: <hex sha256>
{
"event": "process.status_changed",
"created_at": "2026-07-07T00:00:00+00:00",
"data": { "process_id": 123, "from": "activo", "to": "finalizado", ... }
}
Verificar la firma
Calcula un HMAC-SHA256 del cuerpo crudo con tu secreto y compáralo
(tiempo constante) contra X-Conntodo-Signature. Rechaza si no coincide.
// Node.js
const expected = crypto.createHmac('sha256', SECRET)
.update(rawBody).digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return res.status(400).end();
}
2xx en menos de 10 segundos. Cualquier otra respuesta se
reintenta hasta 3 veces con espera creciente (30s, 5min). Diseña tu
handler idempotente: un mismo evento puede llegar más de una vez.
Catálogo de códigos de error
Strings estables: agregar códigos es seguro; renombrar o eliminar uno es breaking change.
| error_code | HTTP | Significado |
|---|---|---|
UNAUTHENTICATED | 401 | Token ausente, inválido o vencido. |
FORBIDDEN | 403 | Autenticado pero sin acceso al recurso. |
PERMISSION_DENIED | 403 | Falta el permiso granular requerido en el workspace. |
ACCOUNT_LOCKED | 403 | Cuenta bloqueada por seguridad. |
WORKSPACE_HEADER_REQUIRED | 400 | Falta X-Workspace-ID. |
WORKSPACE_ID_INVALID | 400 | X-Workspace-ID no es un id válido. |
WORKSPACE_ACCESS_DENIED | 403 | El usuario no es miembro de ese workspace. |
WORKSPACE_CONTEXT_REQUIRED | 400 | El endpoint exige contexto de workspace. |
MODULE_NOT_IN_PLAN | 403 | Módulo no incluido en el plan del workspace. |
SUBSCRIPTION_EXPIRED | 403 | Suscripción vencida — renovar para continuar. |
NOT_FOUND | 404 | Ruta o recurso inexistente (o de otro workspace). |
VALIDATION_FAILED | 422 | Datos inválidos; detalle por campo en errors. |
CONFLICT | 409 | Estado en conflicto (p. ej. duplicado). |
RATE_LIMITED | 429 | Límite de tasa excedido — respeta Retry-After. |
BAD_REQUEST | 400 | Request malformada. |
SERVER_ERROR | 500 | Error interno — reintenta con backoff. |
Changelog de la API
- Integración server-to-server: client credentials (OAuth2) atados a
workspace, con scopes por módulo, y superficie
/api/v1/m2m. Ver la guía. - Webhooks salientes firmados (HMAC-SHA256):
process.created,process.status_changed,form.submission.created,payment.confirmed. Ver la guía. - Rate limiting por plan del workspace (
429 RATE_LIMITEDconRetry-After). - Contrato de listas unificado: elementos en
data, paginación enmeta(antes algunas listas anidaban endata.data).
- Nuevo header
X-App-Key(identidad pública por aplicación): filtra los workspaces de/validatey rechaza logins cruzados entre aplicaciones (403 workspace_not_in_app). Sin la clave el comportamiento anterior se mantiene. - Nuevos módulos
agenda(sedes, disponibilidad, citas, bloqueos) ycalidad(revisión QA de procesos) — ver referencia. - Pagos:
POST /payments/checkout,GET /payments/intents/{uuid}yGET /billing/summary; pasarelas Wompi, ePayco, Mercado Pago y Stripe.
- Envelope único en TODAS las respuestas (incluidas excepciones no manejadas) y catálogo
error_codeestable. /api/v1como superficie oficial; rutas legacy/api/*con headersDeprecation+Sunset: 2027-07-31.- Paginación normada:
?per_pagedefault 20, máximo 100. - Colección Postman y environment sandbox publicados.