> For the complete documentation index see https://domscan.net/llms.txt. Markdown versions of every docs page are available by appending .md to the page URL.

Source: https://domscan.net/zh/docs/subdomains

# 子域查找器

通过 DomScan API，不是。这是尽力而为的被动覆盖。内部名称和来源数据集中缺失的公开主机不会出现，DNS 验证也不会搜索更多名称。

不是。这是尽力而为的被动覆盖。内部名称和来源数据集中缺失的公开主机不会出现，DNS 验证也不会搜索更多名称。

使用 GET /v1/subdomains?domain=example.com&sources=ct。ct 值选择兼容管线，每条记录会报告实际证据来源。仅缓存未命中返回 202，所有来源均失败时返回 503，两者都会退还积分。

GET /v1/subdomains

#### 查询参数

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| domain 必需 | string | 查找子域的根域(例如,"github.com") |
| prefer_cache 可选 | boolean token | 仅返回缓存结果。如果没有新鲜或旧缓存，API 会返回 202，排队后台刷新并退还本次请求的积分。可接受的值：true、false、1、0、yes、no。默认值：false。 |
| sources 可选 | string | 兼容选择值。仅接受 `ct`。它会启动被动发现管线，但每条结果都会标明提供证据的来源：`crtsh`、`crtname`、`hackertarget`、`threatminer`、`wayback` 或 `certspotter`。较早的缓存条目可能标为 `ct`。 |
| verify 可选 | boolean token | 仅对已选入响应的名称执行 DNS 检查。验证不会发现更多名称。可接受的值：`true`、`false`、`1`、`0`、`yes`、`no`。默认值：`false`。 |
| include_wildcards 可选 | boolean token | 在单独的 `wildcards` 数组中返回通配符证书证据。通配符不会混入具体主机名结果。可接受的值：`true`、`false`、`1`、`0`、`yes`、`no`。默认值：`false`。 |
| limit 可选 | integer | 最多返回多少条具体主机名记录。请输入 1 到 2000 的整数。默认值：500。 |
| cursor 可选 | string | 上一页返回的 `next_cursor`。参见[分页](https://domscan.net/docs/response-format#pagination)。 |

#### 使用场景

- 攻击面映射和安全审计

- 审查可能已被遗忘或属于影子 IT 的主机名

- 收购前技术尽职调查

- 竞争对手基础设施分析

- 漏洞赏金侦查

#### 响应字段

| 字段 | 说明 |
| --- | --- |
| `subdomains[].name` | 返回的主机名。如果来源包含根域名，根域名也可能出现。 |
| `subdomains[].source` | 审查公开主机名证据并清楚了解来源 |
| `subdomains[].first_seen` | 有 CT 支持的条目会报告找到的最早证书 not-before 值。其他被动回退条目可能返回 null。 |
| `subdomains[].verified` | 仅当启用 verify 且返回主机名的 DNS 解析成功时为 true，否则为 false。 |
| `subdomains[].dns_records` | 对返回主机名进行可选验证时得到的 A 和 CNAME 记录，或者 null。此字段不会向结果添加名称。 |
| `summary.total_found` | 应用响应数量限制前找到的具体主机名记录总数。如果来源包含根域名，也会计入。 |
| `summary.verified_count` | 在可选 DNS 验证中成功解析的返回主机名数量。 |

#### HTTP 状态码

| HTTP 状态码 | 说明 |
| --- | --- |
| `200` 成功 | 请求成功 |
| `202` 已接受 | 仅缓存的子域名请求未命中，已接受并在后台刷新。不收取积分；请在 Retry-After 延迟后重试。 |
| `400` 请求错误 | 参数无效 |
| `402` 需要付款 | 没有足够额度来执行此请求。 |
| `503` 服务不可用 | 上游服务不可用或正在临时限流。 |
| `504` 网关超时 | 上游查询已超时。 |

#### 请求示例

```bash
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"
```

```python
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']}")
```

```javascript
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}`));
```

#### 响应示例

```json
{
  "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 已接受

```json
{
  "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 积分: 4-5/item

#### 查询参数

| 参数 | 类型 | 必需 |
| --- | --- | --- |
| dry_run | string 允许的值 `true` | 可选 |

#### 正文参数

| 参数 | 类型 | 必需 |
| --- | --- | --- |
| domains | string[] | 必需 |
| verify | boolean 默认值 `false` | 可选 |
| include_wildcards | boolean 默认值 `false` | 可选 |
| limit | integer 默认值 `500` | 可选 |

#### 响应字段

| 字段 | 类型 |
| --- | --- |
| `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 |

#### 请求示例

```bash
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
}'
```

```javascript
const response = await fetch("https://domscan.net/v1/subdomains/bulk", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "domains": [
      "example.com",
      "cloudflare.com"
    ],
    "verify": false,
    "limit": 500
  }),
});
const data = await response.json();
console.log(data);
```

```python
import os
import requests

response = requests.post(
    "https://domscan.net/v1/subdomains/bulk",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "domains": [
            "example.com",
            "cloudflare.com",
        ],
        "verify": False,
        "limit": 500,
    },
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "domains": [
	    "example.com",
	    "cloudflare.com"
	  ],
	  "verify": false,
	  "limit": 500
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/subdomains/bulk", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
```

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/subdomains/bulk")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "domains" => [
    "example.com",
    "cloudflare.com"
  ],
  "verify" => false,
  "limit" => 500
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))
```

#### 响应示例

```json
{
  "results": [
    {
      "input": "example",
      "data": {}
    }
  ],
  "meta": {
    "total": 1,
    "succeeded": 1,
    "failed": 1,
    "max_items": 10,
    "credits_per_item": 1,
    "duration_ms": 1
  }
}
```

#### HTTP 状态码

- `200` 成功
- `400` 请求错误
- `401` 未授权
- `402` 需要付款
- `409` HTTP 409
- `422` HTTP 422
- `429` 请求过多
