🚀 Primeros Pasos con MATICERTS
Bienvenido a MATICERTS, la plataforma moderna para emisión y gestión de certificados digitales. Esta documentación te guiará paso a paso para integrar nuestra API REST en tu aplicación.
MATICERTS es una solución empresarial que permite solicitar, emitir, descargar, renovar y revocar certificados digitales (incluida la verificación de identidad KYC cuando aplica), con autenticación Bearer OAuth 2.0 y Personal Access Tokens para integraciones sistema a sistema. Perfecta para ERPs, CRMs, portales web y sistemas automatizados.
🌍 Elige tu Entorno
Contamos con dos entornos completamente independientes. Cada uno expone su propia aplicación web (el panel donde gestionas tu cuenta) y su propia API REST (la que integras en tu sistema).
Producción
Validez legalInfraestructura real. Los certificados emitidos tienen plena validez legal.
- Aplicación web
- app.maticerts.com
- URL base de la API
https://api.maticerts.com/api/v1
Sandbox
GratuitoEntorno de pruebas para tu ciclo de desarrollo. Sin impacto ni validez legal.
- Aplicación web
- sandbox-app.maticerts.com
- URL base de la API
https://sandbox-api.maticerts.com/api/v1
Entra primero a la aplicación web de Sandbox: ahí creas tu cuenta y generas el Personal Access Token (PAT) que necesitarás para llamar a la API. Cuando tu integración funcione, repite el proceso en Producción.
En Sandbox puedes recorrer el ciclo completo de una solicitud sin generar certificados reales. La emisión, la verificación de identidad (KYC), la descarga y la revocación se simulan, y la solicitud avanza sola de estado (en una solicitud documental, el certificado queda listo unos 30 segundos después del envío). El certificado entregado está firmado por una CA de pruebas (o es auto-firmado, con un nombre que empieza por SANDBOX), así que no sirve para firmar documentos con validez legal. Los cambios de estado sí disparan tus webhooks y notificaciones, para que pruebes tu integración de punta a punta. Los pagos se procesan contra la pasarela de pruebas de Wompi, sin cobros reales.
Parametriza la base URL
En los ejemplos de esta documentación usamos {'{{URL}}'} como marcador de la base URL de la API (incluye el prefijo /api/v1). Configúralo por entorno:
# Sandbox
MATICERTS_API_URL=https://sandbox-api.maticerts.com/api/v1
# Producción
# MATICERTS_API_URL=https://api.maticerts.com/api/v1
Nunca hardcodees las URLs ni los tokens en el código. Usa variables de entorno para cambiar entre Sandbox y Producción sin recompilar tu aplicación.
🔐 Autenticación: Elige tu Método
Salvo los endpoints públicos (catálogos: countries, departments, cities, identity-documents, organization-type, entity-document-types; términos vigentes terms/current; auth/login; y registro, verificación y recuperación de cuenta: register, verify-email, email/verification-notification, forgot-password, reset-password), todas las peticiones a MATICERTS deben incluir un Bearer Token en el encabezado Authorization. Recomendamos enviar además Accept: application/json. Ofrecemos dos métodos según tu caso de uso:
Métodos Soportados
- 🤖 Backend (M2M) - Recomendado
- 👤 Aplicaciones Cliente
Ideal para: ERPs, CRMs, Cronjobs e integraciones automatizadas.
Usa un Personal Access Token (PAT) que generas desde la aplicación web
(Producción · Sandbox)
o por API con POST /api/v1/tokens, autenticándote con el token obtenido en POST /api/v1/auth/login:
curl -X POST "{{URL}}/tokens" \
-H "Authorization: Bearer <TOKEN_DE_LOGIN>" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{ "name": "Token ERP Producción", "expires_in_days": 90 }'
name es obligatorio (de 3 a 255 caracteres). expires_in_days es opcional (acepta de 1 a 365; 90 por defecto) y define la fecha informada en expires_at (ver la nota de abajo). La respuesta trae data.id, data.token y data.expires_at.
Todo PAT es válido 90 días desde su creación. expires_in_days define la fecha expires_at que muestran la respuesta y el listado GET /api/v1/tokens:
- Si pides más de 90 días, el token responde
401a partir del día 90 aunqueexpires_atindique una fecha posterior. - Si pides menos de 90 días, el token deja de aparecer en
GET /api/v1/tokenscuando pasa suexpires_at, pero sigue autenticando hasta el día 90. Si necesitas cortarlo antes, revócalo conDELETE /api/v1/tokens/{id}.
Planifica la rotación de tus PAT a los 90 días de crearlos, no según expires_at.
| Ventaja | |
|---|---|
| ✅ | Vigencia de 90 días desde la creación |
| ✅ | Sin ciclo de refresh por petición: antes de que expire, renuévalo con POST /api/v1/tokens/{id}/renew (emite un token nuevo de 90 días y revoca el anterior) |
| ✅ | Revocables en cualquier momento desde la aplicación web, con DELETE /api/v1/tokens/{id} o todos a la vez con POST /api/v1/tokens/revoke-all |
El valor del token solo se muestra una vez, al crearlo o renovarlo. Puedes hacer hasta 10 intentos de creación en 24 horas, contadas desde el primer intento; cuentan también los intentos rechazados por validación (429 al superarlo; la renovación no cuenta para este límite). Programa la renovación antes de cumplir 90 días desde la creación: un PAT vencido responde 401. Consulta tus tokens y su expires_at con GET /api/v1/tokens (en un PAT creado con expires_in_days distinto de 90, esa fecha no coincide con la vigencia real).
Guárdalo en variables de entorno, nunca en el repositorio ni en el código del navegador. Si se filtra, revócalo de inmediato desde la aplicación web o con DELETE /api/v1/tokens/{id}. Si sospechas que la cuenta se comprometió, usa POST /api/v1/tokens/revoke-all: revoca todos tus PAT y tokens de sesión, incluido el que usaste en la petición.
Ideal para: Portales web, aplicaciones móviles e interfaces de usuario.
Obtén un token de sesión autenticando al usuario final. Es válido 90 días por defecto (consulta expires_at en la respuesta); no existe refresh token, así que cuando expire el usuario debe volver a iniciar sesión.
curl -X POST "{{URL}}/auth/login" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"email": "usuario@empresa.com",
"password": "tu-contraseña-segura"
}'
Respuesta 200 OK (valores ilustrativos; user es el objeto completo del usuario):
{
"success": true,
"message": "Inicio de sesión exitoso.",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
"expires_at": "2026-12-26 10:00:00",
"user": { "...": "datos del usuario" },
"company": {
"has_agreement": false,
"company_type_id": 1,
"issuance_provider": "dual",
"company_name": "MI EMPRESA S.A.S.",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
}
}
company es una foto del momento del inicio de sesión. Los valores vigentes de issuance_provider y has_agreement (convenio pospago) los trae GET /api/v1/quota/status.
Errores habituales:
404conCredenciales inválidas., o con un mensaje que indica que el usuario o la empresa se encuentran inactivos.400si el correo electrónico aún no está verificado.422si faltanemailopassword, o siemailno tiene formato de correo (el detalle viene enerrors).
Para cerrar la sesión y revocar el token usa GET /api/v1/auth/logout con el encabezado Authorization: Bearer <token>.
⏱️ Límites de peticiones
La API admite 60 peticiones por minuto por usuario autenticado (o por IP si la petición no lleva token). Algunos endpoints tienen además límites propios:
| Operación | Límite |
|---|---|
Crear solicitud (POST /api/v1/certificate-request) | 10 por minuto |
Subir archivos (POST /api/v1/certificate-request/{id}/files) | 20 por minuto |
Emitir certificado (POST /api/v1/certificate-request/{id}/issue) | 5 por minuto |
Crear Personal Access Token (POST /api/v1/tokens) | 10 intentos en 24 horas (cuentan también los fallidos) |
Si superas un límite recibirás 429 Too Many Requests. En el límite general, la respuesta incluye la cabecera Retry-After (en segundos) y las cabeceras X-RateLimit-Limit / X-RateLimit-Remaining. En un límite por endpoint, la respuesta es un JSON { "success": false, "message": "..." } sin Retry-After: espera al menos un minuto antes de reintentar (en el caso de los tokens, hasta que se cumplan 24 horas desde el primer intento) y usa un backoff exponencial.
🛠️ Tu Primera Petición: Valida tu Token
Comprueba que tu token es válido consultando el usuario dueño del token. Reemplaza <TU_ACCESS_TOKEN> con tu token real:
- cURL
- Node.js / Fetch
- Python (Requests)
curl -X GET "{{URL}}/auth/user" \
-H "Authorization: Bearer <TU_ACCESS_TOKEN>" \
-H "Accept: application/json"
const response = await fetch('{{URL}}/auth/user', {
method: 'GET',
headers: {
'Authorization': 'Bearer <TU_ACCESS_TOKEN>',
'Accept': 'application/json'
}
});
const data = await response.json();
console.log(data);
import requests
url = "{{URL}}/auth/user"
headers = {
"Authorization": "Bearer <TU_ACCESS_TOKEN>",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())
Si el token es válido recibirás 200 OK con { "success": true, "dataRecords": { "data": [ ... ] } }: data es un arreglo con un único elemento, el usuario autenticado (esquema AuthUser en la referencia de Autenticación). Si el token falta, no es válido, expiró o fue revocado recibirás 401 con { "success": false, "message": "No autenticado." }.
📚 Próximos Pasos
¡Excelente! Tu token funciona y ya puedes consumir la API.
🗺️ El ciclo de vida de una solicitud en la API
- Crear la solicitud:
POST /api/v1/certificate-request(JSON). Cada solicitud tiene un tipo de emisión (issuance_flow):BIOMETRIC(con verificación biométrica de identidad) oDOCUMENTARY(documental, sin biometría). Si no lo envías, se usa el tipo por defecto de tu empresa (ver la nota de abajo). En una solicitudDOCUMENTARY, los soportes (2 a 3 archivos) van en Base64 dentro deattachmentsen esta misma petición; sin ellos responde400y la solicitud no se crea.POST /api/v1/certificate-request/{id}/filessirve solo para agregar archivos después. - Emitir: en una solicitud
BIOMETRICla emisión arranca sola al crearla (no llames a/issuejusto después: normalmente responde409o422); en unaDOCUMENTARY, envíala conPOST /api/v1/certificate-request/{id}/issue. Consulta el avance conGET /api/v1/certificate-request/{id}/issuance. - Verificar identidad (KYC, solo solicitudes
BIOMETRIC): obtén el enlace que debe abrir el suscriptor conGET /api/v1/certificate-request/{id}/kyc-link. - Descargar (solicitud en
PROCESSED):GET /api/v1/certificate-request/{uuid}/issuance/download(URL y PIN) oGET /api/v1/certificate-request/{uuid}/issuance/download/base64. Usa el UUID de la solicitud, no su ID numérico. - Renovar (certificados biométricos de 1 año): puedes renovar en cualquier momento desde la emisión hasta
revocation_date(vencimiento + 15 días de gracia). Consulta la elegibilidad, el precio y si ya hay una orden pendiente conGET /api/v1/certificate-request/{id}/issuance/renewal. Genera la orden conPOST /api/v1/certificate-request/{id}/issuance/renew(si ya hay una pendiente, se reutiliza) y págala con los endpoints de Órdenes. Esta llamada no cobra. - Rechazar o revocar (solo solicitudes
BIOMETRIC, ambos irreversibles):POST /api/v1/certificate-request/{id}/issuance/rejectconreasonpara un trámite en curso sin certificado (la solicitud queda cancelada y hay que crear una nueva), oPOST /api/v1/certificate-request/{uuid}/revokeconrevoking_code(elrevocation_codedeGET .../issuance) yrevocation_reasonpara un certificado ya emitido. - Recibir eventos: registra un webhook con
POST /api/v1/webhooks(catálogo enGET /api/v1/webhooks/events; generan entregas los eventoscertificate_request.*y, desde la 1.21.1,payment.approvedypayment.failed, con el resultado del pago de tus órdenes) y valida la cabeceraX-Webhook-Sig(t=<timestamp>,v1=<HMAC-SHA256 del cuerpo crudo con el secret>). Más detalles en Webhooks.
company.issuance_provider (en el login y en GET /api/v1/company) indica qué tipos puede usar tu empresa. Nunca es null:
issuance_provider | Tipos que puedes usar | Tipo por defecto (sin issuance_flow) |
|---|---|---|
viafirma | BIOMETRIC | BIOMETRIC |
mail | DOCUMENTARY | DOCUMENTARY |
dual | BIOMETRIC y DOCUMENTARY | DOCUMENTARY: para una emisión biométrica envía "issuance_flow": "BIOMETRIC" |
El tipo se fija al crear la solicitud y no cambia después. Los precios (GET /api/v1/pricing), las compras (POST /api/v1/orders) y el saldo (GET /api/v1/quota/status, desglosado en by_flow) también van por tipo de emisión: un certificado comprado para un tipo solo se usa en solicitudes de ese tipo. Para decidir qué hacer con una solicitud, guíate siempre por su issuance_flow, no por la empresa. Detalle en la Guía Paso a Paso y en los Casos de Uso.
Continúa por aquí:
Genera tu token
Entra a la aplicación web de Sandbox (Ajustes → Tokens de API) y crea tu Personal Access Token.
Explora el catálogo
Descubre todos los endpoints disponibles con ejemplos ejecutables.
Guía paso a paso
Implementa tu primer flujo completo de emisión de certificados.
Casos de uso
Revisa ejemplos reales de integración con ERPs y portales web.
Troubleshooting
Resuelve los errores más frecuentes durante la integración.
Si tienes dudas, consulta nuestra sección de Preguntas Frecuentes o contacta al equipo de soporte.