Esta API permite integrar el reporte de phishing de Whalemate en sus propios sistemas, como:
Botones personalizados en clientes de email
Integraciones con SIEM corporativo
Herramientas internas de seguridad
Workflows automatizados
Accede a tu cuenta de Whalemate
Ve a Configuración → Integraciones → API Keys
Clic en Generar nueva API Key
Copia la key (solo se muestra una vez)
Incluye la API Key en cada request mediante el header:
X-API-KEY: tu_api_key_de_60_caracteres_aqui⚠️ Importante:
No compartas tu API Key públicamente
Rota la key periódicamente desde la UI
Si la key se compromete, revócala inmediatamente
Crear reporte de phishing
POST /api/external/reported-emailsHeader | Valor | Obligatorio |
|---|---|---|
| Tu API Key | ✅ Sí |
|
| ✅ Sí |
|
| ✅ Sí |
Campo | Tipo | Descripción |
|---|---|---|
| string (email) | Email del usuario que reporta el phishing |
| string (email) | Email del remitente sospechoso |
| string (max 500) | Asunto del email reportado |
| string (ISO 8601) | Fecha de envío del email sospechoso |
Campo | Tipo | Descripción |
|---|---|---|
| string | Nombre del remitente. Si no se envía, se usa |
| string | Primeros ~200 caracteres del mensaje |
| string | Mensaje completo en formato RFC822 o HTML |
| array | Headers del email (ver estructura abajo) |
| array | URLs encontradas en el email |
| array | Metadata de adjuntos (ver estructura abajo) |
Estructura de headers
[{
"name": "Return-Path",
"value": "<[email protected]>"},{
"name": "Received",
"value": "from mail.example.com by mx.google.com..."}]Estructura de attachments
[{
"name": "invoice.pdf",
"contentType": "application/pdf",
"size": 12345}]Nota: No se sube el contenido del adjunto, solo metadata.
{"reported_by": "[email protected]","email_from": "[email protected]","from": "Banco Nacional","subject": "Urgente: Confirma tu cuenta","send_date": "2026-01-19T10:30:00Z","message_preview": "Estimado cliente, detectamos actividad sospechosa...","raw_message": "Content-Type: text/html; charset=UTF-8\n\n<html>...","headers": [
{
"name": "Return-Path",
"value": "<[email protected]>"
},
{
"name": "X-Mailer",
"value": "PhishMailer 2.0"
}],"links": [
"https://suspicious-domain.com/confirm-account?token=abc123",
"https://evil-tracker.com/pixel.gif"],"attachments": [
{
"name": "documento_importante.pdf",
"contentType": "application/pdf",
"size": 45678
}]}{"success": true,"data": {
"id": 12345,
"reported_at": "2026-01-19T14:30:00Z",
"status": "received",
"category": "unknown",
"source": "external_api"},"message": "Phishing report successfully registered"}{"error": "API Key required"}{"error": "Invalid API Key"}{"success": false,"message": "The reporting user does not exist or does not belong to this company","errors": {
"reported_by": [
"The reporting user does not exist or does not belong to this company"
]}}{"message": "The given data was invalid.","errors": {
"email_from": ["The email from field is required."],
"subject": ["The subject field is required."],
"send_date": ["The send date field is required."]}}{"success": false,"message": "Internal error processing the report"}{"message": "Too Many Attempts.","retry_after": 60}Límite: 100 requests por minuto por API Key
Reinicio: Cada minuto
Header de respuesta: X-RateLimit-Remaining indica requests restantes
Si excedes el límite, recibirás error 429. Espera el tiempo indicado en retry_after (segundos).
curl -X POST https://api.whalemate.io/api/external/reported-emails \
-H "X-API-KEY: tu_api_key_aqui" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"reported_by": "[email protected]",
"email_from": "[email protected]",
"subject": "Has ganado un premio",
"send_date": "2026-01-19T10:30:00Z",
"links": ["https://phishing-site.com/click"]
}'const reportPhishing = async (emailData) => {
const response = await fetch('https://api.whalemate.io/api/external/reported-emails', {
method: 'POST',
headers: {
'X-API-KEY': 'tu_api_key_aqui',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
reported_by: emailData.userEmail,
email_from: emailData.senderEmail,
subject: emailData.subject,
send_date: emailData.date,
raw_message: emailData.fullMessage,
links: emailData.extractedLinks
})
});
const result = await response.json();
if (response.ok) {
console.log('Reporte enviado:', result.data.id);
} else {
console.error('Error:', result.message);
}
};
import requests
from datetime import datetime
def report_phishing(user_email, sender_email, subject, send_date, **kwargs):
url = 'https://api.whalemate.io/api/external/reported-emails'
headers = {
'X-API-KEY': 'tu_api_key_aqui',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
payload = {
'reported_by': user_email,
'email_from': sender_email,
'subject': subject,
'send_date': send_date.isoformat(),
**kwargs # message_preview, links, etc.
}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 201:
data = response.json()
print(f"Reporte creado: ID {data['data']['id']}")
return data['data']['id']
else:
print(f"Error: {response.json()}")
return None
# Uso
report_phishing(
user_email='[email protected]',
sender_email='[email protected]',
subject='Email sospechoso',
send_date=datetime.now(),
links=['https://phishing.com/click']
)
<?php
function reportPhishing($apiKey, $reportedBy, $emailFrom, $subject, $sendDate, $options = []) {
$url = 'https://api.whalemate.io/api/external/reported-emails';
$data = array_merge([
'reported_by' => $reportedBy,
'email_from' => $emailFrom,
'subject' => $subject,
'send_date' => $sendDate,
], $options);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-KEY: ' . $apiKey,
'Content-Type: application/json',
'Accept: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 201) {
echo "Reporte creado: ID " . $result['data']['id'] . "\n";
return $result['data']['id'];
} else {
echo "Error: " . $result['message'] . "\n";
return null;
}
}
// UsoreportPhishing(
'tu_api_key_aqui',
'[email protected]',
'[email protected]',
'Email sospechoso',
date('c'),
['links' => ['https://phishing.com/click']]
);
¿Qué pasa si el usuario reportante no existe en Whalemate?
El endpoint retornará error 422. El usuario debe estar registrado previamente en tu organización dentro de Whalemate.
¿Puedo enviar el contenido completo de adjuntos?
Actualmente solo se acepta metadata (nombre, tipo, tamaño). El contenido completo no se puede enviar por razones de seguridad y tamaño de payload.
¿Cómo sé si mi reporte fue procesado correctamente?
La respuesta 201 con el id del reporte confirma que fue procesado. Adicionalmente, puedes:
Verificar en la UI de Whalemate (sección Email SIEM)
Los analistas de tu organización recibirán notificación por email
¿Los reportes externos se procesan igual que los de add-ins nativos?
Sí, los reportes desde la API tienen el mismo flujo:
Status inicial: received
Category inicial: unknown
Notificaciones a emails configurados
Analistas pueden clasificarlos normalmente
Aparecen en analytics
La única diferencia es el campo source que marca el origen (external_api).
¿Puedo usar una misma API Key para múltiples sistemas?
Sí, pero recomendamos generar una key diferente por sistema para:
Mejor trazabilidad
Revocación granular si hay compromiso
Métricas separadas por origen
¿La API Key expira?
No, las API Keys no expiran automáticamente. Sin embargo, recomendamos rotarlas cada 90 días como buena práctica de seguridad.
¿Qué formato de fecha debo usar para send_date?
Usa formato ISO 8601 (RFC 3339). Ejemplos válidos:
2026-01-19T10:30:00Z (UTC)
2026-01-19T10:30:00-05:00 (con timezone)
2026-01-19T10:30:00.123Z (con milisegundos)
¿Hay límite en el tamaño del payload?
El límite de tamaño del request es de 2MB. Para emails muy grandes, considera enviar solo el message_preview en lugar del raw_message completo.
Nunca expongas la API Key en código cliente (JavaScript en navegador)
Usa HTTPS siempre - la API solo acepta conexiones seguras
Almacena la API Key de forma segura (variables de entorno, secret managers)
Implementa retry con backoff exponencial para errores transitorios
Monitorea el uso de la API Key para detectar uso anómalo
Implementa rate limiting del lado del cliente para no exceder los límites
Usa batch processing si necesitas enviar múltiples reportes
Cachea la validación de usuarios para evitar lookups repetidos
Procesa reportes de forma asíncrona en tu sistema
async function reportWithRetry(emailData, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await reportPhishing(emailData);
return response;
} catch (error) {
if (error.status === 422) {
// Error de validación, no reintentar
throw error;
}
if (error.status === 429) {
// Rate limit, esperar y reintentar
const retryAfter = error.headers.get('Retry-After') || 60;
await sleep(retryAfter * 1000);
continue;
}
if (attempt === maxRetries) {
throw error;
}
// Backoff exponencial para otros errores
await sleep(Math.pow(2, attempt) * 1000);
}
}
}Contamos con una colección oficial de Postman para facilitar las pruebas y la integración con la API de Reporte Externo de Phishing.
Debido a limitaciones en la distribución de archivos, la colección se entrega bajo solicitud.
Por favor, contactá al equipo de soporte de Whalemate para obtener la versión más actualizada.