Referencia para desarrolladores
Buscador de subdominios
Consulta la documentación de la API de Buscador de subdominios, con parámetros de solicitud, campos de respuesta, ejemplos de código y gestión de errores para integraciones con DomScan.
Buscador de subdominios
Devuelve un conjunto de mejor esfuerzo de indicios públicos sobre nombres de host. El parámetro sources=ct selecciona la canalización de compatibilidad, que prueba primero crt.sh y puede recurrir a HackerTarget, ThreatMiner, Wayback Machine y CertSpotter. DomScan no busca nombres por fuerza bruta ni rastrea el sitio objetivo, por lo que el resultado no es un inventario completo. Los fallos del modo solo caché devuelven HTTP 202 y los fallos de todas las fuentes devuelven HTTP 503. Los créditos se reembolsan en ambos casos.
GET
/v1/subdomains
Parámetros de consulta
| Parámetro | Tipo | Descripción |
|---|---|---|
| domain obligatorio | string | Dominio raíz para encontrar subdominios (p. ej., "github.com") |
| prefer_cache opcional | boolean token | Sirve solo resultados en caché. Si no existe una caché nueva ni antigua, la API devuelve 202, pone en cola una actualización en segundo plano y reembolsa los créditos de la solicitud. Valores aceptados: true, false, 1, 0, yes y no. Predeterminado: false. |
| sources opcional | string | Selector de compatibilidad. Solo se acepta ct. Inicia la canalización de descubrimiento pasivo, pero cada resultado indica el proveedor que aportó el indicio: crtsh, hackertarget, threatminer, wayback o certspotter. Las entradas antiguas de caché pueden indicar ct. |
| verify opcional | boolean token | Comprueba mediante DNS solo los nombres ya seleccionados para la respuesta. La verificación no descubre más nombres. Valores aceptados: true, false, 1, 0, yes y no. Predeterminado: false. |
| include_wildcards opcional | boolean token | Devuelve indicios de certificados comodín en un array wildcards separado. Los comodines no se mezclan con los resultados de nombres de host concretos. Valores aceptados: true, false, 1, 0, yes y no. Predeterminado: false. |
| limit opcional | integer | Número máximo de entradas de nombres de host concretos que se devolverán. Introduce un entero entre 1 y 2000. Predeterminado: 500. |
Casos de uso
- Mapeo de superficie de ataque y auditorías de seguridad
- Revisar posibles nombres de host olvidados o de TI en la sombra
- Diligencia debida técnica pre-adquisición
- Análisis competitivo de infraestructura
- Reconocimiento para bug bounty
Campos de respuesta
| Campo | Descripción |
|---|---|
subdomains[].name | Nombre de host devuelto. El dominio raíz puede aparecer si una fuente lo incluye. |
subdomains[].source | Proveedor que aportó el indicio. Los valores posibles son crtsh, hackertarget, threatminer, wayback, certspotter y ct para entradas antiguas de caché. |
subdomains[].first_seen | Para indicios de crt.sh y CertSpotter, el primer valor not-before válido del certificado encontrado para el nombre de host. Las fuentes pasivas alternativas devuelven null porque no ofrecen una fecha de certificado comparable. |
subdomains[].verified | true solo cuando verify está activado y la consulta DNS del nombre de host devuelto encuentra un registro A o CNAME. En los demás casos, false. |
subdomains[].dns_records | Registros A o CNAME obtenidos en la verificación opcional del nombre de host devuelto, o null. Este campo no añade nombres al resultado. |
summary.total_found | Número total de entradas de nombres de host concretos encontradas antes del límite de respuesta, incluido el dominio raíz si una fuente lo incluye. |
summary.verified_count | Número de nombres de host devueltos que resolvieron a un registro A o CNAME durante la verificación DNS opcional. |
Códigos de estado HTTP
| Códigos de estado HTTP | Descripción |
|---|---|
200 OK | Solicitud correcta |
202 Aceptado | Fallo de caché de subdominios en modo solo caché aceptado para actualización en segundo plano. No se cobran créditos; reintenta tras el intervalo Retry-After. |
400 Solicitud incorrecta | Parámetros no válidos |
402 Pago requerido | No tienes créditos suficientes para ejecutar esta solicitud. |
503 Servicio no disponible | El servicio ascendente no está disponible o está limitando temporalmente. |
504 Tiempo de espera de la puerta de enlace agotado | La consulta al servicio de origen agotó el tiempo de espera. |
Solicitud de ejemplo
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&sources=ct&include_wildcards=yes&limit=100"
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&sources=ct&verify=yes&limit=50"
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&prefer_cache=1"
import requests
domscan = requests.Session()
domscan.headers.update({"X-API-Key": "your-api-key"})
response = domscan.get(
"https://domscan.net/v1/subdomains",
params={
"domain": "example.com",
"sources": "ct",
"verify": "yes",
"include_wildcards": "yes",
"limit": 100
}
)
data = response.json()
print(f"Returned {data['summary']['returned']} hostname entries")
print(f"Verified: {data['summary']['verified_count']}")
live_subs = [s for s in data['subdomains'] if s['verified']]
for sub in live_subs[:10]:
print(f" {sub['name']}")
const domscanFetch = (url, options = {}) =>
fetch(url, {
...options,
headers: { ...options.headers, "X-API-Key": "your-api-key" },
});
const response = await domscanFetch(
'https://domscan.net/v1/subdomains?' + new URLSearchParams({
domain: 'example.com',
sources: 'ct',
verify: 'yes',
include_wildcards: 'yes',
limit: '100'
})
);
const data = await response.json();
console.log(`Returned ${data.summary.returned} hostname entries`);
console.log(`Verified: ${data.summary.verified_count}`);
data.subdomains
.filter(s => s.verified)
.forEach(s => console.log(` ${s.name}`));
Respuesta de ejemplo
{
"domain": "example.com",
"subdomains": [
{
"name": "api.example.com",
"source": "crtsh",
"first_seen": "2025-01-15T00:00:00Z",
"verified": true,
"dns_records": {
"A": ["192.0.2.10"],
"CNAME": null
}
}
],
"wildcards": [
{
"pattern": "*.example.com",
"source": "crtsh",
"first_seen": "2024-11-20T00:00:00Z"
}
],
"summary": {
"total_found": 1,
"returned": 1,
"verified_count": 1,
"unverified_count": 0,
"sources_used": ["crtsh"],
"apex_included": false,
"wildcard_suppressed_count": 1,
"wildcard_returned_count": 1
},
"intelligence_summary": {
"data_sources": ["crtsh"],
"source_count": 1,
"cache_status": "live",
"returned_count": 1,
"total_found": 1,
"truncated": false,
"limit": 100,
"verification_requested": true,
"include_wildcards": true,
"verified_count": 1,
"verified_ratio": 1,
"live_dns_record_count": 1,
"apex_included": false,
"wildcard_suppressed_count": 1,
"wildcard_returned_count": 1,
"first_seen_oldest": "2025-01-15T00:00:00Z",
"first_seen_newest": "2025-01-15T00:00:00Z",
"warning_count": 0
},
"meta": {
"query_time_ms": 184,
"cached": false
}
}
202 Aceptado
{
"status": "pending",
"code": "CACHE_MISS_REFRESH_QUEUED",
"message": "Try again in a moment",
"domain": "example.com",
"retry_after": 30,
"credits_charged": 0,
"billing_status": "not_charged",
"request_id": "m8abc12-x9y8"
}
POST
/v1/subdomains/bulk
Parámetros del cuerpo
| Parámetro | Tipo | obligatorio |
|---|---|---|
| domains | string[] | obligatorio |
| verify | boolean | opcional |
| include_wildcards | boolean | opcional |
| limit | integer | opcional |
Campos de respuesta
| Campo | Tipo |
|---|---|
results[] |
unknown[] |
meta |
object |
meta.total |
integer |
meta.succeeded |
integer |
meta.failed |
integer |
meta.max_items |
integer |
meta.credits_per_item |
integer |
meta.duration_ms |
integer |
Solicitud de ejemplo
curl -X POST "https://domscan.net/v1/subdomains/bulk" \
-H "Content-Type: application/json" \
-H "X-API-Key: $DOMSCAN_API_KEY" \
-d '{
"domains": [
"example.com",
"cloudflare.com"
],
"verify": false,
"limit": 500
}'
Respuesta de ejemplo
{
"results": [
null
],
"meta": {
"total": 1,
"succeeded": 1,
"failed": 1,
"max_items": 10,
"credits_per_item": 1,
"duration_ms": 1
}
}