更新日志新功能

一个 API 连接所有 AI 回答引擎

API
POST /v1/async/task 请求、返回的排队任务以及通过 webhook 送达的完成任务

一次请求即可向任意支持的 AI 引擎提问,并通过 webhook 或轮询以结构化 JSON 获取回答。

获得的结果

  • 所有引擎共用一个端点 POST /v1/async/task。用 taskType 选择引擎,用 country 选择市场。
  • 每个引擎的 response 各有不同,外层格式始终一致:任务的 id、status 和时间戳都在固定位置。
  • 按你的方式获取结果:任务完成的瞬间通过 webhook 推送到你的服务器,或在需要时用 GET /v1/async/task/{id} 查询。
  • 用 idempotencyKey 安全重试:用同一个键再次提交,会返回已经创建的任务。

工作原理

AI 引擎回答需要几秒到几分钟,因此每个请求都会成为一个持久保存的任务。任务从 QUEUED 进入 PROCESSING,最终以带回答的 COMPLETED 或带原因的 FAILED 结束。引擎出现临时错误时,任务会回到队列重新尝试,短暂的故障在到达你之前就已处理。

提供 webhook.url 后,我们会把完成的任务推送到你的服务器,在约 30 分钟内最多发送五次。完成的任务还可在 24 小时内通过轮询获取,webhook 与轮询配合使用即可可靠地拿到每一个结果。

应用场景

  • 在自己的后端按任意频率检查品牌曝光。
  • 把同一个问题发给多个引擎,并排比较回答。
  • 耗时的任务也很简单:提交后继续做别的事,结果由 webhook 送回。

发送请求

在 Authorization 请求头中带上 API 密钥发送请求。

curl -X POST https://api.querying.ai/v1/async/task \
  -H "Authorization: Bearer $QUERYING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "taskType": "CHATGPT",
    "payload": {
      "prompt": "Best coffee shops near me for working on a laptop",
      "country": "US"
    },
    "webhook": { "url": "https://your-server.example.com/hooks/querying" },
    "idempotencyKey": "laptop-cafes-us-0001"
  }'

请求字段

taskTypestring必填
要运行的引擎,例如 CHATGPT 或 GOOGLE。
payloadobject必填
引擎输入:prompt 或 query,以及 country 和引擎专属选项。
webhook.urlstring
你服务器上的 HTTPS 地址。任务完成后立即把结果推送到这里。
idempotencyKeystring
你为请求设定的 ID。每个键在账户内对应一个任务,因此重试发送后仍是同一个任务。

响应

调用会立即返回 QUEUED 状态的任务。任务结束前 credits 为 0,idempotencyKey 按发送的值原样返回。

JSON
{
  "success": true,
  "task": {
    "id": "…",
    "taskType": "CHATGPT",
    "status": "QUEUED",
    "priority": 1,
    "createdAt": "…",
    "idempotencyKey": "laptop-cafes-us-0001"
  },
  "credits": { "creditsToCharge": 0, "creditsCharged": 0 }
}

获取结果

每隔几秒用 GET /v1/async/task/{id} 读取任务,直到 status 变为 COMPLETED 或 FAILED。任务结束后,结果保留 24 小时。

curl https://api.querying.ai/v1/async/task/$TASK_ID \
  -H "Authorization: Bearer $QUERYING_API_KEY"

完成的任务包含已扣除的 credits 和引擎的 response。以下是一个真实任务,已截取部分内容。

JSON
{
  "success": true,
  "task": {
    "id": "e5aba119-a26e-4f82-a965-35c9234a428b",
    "taskType": "CHATGPT",
    "status": "COMPLETED",
    "createdAt": "2026-10-02T15:41:03.858Z"
  },
  "credits": { "creditsToCharge": 2, "creditsCharged": 2 },
  "response": {
    "text": "Here are several **nearby cafés that look particularly suitable for laptop work**, based on current local listings and work-friendly details:\n…",
    "sources": [
      {
        "position": 1,
        "url": "https://awifiplace.com/cities/new-york",
        "label": "Best Coffee Shops to Work in New York (2026) | 103 Cafes with WiFi"
      }
    ],
    "searchQueries": [
      "best coffee shops for laptop work near me wifi outlets"
    ]
  }
}
task.statusstring
依次为 QUEUED、PROCESSING,最终为附带回答的 COMPLETED 或附带 error 的 FAILED。
credits.creditsChargedinteger
已完成任务扣除的积分。失败的任务为 0。

Webhook

设置 webhook.url 后,完成的任务会以 POST 送达你的服务器,内容与轮询得到的 task、credits 和 response 相同。失败的任务也以同样方式送达,带有 response.error,扣除 0 积分。每次投递都带有三个签名请求头:

querying-webhook-idstring
任务 ID。每次投递至少送达一次,用它去掉重复投递。
querying-webhook-timestampstring
签名时间(Unix 秒)。接受最近 5 分钟内签名的投递。
querying-webhook-signaturestring
v1, 加上 {id}.{timestamp}.{body} 的 base64 HMAC-SHA256,密钥为 API 密钥的 SHA-256 摘要。

在解析之前,用原始请求体校验签名,匹配后再接受这次投递:

import base64
import hashlib
import hmac
import os
import time


def verify_webhook(headers, body: bytes) -> bool:
    """body is the raw request body, before json.loads."""
    task_id = headers["querying-webhook-id"]
    timestamp = headers["querying-webhook-timestamp"]
    key = hashlib.sha256(os.environ["QUERYING_API_KEY"].encode()).digest()
    signed = f"{task_id}.{timestamp}.".encode() + body
    digest = hmac.new(key, signed, hashlib.sha256).digest()
    expected = "v1," + base64.b64encode(digest).decode()
    given = headers.get("querying-webhook-signature", "")
    fresh = abs(time.time() - int(timestamp)) <= 300
    return fresh and hmac.compare_digest(expected, given)

请在 30 秒内返回 2xx 状态。其他响应或超过 30 秒时,会在 2、4、8、16 分钟后重新投递,共尝试五次,每次都带相同的 querying-webhook-id。

错误

被拒绝的请求会立即返回,success 为 false,error 中含 code、message,字段错误时还有 details。请求停在队列之外,消耗 0 积分。

VALIDATION_ERRORHTTP 400
缺少字段或取值超出范围。details 会指明该字段。
MISSING_API_KEYHTTP 401
缺少 Authorization 请求头,或密钥有误、已过期或已吊销。
INSUFFICIENT_CREDITSHTTP 402
余额低于任务价格。充值积分或升级套餐后再发送。
KEY_SCOPE_DENIEDHTTP 403
该引擎在密钥的“允许的引擎”之外。换用其他密钥,或在“管理密钥”中添加该引擎。
RESOURCE_ALREADY_EXISTSHTTP 409
账户中已有使用该 idempotencyKey 的任务,因此仍只保留一个任务。在批量请求中,该项按成功处理。
PAYLOAD_TOO_LARGEHTTP 413
请求体超过 1 MiB,批量请求超过 8 MiB。
REGION_UNSUPPORTEDHTTP 422
country 在该引擎支持的国家之外。重新发送结果相同,因此 details.retryable 为 false。
PLAN_CONCURRENCY_LIMITHTTP 429
排队和运行中的任务达到套餐上限:免费套餐 2 个,Basic 10 个,Pro 25 个,Scale 50 个,Max 100 个。请在 Retry-After 秒后重新发送。
KEY_DAILY_CREDIT_LIMITHTTP 429
该密钥已用完每日积分上限。Retry-After 持续到下一个 UTC 零点。
QUEUE_BACKPRESSUREHTTP 429
该引擎的队列暂时已满。请在 Retry-After 秒后重新发送。

价格

每个引擎都有各自的积分价格,任务完成时扣费。失败的任务会退还预留的积分。

更多更新

接收最新消息

通过邮件接收产品更新。

RSS 订阅