Integra NOM-151 y firma electrónica a tus sistemas
API REST sobre HTTPS para ERP, CRM, CLM y automatizaciones. Cada organización genera sus llaves desde Integraciones y API en el backoffice. Todas las respuestas son JSON en UTF-8 y las fechas están en UTC (ISO 8601).
Hay dos formas de usar Certifick. Identifica la tuya antes de crear la llave: define los alcances que marcas, los endpoints que llamas y el consumo de certificados.
escenario a
Firma electrónica completa
Certifick gestiona el flujo: envía el documento a los firmantes, valida con OTP, recibe la firma autógrafa o la e.firma (FIEL) del SAT, sella el PDF y al cerrarse el sobre emite la constancia NOM-151 y ancla la huella en blockchain.
Endpoints:POST /envelopes, POST /envelopes/{id}/send, GET /envelopes/{id}, GET /envelopes/{id}/documents/{docId}.
Consumo: 1 certificado por documento firmado; la constancia NOM-151 está incluida.
Úsalo si: necesitas que tus clientes o empleados firmen y quieres la evidencia legal de punta a punta.
escenario b
Solo NOM-151 (conservación)
Tu plataforma ya produce el archivo final y solo necesitas la constancia de conservación de mensajes de datos con sello de tiempo del PSC acreditado. Certifick no ve el flujo de firma; basta la huella del archivo.
Alcances:nom151:write y nom151:read.
Endpoints:POST /nom151/constancias, GET /nom151/constancias/{folio}, POST /nom151/validate.
Entrada:sha256 del archivo, o contentBase64 (máx. 20 MB) si prefieres que Certifick calcule la huella.
Guarda:folio y constanciaBase64 como archivo .asn1 junto al documento.
Necesidad
Escenario
Alcances a marcar
Recabar firmas de terceros por correo
A
envelopes:write, envelopes:read
Firmar con e.firma (FIEL) del SAT
A
envelopes:write, envelopes:read
Conservar un PDF ya firmado o un expediente
B
nom151:write, nom151:read
Verificar integridad o validar una constancia
A o B
nom151:read
Recibir notificaciones automáticas
A o B
webhooks:read
En ambos escenarios empieza con una llave de pruebas (sandbox): las constancias se emiten simuladas con folio sbx-, sin consumir certificados ni contactar al proveedor, y se pueden validar igual. Al terminar, crea la llave de producción con los mismos alcances y cambia solo el secreto. Nuestros certificados no tienen vigencia.
Inicio rápido en 5 minutos
1. En el backoffice, entra a Integraciones y API y crea una llave con los alcances nom151:write y nom151:read. El secreto se muestra una sola vez.
2. Comprueba la conexión con GET /health.
3. Calcula el SHA-256 del archivo y emite la constancia con POST /nom151/constancias.
4. Guarda folio y constanciaBase64 (archivo .asn1) junto al documento en tu sistema.
5. Verifica cuando quieras con GET /verify/{sha256} o POST /nom151/validate.
Alcances: nom151:write, nom151:read, envelopes:read, envelopes:write, webhooks:read. Límite por defecto: 120 peticiones por minuto y por llave (respuesta 429 al excederlo).
Base URL
https://certifick.com/api/public/v1
Cómo calcular el SHA-256 correctamente
Es el error más común de integración. La huella debe calcularse sobre los bytes exactos del archivo que vas a conservar, en hexadecimal minúsculas de 64 caracteres. Si el archivo cambia aunque sea un byte (por ejemplo, al re-guardarlo o al agregar metadatos), la huella cambia y la constancia deja de corresponder.
# macOS / Linux
shasum -a 256 contrato-4471.pdf
# Windows (PowerShell)
Get-FileHash contrato-4471.pdf -Algorithm SHA256
Si prefieres que Certifick la calcule, envía contentBase64 con el archivo completo (máximo 20 MB) en lugar de sha256.
Ambiente de pruebas (sandbox)
Al crear la llave, marca Llave de pruebas (sandbox). Esa llave usa los mismos endpoints y devuelve la misma estructura de respuesta, pero emite constancias simuladas: no consume certificados ni contacta al PSC. El folio inicia con sbx-, environment es sandbox y status es simulado; POST /nom151/validate también valida esas constancias simuladas. Cuando tu integración esté lista, genera una llave de producción con los mismos alcances y cambia sólo el valor del secreto.
Prueba paso a paso en Postman
La colección descargable ya trae la base URL de producción, la autorización Bearer heredada y scripts que guardan solos folio, sha256 y constanciaBase64 tras emitir la constancia.
1. Descarga la colección. Desde /api/public/v1/postman.json o con el botón “Colección de Postman” al inicio de esta página.
2. Crea tu llave sandbox. Backoffice → Integraciones y API → Crear llave → marca Llave de pruebas (sandbox) con alcances nom151:write y nom151:read. Copia el secreto cfk_…: sólo se muestra una vez.
3. Importa en Postman. Import → arrastra el archivo. Aparece la colección “Certifick API v1 — NOM-151”.
4. Configura las variables. Haz clic en el nombre de la colección (no en una petición) → pestaña Variables → pega tu llave en CERTIFICK_API_KEY y deja baseUrl como viene → Save. Ojo: Params no es lo mismo que Variables; Params sólo agrega query string a una petición.
5. Health. Ejecuta la petición 1: responde 200 con modo, organización, alcances y saldo. Un 401 significa llave mal pegada o revocada. Agrega ?deep=1 para comprobar también al PSC.
6. Emite la constancia. Petición 2: envía sha256 (64 hex en minúsculas) o contentBase64 + fileName (≤ 20 MB). Devuelve folio (con prefijo sbx- en sandbox), hashProcessed, issuedAt y constanciaBase64.
7. Guarda folio y huella. El script de la petición 2 los escribe automáticamente en las variables de la colección. Si prefieres hacerlo a mano, copia los valores en las variables folio, sha256 y constanciaBase64. El script es:
const r = pm.response.json();
if (r.folio) pm.collectionVariables.set("folio", r.folio);
if (r.hashProcessed || r.sha256)
pm.collectionVariables.set("sha256", r.hashProcessed || r.sha256);
if (r.constanciaBase64)
pm.collectionVariables.set("constanciaBase64", r.constanciaBase64);
8. Recupera y lista. Peticiones 3 y 4: GET /nom151/constancias/{{folio}} y el listado paginado de tu organización.
9. Valida la constancia. Petición 5: el body ya usa {{sha256}}, {{folio}} y {{constanciaBase64}}. Envía y debes recibir valid: true. Si responde falso, revisa que los tres valores sean de la misma emisión y que el base64 esté completo (sin saltos de línea ni recortes).
10. Verificación pública. Petición 6: GET /verify/{{sha256}}, sin llave; muestra integridad, NOM-151 y blockchain.
11. Pasa a producción. Repite el flujo con una llave sin sandbox: se contacta al PSC real y se consume un certificado por constancia (idempotente por huella, no cobra dos veces la misma).
Errores frecuentes en la prueba: invalid_hash (huella mal formada), insufficient_credits (sin saldo, sólo en producción) y psc_unavailable (reintenta).
Endpoints NOM-151
GET/health
Cualquier llave válida sirve, sin alcance específico. Devuelve la organización, sus alcances, el modo (pruebas o produccion), el saldo de certificados por país y la hora del servidor. Con ?deep=1 además comprueba en vivo la disponibilidad del proveedor de certificación, sin consumir certificados.
Emite la constancia de conservación NOM-151 de una huella, con un PSC acreditado. Consume 1 certificado. La operación es idempotente por organización y huella: repetirla devuelve 200 con la constancia existente y no consume otro certificado. Si el proveedor falla, el certificado se reversa automáticamente. Campo opcional psc para elegir un PSC habilitado (ver GET /psc).
Recupera una constancia ya emitida. Acepta el folio del PSC o la huella SHA-256, por lo que puedes reconstruir el archivo .asn1 en cualquier momento sin guardarlo tú.
GET/nom151/constancias?page=&pageSize=nom151:read
Listado paginado de las constancias de la organización (sin el archivo, para respuestas ligeras).
POST/nom151/validatenom151:read
Valida ante el PSC una constancia que ya tengas: envía sha256, folio y constanciaBase64.
Verificación pública, sin llave: integridad en Certifick, constancia NOM-151, anclaje en blockchain y sello institucional de una huella. Ideal para portales de consulta de tus clientes.
Endpoints de firma electrónica
POST/envelopesenvelopes:write
Crea un sobre con uno o más PDF en base64 y, por defecto, lo envía a firma de inmediato (send: false lo deja en borrador). Cada archivo se certifica con NOM-151 al cerrarse el sobre. psc es opcional: elige un PSC habilitado en tu país (consulta GET /psc); si lo omites se usa el PSC asignado a tu organización.
Devuelve un enlace firmado (15 minutos) al PDF certificado con las firmas estampadas y la constancia NOM-151 en base64.
Coordenadas, tipo de firma y PSC (v1.4)
Todo es opcional y compatible con integraciones actuales. Cada firmante acepta fields[] con document (1 = primer archivo, o su nombre), page, x, y, width y height en porcentaje de la página (0–100, desde la esquina superior izquierda) y kind: firma, iniciales, fecha, nombre o texto. signatureType puede ser dibujada, tipografiada, efirma (solo México) o libre. Además: externalId por firmante, requireLiveness, role: "observador", messageTemplate, reminderEveryDays y documents[].psc para elegir el PSC de un archivo concreto.
requireLiveness: true pide la prueba de vida al firmante y revisa el saldo de la bolsa antes de enviar el sobre (402 si no alcanza). Cada firmante devuelve liveness con status (pendiente, en_proceso, aprobada, rechazada, expirada), provider, startedAt, updatedAt y finishOn: con e.firma la firma siempre concluye en la computadora donde se abrió el enlace, aunque la prueba se haga en el celular; con firma dibujada o tipografiada se termina en el equipo donde se hizo la prueba. Los avisos envelope.signer_liveness_approved y envelope.signer_liveness_rejected se activan por organización en su configuración de avisos.
Retira un documento en firma o rechazado y devuelve su certificado; el sobre puede cerrarse con los demás.
Gestión de firmantes
Estatus: pendiente (en espera de turno), enviado, visto, firmado, rechazado, reemplazado, expirado. Un firmante que ya firmó algún documento o que rechazó no puede editarse ni reemplazarse (409). Tras cambiar el correo o reemplazar, el enlace anterior deja de funcionar. Envía el encabezado Idempotency-Key en PATCH, replace y remind para reintentar sin duplicar acciones.
GET/envelopes/{id}/signersenvelopes:read
Firmantes con externalId, fechas de envío, vista, firma y rechazo, y última notificación.
Consulta los documentos pendientes de firma de un usuario por su correo, aunque no tenga cuenta registrada. Solo devuelve archivos de la organización de tu llave API, uno por asignación pendiente; no incluye observadores, firmas realizadas, rechazadas ni archivos retirados o sobres vencidos. Incluye pendientes en espera de turno (waitingForTurn). Paginación de 15 por defecto, máximo 100. No genera enlaces ni elimina la prueba de vida u OTP.
Reenvía la invitación; máximo una vez cada 10 minutos por firmante (429).
Webhooks firmados
Registra una URL HTTPS y suscríbete a los eventos que necesites. Cada entrega incluye X-Zign-Event, X-Zign-Timestamp y X-Zign-Signature. Valida la firma recalculando el HMAC-SHA256 de `${timestamp}.${cuerpo}` con tu secreto antes de procesar el evento.
Eventos: nom151.constancia.emitida, nom151.constancia.fallida, envelope.created, envelope.sent, envelope.signer_signed, envelope.completed, envelope.declined, envelope.document.declined, envelope.expired, document.certified, envelope.document.completed, envelope.document.replaced, envelope.document.withdrawn, envelope.partially_completed, envelope.cancelled, envelope.signer_viewed, envelope.signer_updated, envelope.signer_replaced, envelope.signer_declined, envelope.signer_liveness_approved y envelope.signer_liveness_rejected (con el firmante completo y los externalId). Cada firmante trae liveness con status (pendiente, en_proceso, aprobada, rechazada, expirada), fechas y finishOn (computadora con e.firma, o el dispositivo de la prueba). Estados del sobre: borrador, en_proceso, completado, completado_parcial (algunos archivos rechazados o retirados), rechazado, expirado, cancelado. Cada archivo en documents[] trae status (en_firma, completado, rechazado, retirado) y declinedReason.
Anclaje blockchain
Cada huella certificada se agrega como hoja de un árbol Merkle diario cuya raíz se ancla en Bitcoin a través de OpenTimestamps. Cualquiera puede comprobar que un documento formó parte de ese conjunto sin revelar su contenido.
# Consultar el anclaje de una fecha (público)
GET https://certifick.com/api/public/v1/blockchain/anchors/2026-08-31
# Verificar un archivo desde el navegador (el archivo nunca se sube)
https://certifick.com/verificar-blockchain