Documentación de la API

Todo lo necesario para integrar el envío de notificaciones certificadas desde tu propio sistema.

En esta página

Prueba la API ahora mismo

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.

Autenticación

Hay dos mecanismos distintos según el endpoint — no todos piden API key:

Crear y listar
POST /v1/notifications
GET /v1/notifications
Requieren API key. Identifica a tu organización — un listado nunca devuelve notificaciones de otra organización.
Consultar por id
GET /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.

Crear una notificación certificada

POST /v1/notifications

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"
  }'
tostring (email), requerido — destinatario.
subjectstring, requerido.
body_textstring, requerido — cuerpo en texto plano.
body_htmlstring, opcional — cuerpo alternativo en HTML.
sender_namestring, opcional (default "NotifiCert").
sender_emailstring, opcional — usado como Reply-To.
channelstring, opcional (default "email").
customer_refstring, opcional — tu propio identificador del cliente (ej. RUT), para poder buscar el envío después sin depender del correo.
attachmentsarray, opcional — ver sección Adjuntos.
variablesobjeto, 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..."
    }
  ]
}

Adjuntos

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:

1. Contenido directo en base64

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)\"
    }]
  }"

2. Plantilla PDF por URL, con variables

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.

filenamestring, opcional (default "adjunto" o "documento.pdf" según el modo).
content_typestring, opcional (default "application/octet-stream").
content_base64string — contenido del archivo en base64. Requerido si no usas template_url.
template_urlstring (URL) — PDF de plantilla a descargar y personalizar. Requerido si no usas content_base64.

Consultar y listar

GET /v1/notifications/{id}

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}.

GET /v1/notifications

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>"
limitint, opcional (default 20, máximo 100).
cursorstring, 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.
qstring, opcional — coincidencia parcial contra el destinatario o el customer_ref.
statusstring, 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.

Certificado y adjuntos originales

Ningún endpoint de esta sección requiere API key — ver Autenticación.

GET /v1/notifications/{id}/certificate

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
GET /v1/notifications/{id}/attachments/{attachment_id}

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
GET /v1/notifications/{id}/tsa-token

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.

GET /verify/{id}

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.

Estados y eventos

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.

queuedCreada, aún no procesada.
sentAceptada por el servidor de envío (Postmark).
deliveredConfirmada la entrega al servidor de correo del destinatario.
deferredEntrega retrasada temporalmente; se reintentará.
failedRebote o rechazo permanente.
complainedEl destinatario marcó el mensaje como spam.

Errores

Todo error se devuelve como JSON con un único campo detail describiendo qué pasó:

{ "detail": "API key inválida" }
400Datos de entrada inválidos: adjunto malformado, límites de tamaño/cantidad excedidos, template_url inválida o apuntando a un host privado.
401API key ausente, inválida, o key de prueba vencida/sin usos — solo aplica a POST /v1/notifications y GET /v1/notifications.
404El id de la notificación, el adjunto, o el certificado/token no existen (o el token TSA aún no se generó).
429Demasiadas solicitudes desde tu IP a GET /v1/notifications/{id}, /certificate o /attachments/{attachment_id} — ver Límites.

Límites

Adjuntos por notificaciónmáx. 10 archivos
Tamaño total de adjuntosmá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 prueba2 llamadas a POST /v1/notifications, expira a los 30 min
Generación de keys de pruebamá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.