Referencia de la API
Accede programáticamente a la inteligencia de phishing de phishunt. Gratis, abierto, sin autenticación requerida.
¿Construyendo un agente de IA? Ver Para agentes IA para el servidor MCP y los wrappers de Agent Skills.
Introducción
El pipeline de detección identifica sitios de phishing sospechosos activos en tiempo real, monitorizando múltiples fuentes de threat intelligence y logs de Certificate Transparency. Los datos se enriquecen con geolocalización IP, información del certificado TLS y veredictos de detección.
Fuentes de detección:
- Certificate Transparency - monitorización en tiempo real de certificados TLS recién emitidos
- Google Safe Browsing - consulta batch contra las listas de amenazas de Google
- OpenPhish - feed de phishing de la comunidad
- PhishTank - URLs de phishing verificadas
- TweetFeed - IOCs compartidos en redes sociales
- urlscan.io - veredictos de escaneo de URL en vivo
Programación del pipeline
| Proceso | Frecuencia | Descripción |
|---|---|---|
| Detection pipeline | Every hour | Scans Certificate Transparency logs and checks threat intel sources for new suspicious phishing domains |
| Active site re-check | Every 6 hours | Re-visits active sites, captures fresh screenshots, and updates detection verdicts |
| New registration scan | Daily (00:30 UTC) | Scans newly registered domains for suspicious keyword patterns |
| Data enrichment | On detection | IP geolocation, ASN, TLS certificate, and hosting organization via ipinfo.io |
Autenticación
No se requiere autenticación. Todos los endpoints son abiertos y gratuitos. Solo envía la petición: sin API keys, sin tokens, sin registro.
Límites de tasa
Los endpoints de /api/ admiten hasta 20 peticiones cada 10 segundos por IP. Si una IP supera ese límite, puede recibir una respuesta 429 y queda bloqueada 10 segundos. Los feeds se cachean 15 minutos, así que no hace falta pedirlos más a menudo.
URL base
https://phishunt.io
Obtener dominios
Devuelve los dominios de phishing sospechosos activos enriquecidos con geolocalización IP, certificado TLS y veredictos de detección de varias fuentes.
Población: detecciones activas menos dominios aparcados (confianza alta) y clones por intención en el hostname; los kits alojados en PaaS (pages.dev, vercel.app, github.io...) se incluyen.
En la salida JSON, cada fila lleva un campo service_range: null, o el rango de IP oficial de un proveedor que contiene ip (por ejemplo un rango de AWS o Google Cloud). Describe la red de la IP, no el indicador, y no es un veredicto. Las filas de /api/v1/search.json y los resultados de /api/v1/domains/{uuid}/related también lo llevan. Los ficheros de feed, la salida CSV, las listas de bloqueo y el bundle STIX no.
Query parameters
| Parámetro | Tipo | Descripción |
|---|---|---|
limit |
integer | Number of results to return. Default 100, max 1000. |
offset |
integer | Number of results to skip for pagination. Default 0, max 10000. |
format |
string | Response format: json, csv, or txt. Default json. |
company |
string | Filter by targeted brand (e.g. amazon, paypal). See targeted brands. |
since |
ISO 8601 | Only entries after this date (e.g. 2026-03-01). |
contains |
string | Coincidencia de subcadena sin distinguir mayúsculas sobre la URL almacenada (host y ruta). 3-80 caracteres, solo letras/dígitos/-._. search y q se aceptan como alias (compatibilidad; contains gana si se envían varios). |
tier |
string | Filtro de vida: all o verified (captura usable o veredicto positivo de urlscan.io). Por defecto all. |
asn |
string | Coincidencia exacta sobre asn. Dígitos, prefijo AS aceptado (p. ej. 15169 o AS15169). |
org |
string | Coincidencia exacta sobre org, valor tal como lo devuelve este endpoint. |
registrar |
string | Coincidencia exacta sobre registrar, valor tal como lo devuelve este endpoint. |
cert |
string | Coincidencia exacta sobre cert (emisor del certificado), valor tal como lo devuelve este endpoint. |
country |
string | Coincidencia exacta sobre country (p. ej. Germany), valor tal como lo devuelve este endpoint. |
ip |
string | Coincidencia exacta sobre ip, cadena IPv4 tal como la devuelve este endpoint. |
Example request
# Get the latest 50 suspicious phishing domains curl "https://phishunt.io/api/v1/domains?limit=50" # Filter by targeted brand curl "https://phishunt.io/api/v1/domains?company=amazon" # Get entries since a date in CSV format curl "https://phishunt.io/api/v1/domains?since=2026-03-01&format=csv" # Paginate: get results 101-200 curl "https://phishunt.io/api/v1/domains?offset=100&limit=100"
Example response
{
"count": 2,
"total": 2,
"offset": 0,
"limit": 100,
"results": [
{
"url": "https://amazon.example-phish.com/signin",
"domain": "amazon.example-phish.com",
"company": "amazon",
"date": "2026-03-27T14:30:00+00:00",
"first_seen": "2026-03-25T09:12:00+00:00",
"uuid": "54889cb5-146d-484f-8b94-7a0b7385bff7",
"ip": "198.51.100.42",
"country": "United States",
"asn": "64496",
"org": "Example Hosting Inc.",
"cert": "Let's Encrypt R3",
"malicious_google": false,
"malicious_openphish": true,
"malicious_phishtank": false,
"malicious_tweetfeed": false,
"malicious_urlscan": true
}
]
}
Feeds
Descarga el feed completo de phishing sospechoso activo. Actualizado cada hora. Dataset completo sin filtrado - usa el endpoint de dominios para parámetros de consulta.
Analizar una URL
Análisis pasivo de cualquier URL: la contrasta con las detecciones ya almacenadas por phishunt (feed activo, detecciones previas, feed de nuevos registros) y aplica heurísticas en vivo sobre la forma de la URL (coincidencia de marca, distancia typosquat/homógrafo, abuso de TLD, hosting PaaS, intención de clon). La URL de destino nunca se contacta. Los dominios desconocidos que resulten sospechosos se encolan para un análisis completo del pipeline.
Query parameters
| Parámetro | Tipo | Descripción |
|---|---|---|
url |
string | La URL a analizar. Obligatorio. Solo http/https, máx. 2048 caracteres. |
Example request
curl "https://phishunt.io/api/v1/analyze?url=https://amazon-secure-login.example.com/signin"
Example response
{
"query": { "url": "...", "host": "...", "normalized_host": "...", "apex": "..." },
"known": {
"in_active_feed": false,
"previously_active": false,
"in_new_registration_feed": false,
"record": null
},
"live_analysis": {
"allowlisted": false,
"brand_match": "amazon",
"kw_score": 85,
"impersonation": false,
"url_signals": { "kw_score_norm": 0.85, "idn_homograph": 0.0, "tld_abuse": 0.3, "clone_intent": 0.0, "paas_host": 0.0, "leet_brand": 0.0 },
"path_signals": { "brand_off_host": 0.0, "suspicious_path": 1.0, "exec_page": 0.0 },
"url_risk_score": 72,
"url_risk": "high",
"why": [
{ "signal": "kw_score_norm", "value": 0.85, "weight": 0.26, "points": 22.1, "kind": "weighted" },
{ "signal": "suspicious_path", "value": 1.0, "weight": 0.0, "points": 12.0, "kind": "path_boost" }
]
},
"history": { "apex_prior_detections": 0, "apex_candidates_seen": 0, "scope": "apex", "brands_targeted": [] },
"action": { "queued_for_analysis": false, "reason": "reserved_domain" },
"external_feeds": { "openphish": false, "phishtank": false, "tweetfeed": false, "listed": false, "listed_scope": null, "note": null, "status": "ok", "feeds_ok": true },
"verdict": "likely_phishing",
"verdict_confidence": "medium",
"verdict_basis": ["the URL shape scores 72/100"],
"probability": {
"status": "ok",
"p_malicious": 0.127,
"percent": 13,
"interval_80": [0.079, 0.198],
"band": "unlikely",
"relative_risk": 9.5,
"coverage": "passive_url_only",
"prior": 0.01342,
"evidence": [
{ "class": "url_shape", "value": 72, "llr": 2.74, "direction": "toward_malicious" },
{ "class": "external_feed", "value": "none", "llr": -0.39, "direction": "toward_benign" },
{ "class": "trusted_zone", "value": "untrusted", "llr": 0.03, "direction": "neutral" }
],
"not_evaluated": [],
"model_version": "2026-09-28.2",
"note": "At this API's ~1.3% base rate ... URL-only estimate; the page was not fetched. ..."
},
"meta": { "analyzed_at": "...", "passive_only": true, "note": "...", "docs": "https://phishunt.io/api/", "license": "CC0-1.0" }
}
verdict es la respuesta única y adjudicada: léela primero. verdict_confidence y verdict_basis te dicen cuánto fiarte y por qué. live_analysis.url_risk es una heurística sobre la forma de la URL, en su propia escala, no un veredicto. action.reason explica por qué la URL se encoló o no (por ejemplo brand_match_unknown_domain si se encoló, reserved_domain para example.com, ip_literal para una IP). external_feeds busca el apex en OpenPhish/PhishTank/TweetFeed (caché local, el destino nunca se contacta). listed_scope te dice si el host analizado está listado él mismo (host) o solo otro host del mismo apex (apex). status/feeds_ok indican la frescura de esa caché. history.apex_prior_detections cuenta las filas almacenadas con veredicto medium, high o critical. apex_candidates_seen cuenta todas las filas almacenadas. scope vale host cuando el apex es hosting compartido o una plataforma de confianza: entonces el historial cubre solo el host exacto. live_analysis.why enumera los 5 principales factores del score y es coherente con url_risk_score. Referencia completa de campos en el spec OpenAPI (esquema AnalyzeResponse).
query.host lo devuelve en su forma xn--. Un host que no puede existir en DNS (más de 253 caracteres, una etiqueta de más de 63, una etiqueta vacía, IDNA inválido) devuelve 400. Registramos cada consulta para recalibrar el modelo de probabilidad: host, path (sin query string, sin fragmento, sin credenciales), scores, veredicto y probabilidad. Guardamos ese registro 90 días.
Probabilidad
El bloque probability va junto a verdict. No lo sustituye. p_malicious es una estimación calibrada de que el host sea malicioso, para una URL típica enviada a esta API. Alrededor del 1,3 % de esas URLs son maliciosas (prior), así que la mayoría de los hosts se quedan cerca de ese número hasta que la evidencia los mueve.
| Campo | Significado |
|---|---|
p_malicious, percent | Probabilidad de que el host sea malicioso, de 0 a 1 (3 decimales), y como porcentaje entero. |
interval_80 | Rango del 80 % para p_malicious. Refleja el error de la estimación. |
band | very_unlikely (menos del 5 %), unlikely (5-30 %), uncertain (30-70 %), likely (70-95 %), very_likely (más del 95 %). |
relative_risk | p_malicious dividido entre prior. Un 9,5 significa 9,5 veces la tasa base. |
coverage | En qué se basa la estimación: passive_url_only, known_record, active_no_render o active_rendered. |
evidence, not_evaluated | Cada clase que movió la estimación, con su llr (log-cociente de verosimilitud: positivo = hacia malicioso), y cada clase que no pudimos comprobar. |
no_evidence. Las estimaciones pasivas se quedan bajas por diseño: no descargamos la página, y el phishing sin marca en la URL es invisible para el análisis de URL. Para tener más evidencia usa el análisis profundo (GET /api/v1/analyze/deep o la herramienta MCP analyze_url_deep). Descarga la página y, si el carril de render está libre, la renderiza en un navegador: entonces la respuesta trae coverage active_rendered o active_no_render. Tarda entre 15 y 45 segundos (50 como máximo). El endpoint REST necesita token y el presupuesto es de 50 análisis al día. Mira el spec OpenAPI.
Campos de la respuesta
Cada objeto del array results (o las entradas del feed) contiene estos campos.
These five flags are positive assertions only. false means the source did not flag the URL when we checked, or was never asked (timeout or quota); it is not a clean verdict.
| Campo | Tipo | Descripción |
|---|---|---|
url | string | Full URL of the suspicious site |
domain | string | Domain name including subdomains |
company | string | Targeted brand slug (e.g. amazon, paypal) |
date | datetime | Last check timestamp (ISO 8601) |
first_seen | datetime | When the site was first detected (ISO 8601) |
uuid | string | Unique identifier for this entry (UUID v4) |
ip | string | Resolved IPv4 address |
country | string | Hosting country name |
asn | string | Autonomous System Number (e.g. 13335) |
org | string | Hosting organization |
cert | string | TLS certificate issuer |
malicious_google | boolean | true if flagged by Google Safe Browsing |
malicious_openphish | boolean | true if present in OpenPhish feed |
malicious_phishtank | boolean | true if present in PhishTank |
malicious_tweetfeed | boolean | true if present in TweetFeed |
malicious_urlscan | boolean | true if flagged by urlscan.io |
Paginación
Usa offset y limit para paginar resultados. La respuesta incluye ambos valores para que puedas calcular la siguiente página.
# Page 1 curl "https://phishunt.io/api/v1/domains?limit=100&offset=0" # Page 2 curl "https://phishunt.io/api/v1/domains?limit=100&offset=100" # Page 3 curl "https://phishunt.io/api/v1/domains?limit=100&offset=200"
Cuando count es menor que limit, has llegado a la última página.
total (distinto de count) es el número de filas que cumplen company/since/contains/tier/los filtros pivote antes de aplicar limit/offset - recorre todo el resultado incrementando offset hasta que offset + count >= total.
Códigos de estado
| Código | Descripción |
|---|---|
| 200 | Success. Response body contains the requested data. |
| 400 | Bad request. Invalid parameter value (e.g. malformed since date). |
| 429 | Rate limited. Back off and retry. |
| 403 | Los feeds, las blocklists y /api/v1/* se saltan el Browser Integrity Check de Cloudflare, así que ahí funciona cualquier User-Agent. Las páginas HTML siguen rechazando un User-Agent Python-urllib o libwww-perl a pelo: pon un User-Agent descriptivo de todos modos. |
Notas
Access-Control-Allow-Origin: *, so you can call the API from browser applications.