API de SwarmHawk
La API de SwarmHawk te da acceso programático a 27 controles de seguridad automatizados más de 3.000+ plantillas CVE activas de nuclei — SSL, DNS, CVEs con confirmación de exploit activo, exposición de breach, typosquats, análisis de amenazas con IA y más — para cualquier dominio. Úsalo para construir flujos de trabajo de seguridad, automatizar due diligence o integrar SwarmHawk en tu propia plataforma.
Hay dos superficies de API:
/api/v2— la superficie autenticada por sesión/JWT heredada utilizada por el panel. La mayoría de lecturas y escrituras también están disponibles aquí por compatibilidad./api/v1— la moderna API pública de Business / Enterprise, asegurada con claves API de portador (swh_…). Esta es la que deben usar las nuevas integraciones.
Content-Type: application/json.Inicio Rápido — escanea un dominio en 30 segundos
# 1. Create an API key at www.swarmhawk.com → Account → API Keys (Business or Enterprise) # 2. Add and start scanning a domain: curl -X POST https://api.swarmhawk.com/api/v1/domains \ -H "Authorization: Bearer swh_your_key_here" \ -H "Content-Type: application/json" \ -d '{"domain": "example.com"}' # Poll the latest report: curl https://api.swarmhawk.com/api/v1/jobs/<job_id> \ -H "Authorization: Bearer swh_your_key_here"
import requests API_KEY = "swh_your_key_here" BASE = "https://api.swarmhawk.com/api/v1" H = {"Authorization": f"Bearer {API_KEY}"} resp = requests.post(f"{BASE}/domains", headers=H, json={"domain": "example.com"}) job_id = resp.json()["job_id"] job = requests.get(f"{BASE}/jobs/{job_id}", headers=H).json() print(f"State: {job['state']}")
const BASE = "https://api.swarmhawk.com/api/v1"; const H = { "Authorization": "Bearer swh_your_key_here", "Content-Type": "application/json" }; const add = await fetch(`${BASE}/domains`, { method: "POST", headers: H, body: JSON.stringify({ domain: "example.com" }) }).then(r => r.json()); const job = await fetch(`${BASE}/jobs/${add.job_id}`, { headers: H }).then(r => r.json()); console.log(`State: ${job.state}`);
Autenticación
SwarmHawk utiliza dos métodos de autenticación según el endpoint:
| Método | Encabezado | Utilizado para |
|---|---|---|
| Clave API (Bearer) | Authorization: Bearer swh_… | /api/v1/* API pública de Business / Enterprise |
| JWT de Sesión | Authorization: Bearer <jwt> | /api/v2/* y endpoints de panel (autenticados por usuario) |
| Ninguno | — | /public-scan, /health |
Formato de clave API
swh_3f8a2b1c4d5e6f7a8b9c0d1e2f3a4b5c
Errores y Límites de Velocidad
Códigos de estado HTTP
| Código | Significado |
|---|---|
| 200 | Éxito |
| 400 | Solicitud incorrecta — verifique el cuerpo de su solicitud |
| 401 | Clave API o token de sesión faltante o inválido |
| 403 | Prohibido — esta función requiere un plan de pago |
| 429 | Límite de velocidad excedido |
| 500 | Error del servidor — reintentar después de 30 segundos |
Estructura de respuesta de error
{
"detail": "Invalid API key"
}Límites de velocidad
| Plan | Límite |
|---|---|
| Free | Claves API no disponibles; use el panel de control o /public-scan |
| Business | Cuota predeterminada por cuenta con recarga de cartera para créditos puntuales |
| Enterprise | Límites personalizados negociados según contrato |
| /public-scan | Sin clave requerida · limitado por IP |
Escanear un dominio
No existe un único endpoint de "escaneo único". Para escanear un dominio a través de la API:
- Añade (y verifica) el dominio con
POST /api/v1/domains— el primer escaneo se pone en cola automáticamente. - Para volver a escanear un dominio ya agregado, llama a
POST /api/v1/domains/{domain_id}/scan. - Consulte
GET /api/v1/jobs/{job_id}para el estado yGET /api/v2/domains/{domain_id}/reportpara los últimos resultados. - Para escaneos anónimos puntuales sin cuenta, utiliza
POST /public-scan(limitado por velocidad, resultados no almacenados).
POST /public-scan
Escaneo anónimo — no requiere clave API. Devuelve un subconjunto de verificaciones con algunos resultados bloqueados. Úsalo para demostraciones o integraciones. Los resultados no se guardan.
| Campo | Tipo | Descripción |
|---|---|---|
| domain | string | Dominio a escanear |
{
"domain": "example.com",
"risk_score": 42,
"critical": 1,
"warnings": 3,
"locked_count": 8,
"checks": [/* 7 free checks visible, 8 locked */],
"scanned_at": "2025-03-10T09:15:00Z"
}GET /scan/passive
Escaneo de huella digital rápido — detecta la pila de software y verifica CVEs conocidos sin un escaneo completo. Respuesta en ~3 segundos. Sin resultados guardados.
{
"domain": "example.com",
"software": [
{"product": "nginx", "version": "1.18.0"},
{"product": "WordPress", "version": "6.3.1"}
],
"cve_hits": [
{
"product": "WordPress 6.3.1",
"top_cve": "CVE-2023-39320",
"top_cvss": 9.8,
"cve_count": 3
}
],
"max_cvss": 9.8,
"priority": "CRITICAL"
}prioridad: CRÍTICA (cvss ≥ 9) · ALTA (≥ 7) · MEDIA (≥ 4) · BAJA. Si la flota de escáneres ascendente no está disponible, el endpoint devuelve una estructura de resultado vacío en lugar de retornar errores 5xx.
GET /api/v2/dominios
Enumera todos los dominios en tu cuenta con sus puntuaciones de riesgo más recientes y verificaciones.
{
"domains": [
{
"id": "uuid",
"domain": "example.com",
"country": "DE",
"status": "active",
"paid": true,
"risk_score": 42,
"scanned_at": "2025-03-10T09:15:00Z",
"checks": [/* latest check array */],
"scan_history": [{"date":"…","risk":42}]
}
]
}POST /api/v2/dominios
Añade un dominio a tu cuenta y pon en cola un escaneo en segundo plano.
| Campo | Tipo | Descripción |
|---|---|---|
| domain | string | Dominio a agregar, p. ej. "mycompany.cz" |
| country | string | Código de país ISO (opcional — detectado automáticamente desde TLD) |
{
"id": "uuid",
"domain": "mycompany.cz",
"status": "scanning",
"message": "Domain added — scan starting now"
}GET /api/v2/domains/{domain_id}/informe
Obtén el último reporte de scan completo para un dominio. Los usuarios gratuitos ven un subconjunto; los usuarios de pago ven los 27 controles incluyendo validación de CVE activo nuclei y resumen con IA.
{
"domain": "example.com",
"risk_score": 42,
"scanned_at": "2025-03-10T09:15:00Z",
"paid": true,
"critical": 1,
"warnings": 3,
"informational": 2,
"locked_count": 0,
"verified_at": "2026-04-08T10:00:00Z",
"checks": [
{
"check": "ssrf",
"status": "info",
"confidence": "informational",
"title": "A10: 3 SSRF surface indicator(s)",
"detail": "Surface area detected (not confirmed vulnerabilities)…",
"score_impact": 0
}
]
}Cada objeto de verificación ahora incluye un campo confidence: "confirmed" (puntuado) o "informational" (sin penalización, solo indicador de superficie). Los hallazgos informativos nunca se cuentan en warnings ni critical.
GET /domains/{domain_id}/verify-token
Devuelve el desafío de propiedad activo emitido por el orquestador de verificación. SwarmHawk admite dos métodos de verificación — registro TXT de DNS o carga de archivo HTTP. Llama a POST /domains/{domain_id}/verify con method: "dns" o "http" una vez que el registro/archivo se haya publicado.
{
"domain": "example.com",
"verified_at": null,
"orchestrator_state": "pending",
"method": {
"name": "DNS TXT record",
"record_name": "_swarmhawk-verify.example.com",
"record_value": "swarmhawk-verify=a3f7b2c1…",
"hint": "Add a TXT record named _swarmhawk-verify.example.com with the value above. Click 'Check DNS' once propagated."
},
"methods": [
{
"type": "dns",
"name": "DNS TXT record",
"record_name": "_swarmhawk-verify.example.com",
"record_value": "swarmhawk-verify=a3f7b2c1…",
"hint": "Add a TXT record …"
},
{
"type": "http",
"name": "File upload",
"path": "/.well-known/swarmhawk-verify.txt",
"url": "https://example.com/.well-known/swarmhawk-verify.txt",
"body": "swarmhawk-verify=a3f7b2c1…",
"hint": "Upload a file at the URL containing the body above. Click 'Check File' once it returns 200."
}
]
}La entrada del método HTTP solo está presente cuando el orquestador ha emitido un desafío http_path. Si el orquestador es inaccesible, el endpoint devuelve 503 no_verification_orchestrator.
POST /dominios/{domain_id}/verificar
Solicite al orquestador que confirme la propiedad mediante el método seleccionado. Si tiene éxito, domains.verified_at se escribe y se devuelve en respuestas de reportes posteriores. El orquestador almacena en caché las verificaciones positivas durante 7 días.
Cuerpo de la solicitud (opcional, por defecto dns):
{ "method": "dns" } // or "http"Respuesta exitosa:
{ "verified": true, "method": "dns" }Respuesta aún no encontrada:
{ "verified": false, "state": "pending", "method": "dns", "detail": "DNS-TXT record not found yet" }GET /api/v2/dominios/{domain_id}/historial
Tendencia de puntuación de riesgo a lo largo del tiempo — útil para construir dashboards o alertar sobre aumentos de puntuación.
{
"domain": "example.com",
"scans": [
{"risk_score":42,"critical":1,"warnings":3,"scanned_at":"2025-03-10T09:15:00Z"},
{"risk_score":38,"critical":0,"warnings":4,"scanned_at":"2025-02-10T08:00:00Z"}
]
}GET /api/v2/domains/{domain_id}/nis2
Mapea los hallazgos del escaneo a los artículos de la Directiva NIS2. Devuelve una puntuación de cumplimiento y estado por artículo — adecuado como evidencia de auditoría para reguladores.
{
"domain": "example.com",
"risk_score": 42,
"nis2_score": 71,
"articles": [
{
"article": "Art.21(2)(i)",
"requirement": "Secure communications",
"status": "met"
},
{
"article": "Art.21(2)(h)",
"requirement": "Supply chain security",
"status": "warning"
}
]
}POST /intel
Genera un informe de amenazas impulsado por IA para tu cartera de dominios usando Claude. Devuelve un informe estructurado con resumen ejecutivo, hallazgos críticos y prioridades de remediación.
| Campo | Tipo | Descripción |
|---|---|---|
| domains | string | Separados por comas: "example.com (riesgo:42), other.cz (riesgo:18)" |
| date | string | Fecha de hoy, p. ej. "10 de marzo de 2025" |
{
"text": "## Executive Summary\n\nYour domain portfolio shows...",
"briefing": "…"
}POST /api/v2/keys
Crea una nueva clave API para tu cuenta. Devuelve todas las claves incluyendo la nueva.
{
"keys": [
{
"key": "swh_3f8a2b1c4d5e6f7a8b9c0d1e2f3a4b5c",
"calls_this_month": 0,
"limit_per_month": 10,
"active": true,
"created_at": "2025-03-10T09:00:00Z"
}
]
}GET /api/v2/keys
Lista todas las claves API y su uso durante el mes actual.
curl https://api.swarmhawk.com/api/v2/keys \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"DELETE /api/v2/keys/{key}
Revoke una clave API inmediatamente. Todas las solicitudes futuras con esta clave serán rechazadas.
{ "revoked": "swh_3f8a2b1c…" }API Business / Enterprise — /api/v1
La superficie /api/v1/* es la API de escritura de producción utilizada por clientes Business y Enterprise. Cada endpoint acepta X-API-Key: swh_… (recomendado para servidor a servidor) o Authorization: Bearer <jwt> (para herramientas propias).
Control de niveles
- Gratuito — Acceso a API denegado (
403 API_ACCESS_REQUIRED). - Pro — Prueba de solo lectura con 10 llamadas. Los endpoints de escritura devuelven
403 business_required. - Empresa — 500 llamadas/mes, débito de cartera/derechos por escaneo/pentest/brecha.
- Enterprise — llamadas ilimitadas; inscripción de administrador con límite de
max_dominiospor cliente y medición por llamada (detalles).
Flujo típico de distribuidor
# 1. Add a domain (returns the DNS challenge inline) curl -X POST https://api.swarmhawk.com/api/v1/domains \ -H "X-API-Key: swh_…" -H "Content-Type: application/json" \ -d '{"domain":"acme.com"}' # {"id":"…","domain":"acme.com","verification":{"state":"pending","dns_record_name":"_swarmhawk.acme.com","dns_record_value":"swh-verify=…"}} # 2. Tenant adds the DNS TXT record, then verify curl -X POST https://api.swarmhawk.com/api/v1/domains/{id}/verify \ -H "X-API-Key: swh_…" # {"verified":true,"state":"verified","method":"dns"} # 3. Kick off a scan / pentest / breach lookup (returns job_id) curl -X POST https://api.swarmhawk.com/api/v1/domains/{id}/scan -H "X-API-Key: swh_…" # {"job_id":"…","status":"queued","domain":"acme.com","swarmhawk_job_id":"…"} # 4. Poll the orchestrator-side job and pull results when status=done curl https://api.swarmhawk.com/api/v1/jobs/{job_id} -H "X-API-Key: swh_…" curl https://api.swarmhawk.com/api/v1/jobs/{job_id}/findings -H "X-API-Key: swh_…" curl https://api.swarmhawk.com/api/v1/jobs/{job_id}/report -H "X-API-Key: swh_…"
POST /api/v1/keys
Emita una clave API para el usuario actual. Business: una clave, 500 llamadas/mes. Enterprise: una clave, ilimitadas (gestionadas por admin vía /admin/api/v1/enterprise/*). Solo JWT Bearer — no puede usar su primera clave para inicializarse a sí misma; el inicio de sesión del panel (o inscripción de admin para Enterprise) es el punto de entrada.
curl -X POST https://api.swarmhawk.com/api/v1/keys -H "Authorization: Bearer …" # { "keys": [{ "id":"…", "key_prefix":"swh_…", "calls_this_month":0, "limit_per_month":500 }], # "created": true, "is_trial": false, "full_key": "swh_…" } ← plaintext shown ONCE
GET /api/v1/keys
Lista claves activas + uso del mes actual. El texto plano nunca se vuelve a mostrar. Solo JWT Bearer — los endpoints de gestión de claves no son accesibles con una clave API.
{ "keys": [{ "id":"…", "key_prefix":"swh_3f8a2b1c",
"calls_this_month":142, "limit_per_month":500,
"cost_this_month_usd":"23.50", "last_used_at":"2026-05-12T19:01:00Z" }] }POST /api/v1/keys/{key_id}/regenerate
Revoca la clave existente e emite una nueva. El nuevo texto plano se muestra una sola vez en la respuesta — la clave anterior deja de funcionar inmediatamente. Solo JWT Bearer.
DELETE /api/v1/keys/{key_id}
Revocar una clave. Idempotente. Solo Bearer JWT.
GET /api/v1/dominios
Enumera los dominios del usuario. Paginado; respeta los parámetros ?limit y ?offset.
POST /api/v1/dominios
Añade un dominio e inicia automáticamente la verificación del orquestador. Devuelve el desafío DNS-TXT en línea para que puedas entregarlo a tu inquilino sin una llamada de seguimiento. Gratuito para el cliente — los añadidos de dominios no debitan la cartera.
Cuerpo
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| domain | string | yes | 4–253 caracteres, en minúsculas. |
| country | string | — | ISO 3166-1 alpha-2. Se deriva automáticamente del TLD si está ausente. |
| industry | string | — | Etiqueta de forma libre para agrupación e informes. |
| primary_contact | string | — | Correo electrónico para enrutamiento de brechas/alertas. |
Respuesta (201)
{
"id": "d1-uuid",
"domain": "acme.example.com",
"country": "US",
"verification": {
"state": "pending",
"dns_record_name": "_swarmhawk.acme.example.com",
"dns_record_value": "swh-verify=Xk2…",
"http_path": "/.well-known/swarmhawk-verify.txt",
"http_body": "swh-verify=Xk2…",
"expires_at": "2026-05-19T20:00:00Z"
}
}Errores: 403 tier_locked en límite; 409 domain_already_added en duplicado; 422 invalid_domain.
GET /api/v1/domains/{domain_id}
Detalle de dominio único: risk_score, last_scanned_at, verified_at, país, etc. 404 en caso de discrepancia.
PATCH /api/v1/domains/{domain_id}
Alterna auto_rescan_enabled para un dominio (el único campo mutable en este endpoint actualmente). Habilitar requiere tier Pro o superior (la puerta de características daily_rescan); deshabilitar siempre está permitido. Para cambiar industry, primary_contact o country, elimina y vuelve a agregar el dominio.
curl -X PATCH https://api.swarmhawk.com/api/v1/domains/{id} \
-H "Authorization: Bearer …" -H "Content-Type: application/json" \
-d '{"auto_rescan_enabled": true}'
# { "ok": true }DELETE /api/v1/domains/{domain_id}
Eliminación permanente de un dominio. Se elimina la fila, su estado de verificación y todos los registros de trabajos asociados. Libera una ranura contra el límite de nivel. Cuota +1.
POST /api/v1/domains/bulk-import
Carga múltiple de un CSV — cada fila es dominio,país (país es obligatorio, código ISO de 2 letras). La primera fila puede ser un encabezado dominio,país — se omite. Respeta el límite por cliente; las filas que lo superan se incluyen en la lista rechazadas con el motivo cuota excedida. Cuota +1 por llamada (no por fila).
Devuelve {accepted: [...], rejected: [...]}. Disponible en los planes Business + Enterprise (funcionalidad: bulk_import).
GET /api/v1/domains/{domain_id}/history
Lista ordenada cronológicamente de escaneos anteriores + deltas de verificación para un dominio.
GET /api/v1/domains/{domain_id}/verification
Obtención de solo lectura del estado actual del desafío de autorización del orquestador (DNS + ruta HTTP + valores de registro + vencimiento). Utilice esto si necesita volver a mostrar el desafío después de que la respuesta inicial de POST /api/v1/domains se pierda.
{
"domain": "acme.example.com",
"state": "pending", // pending | verified | failed | expired
"verified_at": null,
"dns_record_name": "_swarmhawk.acme.example.com",
"dns_record_value": "swh-verify=Xk2…",
"http_path": "/.well-known/swarmhawk-verify.txt",
"http_body": "swh-verify=Xk2…",
"expires_at": "2026-05-19T20:00:00Z"
}POST /api/v1/dominios/{domain_id}/verificar
Solicita al orquestador que ejecute la verificación. method=dns (predeterminado) realiza una búsqueda TXT; method=http obtiene https://<dominio><http_path> y compara con http_body.
curl -X POST https://api.swarmhawk.com/api/v1/domains/{id}/verify \
-H "X-API-Key: swh_…" -H "Content-Type: application/json" \
-d '{"method":"dns"}'
# {"verified":true,"state":"verified","method":"dns"}
# {"verified":false,"state":"pending","method":"dns","detail":"TXT record not found"}Cuando verified:true, tanto domains.verified_at como la caché del orquestador se actualizan — las llamadas posteriores a scan/pentest/breach ya no devuelven domain_unverified.
POST /api/v1/domains/{domain_id}/scan
Envía un escaneo de superficie de ataque al orquestador. Sin verificación de dominio — cualquier dominio añadido es elegible. Business: débitos de billetera/entitlement por service_prices.attack_surface. Enterprise: registra una fila usage_events con precio efectivo por cliente, sin tocar billetera. Cuota +1 en 201.
Respuesta (201)
{
"job_id": "orch-uuid", // poll at GET /api/v1/jobs/{job_id}
"status": "queued",
"domain": "acme.example.com",
"swarmhawk_job_id": "sw-uuid" // internal id, kept for audit
}Errores: 402 INSUFFICIENT_BALANCE, 403 enterprise_inactive, 429 cooldown (ventana compartida de 24h aplicada por orquestador con prueba de penetración), 503 orchestrator_unavailable.
POST /api/v1/domains/{domain_id}/pentest
Envía una prueba de penetración con IA. El parámetro opcional rate_profile controla la agresividad del escaneo: stealth (3 rps) · regular (10 rps, predeterminado) · aggressive (25 rps). Todos los demás parámetros mantienen los valores predeterminados del orquestador. El mismo esquema de billetera y medición que /scan.
curl -X POST https://api.swarmhawk.com/api/v1/domains/{id}/pentest \
-H "X-API-Key: swh_…" -H "Content-Type: application/json" \
-d '{"rate_profile":"regular"}'
# {"job_id":"…","status":"queued","domain":"…","swarmhawk_job_id":"…"}Misma superficie de errores que el escaneo, más 422 invalid_rate_profile.
POST /api/v1/domains/{domain_id}/breach-intel
Encola un trabajo de investigación en darknet que verifica fuentes de darknet para credenciales, hashes e información personal identificable vinculada a este dominio. Asincrónico — devuelve un job_id inmediatamente; consulta GET /api/v1/breach-intel/{job_id} para estado y hallazgos. El tiempo típico de ejecución de extremo a extremo es de 30–90 s. El dominio debe ser verificado. Business: descuenta cartera/derechos según service_prices.breach_intel. Enterprise: registra una fila usage_events con precio efectivo por cliente, sin afectar cartera. Cuota +1 en envío aceptado. Enfriamiento por dominio: 7 días (ventana de darknet del orquestador).
Response (202)
{
"job_id": "sw-uuid", // poll GET /api/v1/breach-intel/{job_id}
"orchestrator_job_id": "orch-uuid", // upstream id, kept for audit
"status": "running",
"domain": "acme.example.com",
"billing_source": "wallet" // or "entitlement" | "admin_override" | "enterprise_metered"
}Errores: 402 INSUFFICIENT_BALANCE, 403 domain_unverified, 403 enterprise_inactive, 409 already_running (un trabajo ya está en curso para este dominio), 429 cooldown (ventana local de 7 días), 429 darknet_cooldown_active (ventana de 7 días impuesta por orquestador con next_available_at), 502 orchestrator_unavailable, 503 orchestrator_unavailable.
GET /api/v1/breach-intel/{job_id}
Consulta un trabajo de investigación en darknet. Con validación de propiedad; sin cuota. El backend consulta perezosamente al orquestador (regulación de 5 s) mientras la fila local esté en estado running, por lo que este endpoint puede llamarse frecuentemente sin sobrecargar flujo ascendente. Una vez que el trabajo alcanza un estado terminal (completed | failed | cancelled), las llamadas posteriores devuelven la fila cacheada sin ningún viaje al orquestador.
Response (200) — running
{
"job_id": "sw-uuid",
"orchestrator_job_id": "orch-uuid",
"domain": "acme.example.com",
"status": "running",
"leak_count": null,
"findings": [],
"pagination": { "page":1, "page_size":50, "total":0, "total_pages":0 },
"error": null,
"billing_source": "wallet",
"requested_at": "2026-05-19T20:23:35Z",
"completed_at": null
}Response (200) — completed
{
"job_id": "sw-uuid",
"domain": "acme.example.com",
"status": "completed",
"leak_count": 4,
"findings": [
{
"id": 2,
"email": "[email protected]",
"username": "alice",
"breach_name": "leakdb",
"breach_date": null,
"has_password": true, // plaintext available via /reveal
"password": { "sha1":"6DD85DDA386874EC…", "encrypted":true },
"risk_level": "high"
}
],
"pagination": { "page":1, "page_size":50, "total":4, "total_pages":1 },
"error": null,
"billing_source": "wallet",
"requested_at": "2026-05-19T20:23:35Z",
"completed_at": "2026-05-19T20:23:43Z"
}Response (200) — failed
{
"job_id": "sw-uuid",
"status": "failed",
"error": "no_data_available", // or "orchestrator_job_not_found" | "orchestrator_failed"
"leak_count": null,
"findings": [],
"billing_source": "wallet",
"requested_at": "2026-05-19T20:23:35Z",
"completed_at": "2026-05-19T20:24:01Z"
}En error = "no_data_available" o "orchestrator_job_not_found", el consumo de cartera/derechos se reembolsa automáticamente — sin acción requerida del llamador.
POST /api/v1/breach-intel/{job_id}/reveal/{finding_id}
Descifra una contraseña en texto plano de un hallazgo en darknet. Solo propietario (intentos entre inquilinos devuelven 404 — privado de existencia). El dominio debe seguir verificado por orquestador en el momento de la llamada. El texto plano se devuelve en línea y NUNCA se persiste en la BD de SwarmHawk; cada llamada escribe una fila admin_audit_log. Sin costo de cuota.
Response (200)
{
"plaintext": "Hunter2!",
"revealed_at": "2026-05-19T20:25:10Z"
}Errores: 403 domain_unverified (verificación caducada desde que se ejecutó el escaneo), 404 finding_not_found (id no es parte de este trabajo — también se devuelve para entre inquilinos), 502 orchestrator_reveal_failed. Solo hallazgos con has_password: true en la respuesta GET pueden ser revelados.
GET /api/v1/jobs/{job_id}
Proxy de estado de trabajo hacia el orquestador. El job_id aquí es el id del orquestador devuelto por POST /scan o /pentest. La propiedad se valida en el servidor — 404 en caso de desajuste (existencia-privada). GET = sin cuota.
{
"id": "orch-uuid",
"status": "running", // queued | running | done | failed | cancelled
"created_at": "…",
"updated_at": "…",
"progress_pct": 42, // integer 0–100 (NOT a 0–1 fraction)
"phase": "recon", // free-form server label, display-only
"target": "acme.example.com"
}Progress is reported as progress_pct (integer percentage, 0–100) plus a free-form phase label — both pass through verbatim from the scan engine, so treat unknown phase values as display-only.
Sondea cada 5–10 segundos mientras status sea queued o running. Una vez done, obtén los hallazgos / reporte a continuación.
GET /api/v1/jobs/{job_id}/findings
Lista estructurada de hallazgos (vulnerabilidades, servicios expuestos, configuraciones débiles, etc.). Se devuelve una vez que status == 'done'.
Returns a bare JSON array. Each item is emitted verbatim by the scan engine, so treat fields beyond the common ones below as additive.
[
{
"id": "f-1",
"severity": "high", // info | low | medium | high | critical
"title": "Exposed admin panel",
"target": "admin.acme.example.com",
"description": "…"
}
]Errors: 404 findings_not_available if no findings exist for the job yet (still running, or output not enabled for your account); 404 not_found for an unknown / cross-tenant job; 502 api_get_findings_unavailable if the scan service is unreachable.
GET /api/v1/jobs/{job_id}/report
Informe JSON completo (resumen ejecutivo + hallazgos + recomendaciones). Disponible una vez que done.
Returns a JSON object wrapping the engine-rendered structured report. The nested report object passes through from the scan engine.
{
"status": "done",
"generated_at": "2026-06-03T09:12:44Z",
"model": "claude-…",
"report": {
"executive_summary": "…",
"findings": [ /* same items as /findings */ ],
"recommendations": [ "…" ]
}
}Errors: 404 report_not_available if the report has not been generated for this job (still running, or report generation not enabled for your account); 502 api_get_report_unavailable if the scan service is unreachable.
GET /api/v1/jobs/{job_id}/report.pdf
El mismo informe renderizado como PDF (flujo binario con Content-Disposition ascendente). Apto para redistribución directa a tu tenant.
On success returns 200 with Content-Type: application/pdf and the upstream Content-Disposition filename.
PDF generation is not enabled on every account / job type. When no PDF is available you get 404 {"error":"report_not_available"} with a human-readable detail — not a generic 502. A 502 api_get_report_pdf_unavailable means the scan service itself is unreachable (retry with back-off). Fall back to GET …/report (JSON) when you only need the data.
Nivel Empresarial
El nivel Enterprise está diseñado para proveedores de hosting, MSSPs y otros revendedores que ejecutan SwarmHawk como una API de marca blanca en nombre de múltiples inquilinos. Se requiere inscripción de administrador (sin compra de autoservicio) y negociación contractual — contacta con ventas para incorporarse.
Qué diferencia hay con Business
- Límite máximo de dominios por cliente — tu contrato establece
max_domains(p. ej. 100, 500, 5000); la solicitud (N+1)ésimaPOST /api/v1/domainsdevuelve403 tier_lockedconfeature:"domains"y un cuerpolimit/current. - Llamadas API ilimitadas — tu clave incluye
limit_per_month: null; se omite la cuota mensual que aplica a Pro/Business. - Medición por llamada — cada llamada de
scan,pentesteintelligence de brechasse registra en un registrousage_eventsinmutable con el precio efectivo por cliente, recuperable medianteGET /api/v1/usage. Los precios por servicio pueden ser sobrescritos por contrato por un administrador (en caso contrario, recurren a la tarifa global). - Sin cartera / sin Stripe — La facturación empresarial se realiza fuera de la plataforma en un ciclo de facturación mensual. El saldo de cartera de tu revendedor es irrelevante.
- Solo API — Los clientes Enterprise no inician sesión en el panel. El equipo de ventas te entrega tu clave portadora fuera de banda; todo lo siguiente funciona con
X-API-Key: swh_….
Endpoints disponibles
Los clientes Enterprise utilizan la superficie Business existente /api/v1/* más el nuevo GET /api/v1/usage:
POST /api/v1/keys,GET /api/v1/keys— ver tus metadatos clave propios (la clave en texto plano solo se muestra una vez en la inscripción / regeneración).POST /api/v1/domains— sujeto al límitemax_domainspor cliente.POST /api/v1/domains/{id}/verifyPOST /api/v1/domains/{id}/scanPOST /api/v1/domains/{id}/pentestPOST /api/v1/domains/{id}/breach-intel·GET /api/v1/breach-intel/{job_id}GET /api/v1/usage— Solo para empresa (véase abajo).
GET /api/v1/usage
Agregados de uso por dominio para un cliente Enterprise en un período de facturación mensual determinado. Úselo para reconciliar su factura mensual o para facturar a sus propios inquilinos por dominio.
Parámetros de consulta
| Nombre | Tipo | Predeterminado | Descripción |
|---|---|---|---|
| period | string | mes actual | Formato YYYY-MM. Se traduce a [YYYY-MM-01, próximo-mes-01) UTC. Los valores con formato incorrecto devuelven 400 invalid_period. |
Ejemplo
curl https://api.swarmhawk.com/api/v1/usage?period=2026-05 \
-H "X-API-Key: swh_…"Respuesta
{
"period": "2026-05",
"currency": "USD",
"domains": [
{
"domain_id": "d1-uuid",
"domain": "acme.example.com",
"scans_count": 12,
"pentests_count": 3,
"breach_lookups_count": 8,
"total_cost_usd": 234.50
}
],
"totals": {
"scans_count": 47,
"pentests_count": 11,
"breach_lookups_count": 22,
"total_cost_usd": 1284.75
}
}Notas
- El array
domainscontiene solo dominios con al menos un evento en el período. Los dominios que posees pero que no utilizaste ese mes se omiten — consultaGET /api/v1/domainspara el inventario completo. - Si un dominio se elimina entre el evento y la consulta, su fila sigue apareciendo con
domain_id: nullydomain: "<deleted>"— el registro de auditoría se preserva. - El costo refleja el precio efectivo por llamada en el momento del evento: anulación de contrato por cliente si está configurada, de lo contrario, la tarifa de la tarjeta de precios del servicio global.
- 403
enterprise_onlyse devuelve a cualquier nivel que no sea Enterprise que acceda a este endpoint.
Comportamiento de desactivación
Si tu cuenta Enterprise está pausada por un administrador (falta de pago, fin de contrato, etc.), todas las llamadas a /api/v1/* — lectura y escritura — devuelven:
HTTP 403 { "detail": { "error": "enterprise_inactive" } }
La clave de API no se revoca (por lo que la reactivación restaura el acceso sin emitir nuevas claves), y los usage_events + domains históricos se conservan. Contacte a ventas para reactivar.
SDK de Python
El SDK de Python de SwarmHawk proporciona a las plataformas de seguridad una interfaz programática limpia para extraer hallazgos, configurar integraciones push y consumir bundles de STIX 2.1, sin necesidad de HTTP raw.
Métodos del SDK
| Método | Descripción | Devuelve |
|---|---|---|
domains(min_risk, country, limit, offset) | Resultados de escaneo paginados | list[dict] |
domain(name) | Detalle completo de un único dominio | dict |
alerts(min_risk, since, limit) | Hallazgos de alto riesgo, opcionales desde datetime | list[dict] |
iter_alerts(min_risk, page_size) | Generador — pagina automáticamente todos los resultados | Iterator[dict] |
stix_bundle(min_risk, limit) | Bundle STIX 2.1 desde endpoint /taxii | dict |
integrations() | Lista integraciones push configuradas | list[dict] |
configure_integration(service, config) | Guarda las credenciales de integración | dict |
test_integration(service, config) | Prueba la conectividad sin guardar | {ok, message} |
API de Integración
INTEGRATIONS_ENABLED=false (la configuración predeterminada de la plataforma), todos los endpoints /integrations* devuelven HTTP 410 { "error": "feature_disabled" }. Contacta a [email protected] si necesitas reactivar esta función en tu cuenta.Cuando esté habilitado, configure integraciones push para que SwarmHawk envíe automáticamente los hallazgos críticos a sus plataformas de seguridad en el momento en que se detecten (riesgo ≥ 70).
GET /integraciones
Enumera todas las integraciones configuradas para el usuario autenticado. Los secretos están enmascarados.
POST /integraciones/{service}
Guardar o actualizar configuración de integración. service es uno de: splunk · sentinel · crowdstrike · gravityzone · cortex · jira · servicenow · webhook · stix
POST /integraciones/{servicio}/prueba
Prueba la conectividad sin guardar. Devuelve {"ok": true, "message": "..."}
DEL /integraciones/{servicio}
Eliminar una configuración de integración.
Servicios compatibles
| Servicio | Método de autenticación | Activador | Tipo de payload |
|---|---|---|---|
| splunk | Token HEC | riesgo ≥ 70 | evento JSON alineado con CIM |
| sentinel | HMAC de clave compartida del área de trabajo | riesgo ≥ 70 | Campos listos para KQL plana (_s/_d/_b) |
| crowdstrike | Credenciales de cliente OAuth2 | riesgo ≥ 70 | IOC (type=dominio, action=detect/prevent) |
| gravityzone | Clave de acceso Bearer | riesgo ≥ 70 | JSON-RPC createCustomRule |
| cortex | SHA-256 HMAC (api_key_id/nonce/ts) | riesgo ≥ 70 | Alerta externa con etiquetas MITRE |
| jira | Básica (email:api_token) | riesgo ≥ 70 AND cvss ≥ 7 | Incidencia en formato ADF con tablas de CVE/software |
| servicenow | Básica (usuario:contraseña) | riesgo ≥ 70 | Incidente con mapeo de urgencia/impacto/SLA |
| webhook | Firma HMAC-SHA256 opcional | riesgo ≥ 70 | Carga JSON enriquecida |
| stix | Bearer (lectura vía /taxii) | Basado en extracción | Objetos DomainName + Vulnerability de STIX 2.1 |
STIX / TAXII 2.1
SwarmHawk expone un endpoint compatible con TAXII 2.1. Conecta cualquier plataforma de inteligencia de amenazas (OpenCTI, MISP, ThreatConnect, Anomali) para extraer hallazgos de SwarmHawk como objetos STIX 2.1.
GET /taxii/colecciones/
Punto de conexión de descubrimiento TAXII — devuelve metadatos de colecciones.
GET /taxii/collections/swarmhawk/objects/
Devuelve un paquete STIX 2.1 de tus dominios de alto riesgo como objetos domain-name, vulnerability y relationship.
| Parámetro | Predeterminado | Descripción |
|---|---|---|
| min_risk | 70 | Puntuación de riesgo mínima (0–100) |
| limit | 100 | Máximo de objetos (1–500) |
Tipos de objetos STIX devueltos
| Tipo | Contenido |
|---|---|
| domain-name | Valor de dominio, puntuación de riesgo, prioridad, país |
| vulnerability | ID de CVE, puntuación CVSS, descripción |
| relationship | nombre-de-dominio → relacionado-con → vulnerabilidad |
Todos los IDs de objeto son determinísticos (UUID5) — el mismo dominio siempre produce el mismo ID STIX en todas las generaciones de bundles, permitiendo la deduplicación adecuada en las plataformas de inteligencia de amenazas posteriores.
Scripts de Adaptador
Scripts independientes de Python para plataformas donde prefieres un pull programado (cron / Lambda / Azure Function) sobre el conector push siempre activo. Cada script obtiene las alertas de SwarmHawk y las envía a la plataforma de destino en una única ejecución.
pip install httpx y aceptan tanto flags de CLI como variables de entorno.| Plataforma | Script | Riesgo mínimo por defecto | Descargar |
|---|---|---|---|
| Splunk SIEM | splunk_ta.py |
70 | ↓ splunk_ta.py |
| Microsoft Sentinel | sentinel_connector.py |
70 | ↓ sentinel_connector.py |
| CrowdStrike Falcon | crowdstrike_adapter.py |
80 | ↓ crowdstrike_adapter.py |
| Bitdefender GravityZone | gravityzone_adapter.py |
80 | ↓ gravityzone_adapter.py |
| Palo Alto Cortex XDR | cortex_adapter.py |
75 | ↓ cortex_adapter.py |
| Jira | jira_adapter.py |
70 + cvss ≥ 7 | ↓ jira_adapter.py |
| ServiceNow | servicenow_adapter.py |
70 | ↓ servicenow_adapter.py |
sdk/adapters/.Adaptador TA Splunk
| Marcador | Variable de entorno | Descripción |
|---|---|---|
| --api-key | SWARMHAWK_API_KEY | Clave API de SwarmHawk |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínima (predeterminado: 70) |
| --base-url | SWARMHAWK_BASE_URL | URL base de la API |
| --index | SWARMHAWK_SPLUNK_INDEX | Nombre del índice de Splunk (predeterminado: main) |
Emite eventos sourcetype=swarmhawk:scan con campos alineados a CIM: dest, vendor_product, category, severity.
Adaptador de Microsoft Sentinel
| Marcar | Variable de entorno | Descripción |
|---|---|---|
| --workspace-id | AZURE_WORKSPACE_ID | ID del espacio de trabajo de Log Analytics |
| --shared-key | AZURE_SHARED_KEY | Clave compartida primaria o secundaria |
| --log-type | AZURE_LOG_TYPE | Nombre de tabla personalizado (predeterminado: SwarmHawk) |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínima (predeterminado: 70) |
Los datos se almacenan en la tabla personalizada SwarmHawk_CL. Ejemplo de KQL: SwarmHawk_CL | where RiskScore_d >= 80 | sort by TimeGenerated desc
Adaptador CrowdStrike Falcon
| Marcar | Variable de entorno | Descripción |
|---|---|---|
| --cs-client-id | CS_CLIENT_ID | ID de cliente de Falcon API |
| --cs-client-secret | CS_CLIENT_SECRET | Secreto del cliente de la API de Falcon |
| --cs-base-url | CS_BASE_URL | URL base de Falcon (predeterminada: api.crowdstrike.com) |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínima (por defecto: 80) |
Envía dominios como IOCs (type=domain) en lotes de 200. La acción es prevent para malware/phishing confirmados, detect para exposición a CVE.
Adaptador Bitdefender GravityZone
| Bandera | Variable de entorno | Descripción |
|---|---|---|
| --gz-api-url | GZ_API_URL | Punto final JSON-RPC de GravityZone |
| --gz-access-key | GZ_ACCESS_KEY | Clave de acceso API de GravityZone |
| --gz-company-id | GZ_COMPANY_ID | ID de empresa/inquilino |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínima (predeterminado: 80) |
Crea reglas de red personalizadas mediante createCustomRule. La acción es block para malware/phishing, report para exposición de CVE.
Adaptador Palo Alto Cortex XDR
| Marcar | Variable de entorno | Descripción |
|---|---|---|
| --xdr-api-key | XDR_API_KEY | Clave de API de Cortex XDR |
| --xdr-api-key-id | XDR_API_KEY_ID | ID numérico de clave API |
| --xdr-fqdn | XDR_FQDN | El FQDN de su tenant (sin https://api-) |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínimo (predeterminado: 75) |
Envía alertas externas con etiquetas de técnicas MITRE ATT&CK (T1566, T1190, T1046, T1557…). Lotes de 100 por llamada API.
Adaptador Jira
| Marcar | Variable de entorno | Descripción |
|---|---|---|
| --jira-base-url | JIRA_BASE_URL | URL de Atlassian Cloud |
| --jira-email | JIRA_EMAIL | Correo electrónico de cuenta Atlassian |
| --jira-token | JIRA_TOKEN | Token de API de Atlassian (id.atlassian.com → Security) |
| --jira-project | JIRA_PROJECT | Clave del proyecto (predeterminado: SEC) |
| --jira-issue-type | JIRA_ISSUE_TYPE | Tipo de incidencia (predeterminado: Bug) |
| --min-cvss | SWARMHAWK_MIN_CVSS | CVSS mínimo para crear ticket (predeterminado: 7.0) |
Crea incidencias ADF estructuradas con tabla de resumen de riesgos, hallazgos de CVE, stack de software, controles fallidos, bullets de remediación y etiqueta NIS2. Se ejecuta solo cuando riesgo ≥ 70 Y cvss ≥ min_cvss para evitar spam de tickets.
Adaptador de ServiceNow
| Marcar | Variable de entorno | Descripción |
|---|---|---|
| --snow-instance | SNOW_INSTANCE | Subdominio de instancia de ServiceNow (sin .service-now.com) |
| --snow-user | SNOW_USER | Nombre de usuario de ServiceNow |
| --snow-password | SNOW_PASSWORD | Contraseña de ServiceNow |
| --snow-table | SNOW_TABLE | Tabla de destino (predeterminado: incident) |
| --min-risk | SWARMHAWK_MIN_RISK | Puntuación de riesgo mínima (predeterminado: 70) |
| Prioridad | Urgencia | Impacto | objetivo de SLA |
|---|---|---|---|
| CRITICAL | 1 | 1 | 4 horas |
| HIGH | 1 | 2 | 24 horas |
| MEDIUM | 2 | 2 | 7 días |
| LOW / INFO | 3 | 3 | 30 días |
Objetos de Respuesta
Verificar objeto
| Campo | Tipo | Descripción |
|---|---|---|
| check | string | Identificador de verificación (consulte Nombres de verificación a continuación) |
| status | string | ok · warning · critical · locked |
| title | string | Hallazgo legible de una línea |
| detail | string | Explicación completa con evidencia |
| score_impact | number | Puntos agregados a la puntuación de riesgo (0–40) |
Interpretación de puntuación de riesgo
| Puntuación | Nivel | Significado |
|---|---|---|
| 0 – 29 | RIESGO BAJO | Postura de seguridad sólida, problemas menores |
| 30 – 59 | RIESGO MEDIO | Problemas destacados que requieren atención |
| 60 – 100 | RIESGO ALTO | Hallazgos críticos, acción inmediata requerida |
Verificar Nombres
Cada entrada en el array checks[] de un informe de escaneo lleva un identificador check. La lista exhaustiva de identificadores emitidos por el escáner actualmente (fuente: backend/scanhawk_translator.py + backend/post_scan_processor.py):
| verificación | Grupo | Descripción |
|---|---|---|
tls_protocol | TLS | Versión TLS negociada (marca TLS < 1.2) |
tls_cipher | TLS | Conjuntos de cifrado débiles |
tls_cert_expiry | TLS | Vencimiento de certificado / ya expirado |
tls_self_signed | TLS | Certificado autofirmado |
tls_handshake | TLS | Errores de protocolo de enlace TLS |
email_dmarc | DMARC ausente o débil (p=none) | |
mx_blacklist | Host MX en una lista de bloqueo pública | |
blacklist | Reputation | Dominio o registro A en una lista de bloqueo pública (Spamhaus / URLhaus / Safe Browsing) |
ip_reputation | Reputation | Señales de reputación de IP de alojamiento / geo / ASN |
cve_match | Vulns | Huella digital de software coincidió con CVEs conocidas (CVSS + KEV + EPSS) |
exposed_git | Exposure | Directorio /.git/ público |
exposed_env | Exposure | Archivo .env público |
mixed_content | Web | La página HTTPS carga subrrecursos HTTP |
sri_missing | Web | Integridad de subrecursos ausente en scripts de terceros |
cookies_secure | Web | Cookies sin los atributos Secure / HttpOnly / SameSite |
takeover_risk | DNS | Subdominio huérfano / candidato a takeover |
security_txt | Hygiene | Falta /.well-known/security.txt (RFC 9116) |
whois_privacy | Hygiene | Protección de privacidad WHOIS activada / desactivada |
ai_summary | Reporting | Análisis de amenazas generado por IA (solo usuarios de pago) |
Las verificaciones granulares (p. ej. tls_protocol, tls_cipher) se agrupan bajo categorías más amplias (TLS, DNS, Headers, etc.) para su visualización en el dashboard. El informe PDF utiliza etiquetas adicionales orientadas al usuario (véase backend/main.py:CHECK_LABELS), pero los identificadores JSON anteriores conforman la superficie canónica.
Obtén tu clave API gratuita en www.swarmhawk.com → Iniciar sesión → Cuenta → Claves API
Obtener Clave API Gratuita →Pruébalo en Vivo
Explorador API completamente interactivo — ejecuta solicitudes reales contra la API de SwarmHawk directamente desde tu navegador. Pega tu clave API en el botón Autorizar para desbloquear endpoints autenticados.