Esta API permite integrar o reporte de phishing da Whalemate em seus próprios sistemas, como:
Botões personalizados em clientes de email
Integrações com SIEM corporativo
Ferramentas internas de segurança
Fluxos de trabalho automatizados
Registro de reportes de campanhas de simulação em suas análises da Whalemate
Todos os endpoints desta API residem sob o host {{base_url}}. Nos exemplos deste documento, substitua {{base_url}} pelo host que a Whalemate indicar.
Para obter o host de produção (
base_url), entre em contato com seu representante da Whalemate ou escreva para nós através do chat de suporte.
Acesse sua conta da Whalemate
Vá em Configurações → Integrações → API Keys
Clique em Gerar nova API Key
Copie a key (só é exibida uma vez)
Inclua a API Key em cada request por meio do header:
X-API-KEY: tu_api_key_de_60_caracteres_aqui⚠️ Importante:
Não compartilhe sua API Key publicamente
Rotacione a key periodicamente pela UI
Se a key for comprometida, revogue-a imediatamente
Criar reporte de phishing
POST {{base_url}}/api/external/reported-emails| Header | Valor | Obrigatório |
|---|---|---|
X-API-KEY |
Sua API Key | ✅ Sim |
Content-Type |
application/json |
✅ Sim |
Accept |
application/json |
✅ Sim |
| Campo | Tipo | Descrição |
|---|---|---|
reported_by |
string (email) | Email do usuário que reporta o phishing |
email_from |
string (email) | Email do remetente suspeito |
subject |
string (max 500) | Assunto do email reportado |
send_date |
string (ISO 8601) | Data de envio do email suspeito |
| Campo | Tipo | Descrição |
|---|---|---|
from |
string | Nome do remetente. Se não for enviado, usa-se email_from |
message_preview |
string | Primeiros ~200 caracteres da mensagem |
raw_message |
string | Mensagem completa em formato RFC822 ou HTML |
headers |
array | Headers do email (ver estrutura abaixo) |
links |
array | URLs encontradas no email |
attachments |
array | Metadata de anexos (ver estrutura abaixo) |
campaign_id |
integer | ID da campanha de simulação. Se for incluído, registra o evento reported nessa campanha em vez de criar um incidente no SIEM. (Solicitar campanha à equipe de suporte) |
Estrutura de headers
[{
"name": "Return-Path",
"value": "<[email protected]>"},{
"name": "Received",
"value": "from mail.example.com by mx.google.com..."}]Estrutura de attachments
[{
"name": "invoice.pdf",
"contentType": "application/pdf",
"size": 12345}]Nota: Não é enviado o conteúdo do anexo, apenas 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}Limite: 100 requests por minuto por API Key
Reinício: A cada minuto
Header de resposta: X-RateLimit-Remaining indica requests restantes
Se você exceder o limite, receberá erro 429. Aguarde o tempo indicado em retry_after (segundos).
Em todos os exemplos, substitua
{{base_url}}pelo host que a Whalemate indicar (ver URL Base).
curl -X POST {{base_url}}/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('{{base_url}}/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 = '{{base_url}}/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 = '{{base_url}}/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']]
);O que acontece se o usuário reportante não existir na Whalemate?
O endpoint retornará erro 422. O usuário deve estar previamente registrado em sua organização dentro da Whalemate.
Posso enviar o conteúdo completo dos anexos?
Atualmente só é aceita metadata (nome, tipo, tamanho). O conteúdo completo não pode ser enviado por razões de segurança e tamanho do payload.
Como sei se meu reporte foi processado corretamente?
A resposta 201 com o id do reporte confirma que foi processado. Além disso, você pode:
Verificar na UI da Whalemate (seção Email SIEM)
Os analistas de sua organização receberão notificação por email
Os reportes externos são processados da mesma forma que os de add-ins nativos?
Sim, os reportes a partir da API têm o mesmo fluxo:
Status inicial: received
Categoria inicial: unknown
Notificações para emails configurados
Analistas podem classificá-los normalmente
Aparecem em analytics
A única diferença é o campo source que marca a origem (external_api).
Posso usar a mesma API Key para múltiplos sistemas?
Sim, mas recomendamos gerar uma key diferente por sistema para:
Melhor rastreabilidade
Revogação granular em caso de comprometimento
Métricas separadas por origem
A API Key expira?
Não, as API Keys não expiram automaticamente. No entanto, recomendamos rotacioná-las a cada 90 dias como boa prática de segurança.
Que formato de data devo usar para send_date?
Use o formato ISO 8601 (RFC 3339). Exemplos válidos:
2026-01-19T10:30:00Z (UTC)
2026-01-19T10:30:00-05:00 (