Todo lo necesario para integrar el envío de notificaciones certificadas desde tu propio sistema.
Genera una API key de prueba al instante, con tu correo. Sirve para
2 llamadas a POST /v1/notifications y expira sola a los 30 minutos —
un mismo correo solo puede generar una.
Hay dos mecanismos distintos según el endpoint — no todos piden API key:
Crear y listarPOST /v1/notificationsGET /v1/notifications |
Requieren API key. Identifica a tu organización — un listado nunca devuelve notificaciones de otra organización. |
Consultar por idGET /v1/notifications/{id} y sus
sub-recursos (certificado, adjuntos, token TSA) |
No requieren API key. El id de la notificación es un UUID
no adivinable que solo conocen quien la creó y quien recibió el certificado/QR — actúa
como el token de acceso en sí mismo, igual que la página pública de verificación
/verify/{id}. |
Para los endpoints que sí la requieren, la API key va así:
# Header (recomendado) Authorization: Bearer <tu_api_key> # o como query param POST https://notificert.online/v1/notifications?api_key=<tu_api_key>
Una key ausente responde 401; una key que no exista en el
sistema también responde 401 (no hay fallback silencioso).
¿No tienes una key todavía? Genera una de prueba arriba, o usa
demo-key-12345 si estás corriendo el proyecto en local en modo demo.
Envía el correo (o lo simula, en modo demo) y arranca la cadena de eventos certificados. Devuelve de inmediato el estado y la URL del certificado.
curl -X POST https://notificert.online/v1/notifications \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <tu_api_key>" \
-d '{
"to": "destinatario@ejemplo.cl",
"subject": "Aviso importante",
"body_text": "Estimado cliente, le comunicamos que...",
"body_html": null,
"sender_name": "Mi Empresa S.A.",
"sender_email": "notificaciones@miempresa.cl"
}'
| to | string (email), requerido — destinatario. |
| subject | string, requerido. |
| body_text | string, requerido — cuerpo en texto plano. |
| body_html | string, opcional — cuerpo alternativo en HTML. |
| sender_name | string, opcional (default "NotifiCert"). |
| sender_email | string, opcional — usado como Reply-To. |
| channel | string, opcional (default "email"). |
| customer_ref | string, opcional — tu propio identificador del cliente (ej. RUT), para poder buscar el envío después sin depender del correo. |
| attachments | array, opcional — ver sección Adjuntos. |
| variables | objeto, opcional — valores para reemplazar {{variable}} en subject, body_text y en cualquier adjunto que use template_url. Ver Adjuntos. |
Header opcional Idempotency-Key: cualquier string único que
elijas (ej. el id de tu propia orden). Si reintentás la misma llamada — por timeout, sin haber
visto la respuesta original — con la misma key, te devuelve la notificación ya creada en vez de
generar una segunda certificada duplicada. Las keys son por organización: dos organizaciones
distintas pueden repetir la misma key sin chocar entre sí.
curl -X POST https://notificert.online/v1/notifications \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <tu_api_key>" \
-H "Idempotency-Key: mi-orden-00123" \
-d '{ "to": "destinatario@ejemplo.cl", "subject": "Aviso importante", "body_text": "..." }'
Respuesta (200):
{
"id": "f3210ad1-59fa-4ead-8a9b-2838df5553d1",
"status": "sent",
"content_hash": "f8019b77...",
"created_at": "2026-07-14T02:18:50.858634",
"certificate_url": "https://notificert.online/v1/notifications/{id}/certificate",
"attachments": [
{
"id": "9f980ac0-...",
"filename": "informe.pdf",
"content_type": "application/pdf",
"size_bytes": 7136,
"sha256": "bbf3c642..."
}
]
}
Se guardan con su hash SHA-256 (queda registrado en la cadena de eventos certificada) y se anexan al final del certificado PDF cuando es posible previsualizarlos. Cada adjunto se manda de una de estas dos formas — nunca ambas a la vez:
curl -X POST https://notificert.online/v1/notifications \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <tu_api_key>" \
-d "{
\"to\": \"destinatario@ejemplo.cl\",
\"subject\": \"Informe adjunto\",
\"body_text\": \"Adjuntamos el informe solicitado.\",
\"attachments\": [{
\"filename\": \"informe.pdf\",
\"content_type\": \"application/pdf\",
\"content_base64\": \"$(base64 -i informe.pdf)\"
}]
}"
En vez de mandar el archivo codificado, le pasas la URL de un PDF que ya
tiene {{variable}} escritas en el texto — el mismo motor que usa el envío
masivo del portal descarga ese PDF y reemplaza cada variable con los valores de
variables (que también se aplican a subject y body_text).
curl -X POST https://notificert.online/v1/notifications \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <tu_api_key>" \
-d '{
"to": "destinatario@ejemplo.cl",
"subject": "Aviso para {{nombre}}",
"body_text": "Estimado {{nombre}}, su póliza {{poliza}} vence el {{fecha}}.",
"attachments": [{
"template_url": "https://tu-servidor.cl/plantilla-poliza.pdf",
"filename": "aviso-poliza.pdf"
}],
"variables": {
"nombre": "Juan Pérez",
"poliza": "POL-12345",
"fecha": "01/08/2026"
}
}'
template_url debe ser una URL http/https pública — por
seguridad, se rechaza cualquier URL que resuelva a una IP privada, loopback o interna
(protección contra SSRF). Límite de tamaño: 10 MB por
plantilla descargada.
| filename | string, opcional (default "adjunto" o "documento.pdf" según el modo). |
| content_type | string, opcional (default "application/octet-stream"). |
| content_base64 | string — contenido del archivo en base64. Requerido si no usas template_url. |
| template_url | string (URL) — PDF de plantilla a descargar y personalizar. Requerido si no usas content_base64. |
Estado actual, metadata, adjuntos y la cadena completa de eventos certificados. No requiere API key — ver Autenticación.
curl https://notificert.online/v1/notifications/{id}
Respuesta (200):
{
"id": "f3210ad1-59fa-4ead-8a9b-2838df5553d1",
"status": "delivered",
"channel": "email",
"sender_name": "Mi Empresa S.A.",
"sender_email": "notificaciones@miempresa.cl",
"recipient_email": "destinatario@ejemplo.cl",
"customer_ref": "76.123.456-7",
"subject": "Aviso importante",
"content_hash": "f8019b77...",
"created_at": "2026-07-14T02:18:50.858634",
"certificate_url": "https://notificert.online/v1/notifications/{id}/certificate",
"tsa": {
"timestamped_at": "2026-07-14T02:19:03.102000",
"hash": "a17c0e2b...",
"token_url": "https://notificert.online/v1/notifications/{id}/tsa-token"
},
"attachments": [
{
"id": "9f980ac0-...",
"filename": "informe.pdf",
"content_type": "application/pdf",
"size_bytes": 7136,
"sha256": "bbf3c642...",
"download_url": "https://notificert.online/v1/notifications/{id}/attachments/9f980ac0-..."
}
],
"events": [
{ "event_type": "created", "event_data": {"...": "..."}, "event_hash": "0a1b2c...", "created_at": "2026-07-14T02:18:50.900000" },
{ "event_type": "sent", "event_data": {"...": "..."}, "event_hash": "3d4e5f...", "created_at": "2026-07-14T02:18:51.200000" },
{ "event_type": "delivered", "event_data": {"...": "..."}, "event_hash": "6a7b8c...", "created_at": "2026-07-14T02:18:58.400000" }
]
}
tsa es null hasta que la cadena llega a un estado
terminal (delivered, failed o complained) y se sella. Cada
elemento de events es un eslabón de la cadena de hashes — la misma evidencia que
muestra el certificado PDF y que recomputa /verify/{id}.
Lista paginada por cursor (keyset, no por offset numérico), con búsqueda por destinatario y filtro de estado opcionales (el mismo mecanismo que usa el buscador del portal). Requiere API key — solo lista notificaciones de tu organización.
curl "https://notificert.online/v1/notifications?limit=20&q=destinatario%40ejemplo.cl&status=delivered" \ -H "Authorization: Bearer <tu_api_key>"
| limit | int, opcional (default 20, máximo 100). |
| cursor | string, opcional — cursor opaco de paginación. Omitilo para la primera
página; para pedir la siguiente, pasá el next_cursor que trajo la respuesta
anterior. No es un número de página ni un offset — no le asumas ningún formato. |
| q | string, opcional — coincidencia parcial contra el destinatario o el customer_ref. |
| status | string, opcional — uno de los valores de la sección Estados. |
La respuesta es {"items": [...], "next_cursor": "..."} —
next_cursor viene en null cuando ya no hay más páginas.
Ningún endpoint de esta sección requiere API key — ver Autenticación.
Descarga el certificado PDF (se regenera automáticamente si algún evento cambió desde la última descarga).
curl https://notificert.online/v1/notifications/{id}/certificate -o certificado.pdf
Descarga un adjunto original tal como se guardó, para verificar su hash SHA-256 de forma independiente del certificado.
curl https://notificert.online/v1/notifications/{id}/attachments/{attachment_id} -o adjunto.pdf
shasum -a 256 adjunto.pdf # debe coincidir con el sha256 devuelto por la API
Descarga el token de sello de tiempo (RFC 3161) crudo, en formato DER, para
verificarlo de forma independiente con herramientas estándar. Es el mismo sello que viaja embebido
en el PDF del certificado como firma PAdES, extraído para poder inspeccionarlo por separado.
404 si la notificación todavía no fue sellada (ver tsa en la respuesta de
GET /v1/notifications/{id}).
curl https://notificert.online/v1/notifications/{id}/tsa-token -o token.tsr
openssl ts -reply -in token.tsr -token_in -text # inspeccionar el sello de tiempo
-token_in es necesario: esto es un TimeStampToken "pelado", no
la respuesta completa del protocolo RFC 3161.
Página HTML pública (sin autenticación) que recomputa y verifica la cadena de hashes y muestra el registro en formato legible. Es el destino del código QR del certificado — pensada para que la abra cualquier persona, no un desarrollador.
El estado de una notificación avanza a medida que Postmark confirma cada etapa. No existe un estado "leído/abierto": esa señal proviene de la precarga automática de imágenes de los proveedores de correo, no de una lectura real, así que no se certifica.
| queued | Creada, aún no procesada. |
| sent | Aceptada por el servidor de envío (Postmark). |
| delivered | Confirmada la entrega al servidor de correo del destinatario. |
| deferred | Entrega retrasada temporalmente; se reintentará. |
| failed | Rebote o rechazo permanente. |
| complained | El destinatario marcó el mensaje como spam. |
Todo error se devuelve como JSON con un único campo detail
describiendo qué pasó:
{ "detail": "API key inválida" }
| 400 | Datos de entrada inválidos: adjunto malformado, límites de tamaño/cantidad excedidos, template_url inválida o apuntando a un host privado. |
| 401 | API key ausente, inválida, o key de prueba vencida/sin usos — solo aplica a POST /v1/notifications y GET /v1/notifications. |
| 404 | El id de la notificación, el adjunto, o el certificado/token no existen (o el token TSA aún no se generó). |
| 429 | Demasiadas solicitudes desde tu IP a GET /v1/notifications/{id}, /certificate o /attachments/{attachment_id} — ver Límites. |
| Adjuntos por notificación | máx. 10 archivos |
| Tamaño total de adjuntos | máx. 7 MB (deja margen bajo el tope de 10 MB de Postmark, que se mide después de codificar en base64) |
| Usos por API key de prueba | 2 llamadas a POST /v1/notifications, expira a los 30 min |
| Generación de keys de prueba | máx. 5 por hora, por IP |
Endpoints públicos por {id} | máx. 60 solicitudes cada 5 min, por IP — aplica a GET /v1/notifications/{id}, /certificate, /attachments/{attachment_id} y /verify/{id}. No aplica a /tsa-token ni a POST/GET de /v1/notifications (esos solo están limitados por lo que permita tu API key). |
Documentación interactiva (Swagger/OpenAPI) disponible en /docs.