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
- Ve a Ajustes > Claves API
- Pulsa Crear clave API
- Introduce un nombre descriptivo para la clave (p. ej. "Dashboard de monitorización", "Pipeline de CI")
- 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_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6El 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/domainsEndpoints disponibles
Dominios
Listar dominios
curl -H "X-API-Key: dex_your_key_here" \
https://api.dmarc-examiner.com/api/v1/domainsRespuesta:
{
"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/domainsDevuelve 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}/verifyDevuelve 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-dmarcDevuelve 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}/statisticsDevuelve 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/csvAlertas
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}/dismissReportes 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/summaryEstadísticas agregadas
curl -H "X-API-Key: dex_your_key_here" \
https://api.dmarc-examiner.com/api/v1/forensic-reports/statisticsWebhooks (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/webhooksCada 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=" + signatureCómo verificar
- Rechaza requests donde
|now - X-Webhook-Timestamp| > 5 minutos. - Recalcula la firma esperada con tu secret guardado y el body crudo.
- Compara con igualdad en tiempo constante (nunca
==). - 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/webhooksLa 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}/testDevuelve 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:
- Ve a Ajustes > Claves API
- Pulsa el icono de eliminar junto a la clave que quieres revocar
- 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