Claves API

Las claves API te permiten acceder a tus datos de DMARC Examiner de forma programática a través de la API REST. Úsalas para integrar la monitorización DMARC en tus propias herramientas, dashboards o flujos de automatización.

Crear una clave API

  1. Ve a Ajustes > Claves API
  2. Pulsa Crear clave API
  3. Introduce un nombre descriptivo para la clave (p. ej. "Dashboard de monitorización", "Pipeline de CI")
  4. Copia la clave en ese momento: solo se muestra una vez

Cada organización puede tener hasta 5 claves API activas. Las claves pertenecen a la organización y dan acceso de lectura a todos sus dominios, informes y alertas.

Formato de la clave API

Las claves API siguen el formato dex_ seguido de 32 caracteres hexadecimales:

dex_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

El prefijo dex_ identifica la clave como una clave API de DMARC Examiner. En Ajustes solo se muestran los 8 primeros caracteres para identificarla.

Autenticación

Incluye tu clave API en la cabecera X-API-Key en cada petición:

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/domains

Endpoints disponibles

Dominios

Listar dominios

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/domains

Respuesta:

{
  "data": [
    {
      "id": "uuid",
      "name": "example.com",
      "status": "active",
      "verified_at": "2025-01-15T10:30:00Z",
      "last_report_at": "2025-03-20T08:00:00Z",
      "created_at": "2025-01-10T09:00:00Z"
    }
  ]
}

Crear un dominio

curl -X POST \
  -H "X-API-Key: dex_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name":"example.com"}' \
  https://api.dmarc-examiner.com/api/v1/domains

Devuelve 201 Created con el dominio creado. La respuesta incluye reporting_email y dmarc_record — cópialos en tu DNS para empezar a recibir informes DMARC. Devuelve 409 Conflict si el dominio ya existe en la organización, o un error de límite de plan si superas el cupo.

Obtener un dominio

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/domains/{domain_id}

Verificar un dominio

Re-consulta el DNS para localizar tu reporting email y actualiza el estado del dominio si lo encuentra.

curl -X POST \
  -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/domains/{domain_id}/verify

Devuelve 200 OK con {"verified": true, "domain": {...}} en caso de éxito, o 422 Unprocessable Entity con la razón si el DNS aún no contiene el reporting email.

Eliminar un dominio

curl -X DELETE \
  -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/domains/{domain_id}

Devuelve 204 No Content en caso de éxito.

Comprobar registro DMARC existente (cualquier dominio)

Utilidad libre — no requiere que el dominio pertenezca a tu organización. Útil para due diligence antes de añadir un dominio nuevo.

curl -X POST \
  -H "X-API-Key: dex_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com"}' \
  https://api.dmarc-examiner.com/api/v1/check-dmarc

Devuelve el registro DMARC existente (si lo hay), la política parseada y las direcciones de reporting.

Informes

Listar informes

curl -H "X-API-Key: dex_your_key_here" \
  "https://api.dmarc-examiner.com/api/v1/reports?domain_id=uuid&page=1&limit=20"

Parámetros de consulta:

Parámetro Tipo Descripción
domain_id string Filtrar por UUID de dominio
date_from integer Timestamp Unix: filtra informes desde esta fecha
date_to integer Timestamp Unix: filtra informes hasta esta fecha
page integer Número de página (por defecto: 1)
limit integer Resultados por página (por defecto: 20, máx.: 100)

Obtener un informe

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/reports/{report_id}

Devuelve el informe con todos sus registros individuales, incluidos los datos de geolocalización.

Obtener las estadísticas de un informe

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/reports/{report_id}/statistics

Devuelve estadísticas agregadas por país, ASN y resultado de autenticación.

Exportar un informe a CSV

curl -H "X-API-Key: dex_your_key_here" \
  -o report.csv \
  https://api.dmarc-examiner.com/api/v1/reports/{report_id}/export/csv

Alertas

Listar alertas

curl -H "X-API-Key: dex_your_key_here" \
  "https://api.dmarc-examiner.com/api/v1/alerts?severity=critical&status=pending"

Parámetros de consulta:

Parámetro Tipo Descripción
severity string Filtrar por severidad: info, warning, critical
status string Filtrar por estado: pending, sent, dismissed
page integer Número de página (por defecto: 1)
limit integer Resultados por página (por defecto: 20, máx.: 100)

Descartar una alerta

curl -X PUT \
  -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/alerts/{alert_id}/dismiss

Reportes forenses (plan Pro o superior)

Los informes forenses (DMARC RUF) contienen el detalle del mensaje fallido — IP del remitente, MAIL FROM original, resultados de autenticación por comprobación. Estos endpoints devuelven 403 Forbidden si el plan actual no incluye reportes forenses.

Listar informes forenses

curl -H "X-API-Key: dex_your_key_here" \
  "https://api.dmarc-examiner.com/api/v1/forensic-reports?domain_id=uuid&page=1&limit=20"

Parámetros: domain_id, date_from, date_to, source_ip, auth_failure (dmarc / spf / dkim), page, limit.

Obtener un reporte forense

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/forensic-reports/{forensic_report_id}

Devuelve el registro completo incluyendo resultados de autenticación parseados, geolocalización de la IP origen y las cabeceras originales (cuando estén disponibles).

Resumen (últimos 7 días)

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/forensic-reports/summary

Estadísticas agregadas

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/forensic-reports/statistics

Webhooks (plan Pro o superior)

Los webhooks permiten suscribirse a eventos y que los enviemos por POST a tu URL. Hoy el sistema emite un único evento:

  • alert.created — se dispara cada vez que se crea una alerta en tu organización (procesamiento de informes o detección de cambios DNS).

Otros tipos (report.received, domain.verified) NO se emiten actualmente.

Estos endpoints devuelven 403 Forbidden si el plan no incluye alertas avanzadas. Las entregas fallidas se reintentan dos veces (30 s, 120 s) y el webhook se auto-deshabilita tras 10 fallos consecutivos.

Listar webhooks

curl -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/webhooks

Cada webhook se crea con un secret que guardas en tu lado. Cada entrega va firmada con HMAC-SHA256 — el secret nunca viaja en la red.

Cómo se firma cada entrega

Cada POST a tu URL incluye:

Header Valor
Content-Type application/json
User-Agent DMARC-Examiner-Webhooks/1.0
X-Webhook-Timestamp Segundos Unix cuando firmamos el request
X-Webhook-Signature sha256=<hex> — ver abajo

Donde:

signed_value = "{X-Webhook-Timestamp}.{raw_request_body}"
signature    = hex(HMAC-SHA256(secret, signed_value))
header       = "sha256=" + signature

Cómo verificar

  1. Rechaza requests donde |now - X-Webhook-Timestamp| > 5 minutos.
  2. Recalcula la firma esperada con tu secret guardado y el body crudo.
  3. Compara con igualdad en tiempo constante (nunca ==).
  4. Solo entonces parsea el body.

Node.js

import crypto from 'node:crypto'

function verify(req, secret) {
  const timestamp = req.headers['x-webhook-timestamp']
  const sigHeader = req.headers['x-webhook-signature']
  const rawBody = req.rawBody // string de bytes, NO JSON parseado

  if (!timestamp || !sigHeader?.startsWith('sha256=')) return false
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')

  const got = sigHeader.slice('sha256='.length)
  return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(got, 'hex'))
}

Python

import hmac, hashlib, time

def verify(headers, raw_body: bytes, secret: str) -> bool:
    ts = headers.get('X-Webhook-Timestamp')
    sig = headers.get('X-Webhook-Signature', '')
    if not ts or not sig.startswith('sha256='):
        return False
    if abs(time.time() - int(ts)) > 300:
        return False
    signed = f"{ts}.{raw_body.decode()}".encode()
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig[len('sha256='):])

PHP

function verify(array $headers, string $rawBody, string $secret): bool {
    $ts = $headers['X-Webhook-Timestamp'] ?? null;
    $sig = $headers['X-Webhook-Signature'] ?? '';
    if (!$ts || !str_starts_with($sig, 'sha256=')) return false;
    if (abs(time() - (int) $ts) > 300) return false;
    $expected = hash_hmac('sha256', $ts . '.' . $rawBody, $secret);
    return hash_equals($expected, substr($sig, strlen('sha256=')));
}

Errores comunes

  • Los frameworks parsean el JSON antes de tu handler, pero la firma es sobre los bytes crudos. Captura el body crudo antes del parseo (Express: bodyParser.raw(), Symfony: $request->getContent(), Flask: request.get_data()).
  • Usar == en lugar de comparación de tiempo constante es una vulnerabilidad timing-attack.
  • Saltarse la ventana de timestamp es una vulnerabilidad replay-attack.

Crear un webhook

curl -X POST \
  -H "X-API-Key: dex_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/dmarc-events","name":"Producción"}' \
  https://api.dmarc-examiner.com/api/v1/webhooks

La URL debe ser HTTPS. Cada organización tiene un máximo de webhooks activos.

Actualizar un webhook

curl -X PUT \
  -H "X-API-Key: dex_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"is_active":false}' \
  https://api.dmarc-examiner.com/api/v1/webhooks/{webhook_id}

Acepta cualquier combinación de url, name, is_active.

Eliminar un webhook

curl -X DELETE \
  -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/webhooks/{webhook_id}

Enviar evento de prueba

curl -X POST \
  -H "X-API-Key: dex_your_key_here" \
  https://api.dmarc-examiner.com/api/v1/webhooks/{webhook_id}/test

Devuelve el resultado de la entrega (HTTP status, tiempo de respuesta, error si lo hay).

Límites de uso

Las peticiones a la API están limitadas a 100 peticiones por minuto por clave API. Si superas el límite, la API devuelve una respuesta 429 Too Many Requests.

Revocar una clave

Para revocar una clave API:

  1. Ve a Ajustes > Claves API
  2. Pulsa el icono de eliminar junto a la clave que quieres revocar
  3. Confirma la revocación

Las claves revocadas dejan de funcionar al instante y no se pueden recuperar. Tendrás que crear una clave nueva y actualizar tus integraciones.

Buenas prácticas de seguridad

  • No expongas nunca las claves API en código del lado del cliente ni en repositorios públicos
  • Usa variables de entorno para guardar las claves en tus aplicaciones
  • Crea claves distintas para cada integración, así puedes revocarlas por separado
  • Rota las claves de forma periódica: crea una clave nueva, actualiza tu integración y revoca la antigua

Artículos relacionados