域名状态查询API
接口概述
提供域名在各主流平台的拦截/封禁状态检测服务。接口采用子类型设计,通过
sub_type 参数指定检测目标平台,支持批量检测多个 URL。
每个子类型拥有独立的资源包(API 调用次数),互不干扰、独立扣费。
批量统一走批次异步:一次提交多个 URL(>1 条)时,接口会将整批域名记录为一个
批次任务(返回 task_id),检测在后台异步执行,
调用方通过查询批次结果接口轮询获取整批状态。
只有单条查询支持同步等待返回。
子类型说明
通过 sub_type 参数选择要检测的目标平台:
| 子类型值 | 检测平台 | 扣费类型(credits_key) | 状态 |
|---|---|---|---|
wechat |
微信拦截检测 | domain_check_wechat |
✅ 已开放 |
qq |
QQ 拦截检测 | domain_check_qq |
✅ 已开放 |
douyin |
抖音拦截检测 | douyin |
✅ 已开放 |
扩展说明:后续新增平台(如支付宝等)只需在服务端注册新子类型并配置对应资源包,接口结构无需变更,客户端只需传入新的
sub_type 值即可。
批次异步规则
| 提交场景 | 执行方式 | 结果获取 |
|---|---|---|
| 多个 URL(>1 条,任意子类型) | 一律转批次异步:整批域名记录为单个批次任务(task_id),后台异步检测。微信条目入 UI 检测队列,QQ 条目入平台任务队列(服务端计划任务消费) |
轮询 查询批次结果接口 |
单个 URL 且 async=0(默认) |
同步等待:微信最多等 wait_timeout 秒(默认 6s,超时自动转队列);QQ 直接返回(<1s) |
响应 results 直接给出结果;超时转队列的条目带 task_id 轮询 |
单个 URL 且 async=1 |
强制异步入批次队列 | 轮询查询批次结果接口 |
注意:批次任务保留 24 小时(
expires_at),过期后任务记录自动清理,请在有效期内取走结果。
响应中的 auto_async=true 表示本次是被"批量自动转异步"规则转为异步的(区别于调用方显式传 async=1)。
接口地址
/api/domain_check_api.php
请求方式
POST请求参数
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| api_key | string必填 | 是 | API 密钥(唯一鉴权凭证) |
| sub_type | string必填 | 是 | 检测子类型:wechat(微信) / qq(QQ) / douyin(抖音) |
| urls | array必填 | 是 | 要检测的 URL 数组,支持批量;也接受单个 URL 字符串 |
| include_raw | bool可选 | 否 | 是否透传上游原始响应:传 true 时 results[].raw_response 才有值(用于调试);默认 false,此时 raw_response 为 null。判定文案 message 字段不受此参数影响,始终返回 |
| async | bool可选 | 否 | 是否强制异步:1/true 时所有条目直接入队列返回 task_id;默认 0。批量(>1 条)时无论是否传都自动异步 |
| wait_timeout | number可选 | 否 | 单条同步模式下的等待秒数(默认 6,最低 0.5),仅微信单条且未异步时有效;超时未出结果自动转队列 |
参数传递方式
参数可通过以下方式传递(优先级从高到低):
1. HTTP Header(如
2. JSON Body (Content-Type: application/json)
3. POST Form (Content-Type: application/x-www-form-urlencoded)
4. GET Query String
1. HTTP Header(如
api_key: your_api_key)2. JSON Body (Content-Type: application/json)
3. POST Form (Content-Type: application/x-www-form-urlencoded)
4. GET Query String
请求示例
// JSON 请求示例 — 微信批量检测(自动转批次异步)
{
"api_key": "your_api_key",
"sub_type": "wechat",
"urls": [
"https://www.baidu.com",
"https://www.example.com"
]
}
// cURL 示例 — 批量提交(返回 task_id 后轮询取结果)
curl -X POST /api/domain_check_api.php \
-H "api_key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"sub_type":"wechat","urls":["https://www.baidu.com","https://www.example.com"]}'
// 单条同步检测(QQ 直接出结果;微信最多等 wait_timeout 秒)
curl -X POST /api/domain_check_api.php \
-H "api_key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"sub_type":"qq","urls":["https://www.baidu.com"]}'
// 需要上游原始响应调试时,加 include_raw 参数
curl -X POST /api/domain_check_api.php \
-H "api_key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"sub_type":"wechat","urls":["https://www.baidu.com"],"include_raw":true,"wait_timeout":8}'
响应示例
成功响应(批量提交 → 自动转批次异步)
{
"code": 0,
"message": "success",
"data": {
"sub_type": "wechat",
"sub_type_name": "微信拦截检测",
"async": true,
"auto_async": true,
"task_id": "p_3_1761820800_a1b2c3",
"results": [
{
"url": "https://www.baidu.com",
"sub_type": "wechat",
"status": "async",
"message": "已提交 UI 检测队列,请通过 task_id 查询结果",
"raw_response": null,
"task_id": "p_3_1761820800_a1b2c3"
},
{
"url": "https://www.example.com",
"sub_type": "wechat",
"status": "async",
"message": "已提交 UI 检测队列,请通过 task_id 查询结果",
"raw_response": null,
"task_id": "p_3_1761820800_a1b2c3"
}
],
"request_count": 2,
"billed_count": 2,
"refund_count": 0,
"async_count": 2,
"remaining_credits": 45
}
}
成功响应(单条同步检测)
{
"code": 0,
"message": "success",
"data": {
"sub_type": "qq",
"sub_type_name": "QQ 拦截检测",
"async": false,
"auto_async": false,
"task_id": null,
"results": [
{
"url": "https://www.baidu.com",
"sub_type": "qq",
"status": "normal",
"message": "域名正常",
"raw_response": null
}
],
"request_count": 1,
"billed_count": 1,
"refund_count": 0,
"async_count": 0,
"remaining_credits": 97
}
}
成功响应(unknown 状态,自动退费)
{
"code": 0,
"message": "success",
"data": {
"sub_type": "qq",
"sub_type_name": "QQ 拦截检测",
"async": false,
"auto_async": false,
"task_id": null,
"results": [
{
"url": "https://example-timeout.com",
"sub_type": "qq",
"status": "unknown",
"message": "QQ 检测第三方接口请求失败: HTTP 0, curl=Operation timed out after 10000 milliseconds",
"raw_response": null
}
],
"request_count": 1,
"billed_count": 0,
"refund_count": 1,
"async_count": 0,
"remaining_credits": 98
}
}
错误响应(调用次数不足)
{
"code": 1004,
"message": "域名检查·QQ 调用次数不足,剩余 0 次,需要 2 次",
"data": null
}
响应字段说明
顶层结构
| 字段 | 类型 | 说明 |
|---|---|---|
code | int | 0=成功,非 0=错误(见错误码说明) |
message | string | 响应描述,成功时为 "success",失败时为具体错误信息 |
data | object|null | 成功时为业务数据,失败时为 null |
data 对象字段
| 字段 | 类型 | 说明 |
|---|---|---|
sub_type | string | 本次检测使用的子类型(wechat / qq) |
sub_type_name | string | 子类型中文名(如"QQ 拦截检测") |
async | bool | 本次是否有条目转入异步队列(async_count > 0) |
auto_async | bool | 是否因"批量自动转异步"规则转为异步(区别于显式传 async=1) |
task_id | string|null | 批次任务 ID,用于查询批次结果;纯同步且无入队条目时为 null |
results | array | 检测结果数组,每个元素对应一个请求的 URL |
request_count | int | 本次提交的 URL 数量(= results 数组长度) |
billed_count | int | 本次实际扣费的条数 |
refund_count | int | 本次检测失败已退费的条数(不扣费) |
async_count | int | 转入异步队列的条数 |
remaining_credits | int | 扣费后的剩余资源包次数(仅返回当前 sub_type 对应的资源包) |
results 数组元素字段
| 字段 | 类型 | 说明 |
|---|---|---|
url | string | 本次检测的原始 URL |
sub_type | string | 检测子类型(与顶层一致) |
status | string | 检测结果状态:normal / blocked / unknown / async(详见状态说明) |
message | string | 判定文案或状态描述(始终返回) |
raw_response | object|null | 上游原始响应透传。仅当请求携带 include_raw=true 时才有值,否则固定为 null。不同子类型结构不同 |
task_id | string | 所属批次任务 ID(本次生成了批次任务时每个条目都会带) |
结果状态说明
| status 值 | 含义 |
|---|---|
normal |
检测通过,域名未被该平台拦截 |
blocked |
检测判定为被该平台拦截 |
unknown |
无法检测(检测接口不可用、超时或平台未开放)。该条目自动退费,不扣次数 |
async |
条目已转入异步队列,结果请通过 task_id 轮询查询批次结果接口获取 |
可用性提醒:微信(
wechat)域名查询接口可能短期失效(上游凭证过期、平台风控调整等原因)。
若 results 数组元素的 status 字段返回 unknown,说明当前无法提供可靠结果,
对应条目不扣费(自动退费)。请等待服务恢复后重试,
或临时改用其他平台的接口保障查询连续性。
查询批次结果
批次任务(task_id)的整批结果通过本接口轮询获取。建议每 2~3 秒查询一次,
直到 task_state 变为 done。任务保留 24 小时。
/api/domain_check_status.php
请求方式
GET请求参数
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| task_id | string必填 | 是 | 提交接口返回的批次任务 ID |
| api_key | string必填 | 是 | API 密钥(仅可查询本账号创建的批次) |
请求示例
curl "/api/domain_check_status.php?task_id=p_3_1761820800_a1b2c3&api_key=your_api_key"
响应示例
{
"code": 0,
"message": "success",
"data": {
"task_id": "p_3_1761820800_a1b2c3",
"task_state": "partial",
"progress": { "done": 1, "total": 2 },
"sub_type": "wechat",
"sub_type_name": "微信拦截检测",
"results": [
{
"url": "https://www.baidu.com",
"sub_type": "wechat",
"status": "normal",
"message": "放行"
},
{
"url": "https://www.example.com",
"sub_type": "wechat",
"status": "async",
"message": "检测中,请稍后查询"
}
],
"billed_count": 2,
"refund_count": 0,
"remaining_credits": 45
}
}
响应字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
task_id | string | 批次任务 ID |
task_state | string | 批次整体状态:pending(待执行)/ running(执行中)/ partial(部分完成)/ done(全部完成) |
progress | object | 进度:done 已完成条数 / total 总条数 |
results | array | 各 URL 最新状态,字段同提交接口的 results 元素 |
billed_count | int | 已计费条数(异步任务随结算动态变化) |
refund_count | int | 已退费条数(检测失败/任务过期自动退费) |
remaining_credits | int | 当前资源包剩余次数 |
提示:结果条目出现
unknown 时表示该条检测失败,系统会自动退费并计入 refund_count,无需额外处理。
扣费规则
- 按子类型独立扣费:
wechat扣domain_check_wechat资源包;qq扣domain_check_qq资源包;douyin扣douyin资源包,互不干扰 - 按 URL 条数扣费:批量检测 5 个 URL 扣 5 次
- 检测前检查余额:资源包不足时整批拒绝,直接返回 1004 错误,不会先检测再扣费
- 同步完成正常扣;异步入队预扣(入队即扣,拿到结果后不再重复扣)
- 失败自动退费:检测失败(unknown)、任务过期的条目自动退回资源包,响应中体现为
billed_count(实扣)与refund_count(已退) - 响应包含剩余次数:
remaining_credits返回扣费后的剩余量
错误码说明
| 错误码 | 说明 |
|---|---|
| 0 | 成功 |
| 1001 | 缺少必要参数(如 api_key / sub_type / urls) |
| 1002 | 参数验证失败(如非法 URL 格式、不支持的子类型) |
| 1003 | API 密钥无效或用户名不存在 |
| 1004 | 权限不足或子类型 API 调用次数不足 |
| 1006 | 服务未开放(子类型已注册但尚未上线) |
| 5000 | 服务内部错误(检测器异常、网络超时等) |
调用示例
PHP 示例(批量提交 + 轮询取结果)
<?php
$apiKey = "your_api_key";
$base = "http://your-domain";
// 1. 批量提交(>1 条自动转批次异步)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$base/api/domain_check_api.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"api_key" => $apiKey,
"sub_type" => "wechat",
"urls" => ["https://www.baidu.com", "https://www.example.com"],
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$submit = json_decode(curl_exec($ch), true);
curl_close($ch);
if ($submit['code'] !== 0) {
exit("提交失败: [{$submit['code']}] {$submit['message']}\n");
}
$taskId = $submit['data']['task_id'];
// 2. 轮询批次结果(单条同步场景 task_id 为 null 时直接用 results)
if ($taskId) {
while (true) {
sleep(3);
$r = json_decode(file_get_contents(
"$base/api/domain_check_status.php?task_id=$taskId&api_key=$apiKey"
), true);
if ($r['code'] !== 0) exit("查询失败: {$r['message']}\n");
echo "进度: {$r['data']['progress']['done']}/{$r['data']['progress']['total']}\n";
if ($r['data']['task_state'] === 'done') {
$submit = $r;
break;
}
}
}
foreach ($submit['data']['results'] as $item) {
echo $item['url'] . " -> " . $item['status'] . " (" . $item['message'] . ")\n";
}
echo "剩余次数: " . $submit['data']['remaining_credits'] . "\n";
?>
Python 示例(批量提交 + 轮询取结果)
import requests, time
base = "http://your-domain"
api_key = "your_api_key"
# 1. 批量提交(>1 条自动转批次异步)
submit = requests.post(f"{base}/api/domain_check_api.php", json={
"api_key": api_key,
"sub_type": "wechat",
"urls": ["https://www.baidu.com", "https://www.example.com"],
}).json()
if submit["code"] != 0:
raise SystemExit(f"提交失败: [{submit['code']}] {submit['message']}")
task_id = submit["data"]["task_id"]
# 2. 轮询批次结果
if task_id:
while True:
time.sleep(3)
r = requests.get(f"{base}/api/domain_check_status.php",
params={"task_id": task_id, "api_key": api_key}).json()
p = r["data"]["progress"]
print(f"进度: {p['done']}/{p['total']}")
if r["data"]["task_state"] == "done":
submit = r
break
for item in submit["data"]["results"]:
print(f"{item['url']} -> {item['status']} ({item['message']})")
print(f"剩余次数: {submit['data']['remaining_credits']}")
JavaScript(前端)示例
const base = "http://your-domain";
const apiKey = "your_api_key";
// 1. 批量提交(>1 条自动转批次异步)
const submit = await (await fetch(`${base}/api/domain_check_api.php`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
api_key: apiKey,
sub_type: "wechat",
urls: ["https://www.baidu.com", "https://www.example.com"],
}),
})).json();
if (submit.code !== 0) throw new Error(`提交失败: ${submit.message}`);
// 2. 轮询批次结果
let final = submit;
const taskId = submit.data.task_id;
while (taskId && final.data.task_state !== "done") {
await new Promise(r => setTimeout(r, 3000));
final = await (await fetch(
`${base}/api/domain_check_status.php?task_id=${taskId}&api_key=${apiKey}`
)).json();
console.log("进度:", final.data.progress.done, "/", final.data.progress.total);
}
final.data.results.forEach(item => {
console.log(item.url, "->", item.status, item.message);
});
console.log("剩余次数:", final.data.remaining_credits);