
Now supporting mainland China on ChatGPT, Gemini and Google
Set country to CN or HK on CHATGPT, GEMINI and GOOGLE tasks to get the answers users in mainland China and Hong Kong see.

Send a prompt to any supported AI engine with one request and receive the answer as structured JSON, by webhook or by polling.
POST /v1/async/task, for every engine. Pick the engine with taskType and the market with country.id, status and timestamps around an engine-specific response.GET /v1/async/task/{id} whenever you are ready.idempotencyKey: sending the same key again returns the task you already created.AI engines take seconds to minutes to answer, so every request becomes a durable task. A task moves from QUEUED to PROCESSING and ends as COMPLETED with the answer or FAILED with the reason. A temporary engine error sends the task back to the queue for another attempt, so short hiccups are retried before they ever reach you.
Add webhook.url and we post the finished task to your server, with up to five attempts over about 30 minutes. Finished tasks also stay available for polling for 24 hours, so a webhook and a poll together cover every result.
Send the request with your API key in the Authorization header.
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"
}'taskTypestringRequiredCHATGPT or GOOGLE.payloadobjectRequiredprompt or query, plus country and the engine’s options.webhook.urlstringidempotencyKeystringThe call answers at once with the task in QUEUED. credits stays at 0 until the task finishes, and idempotencyKey comes back as you sent it.
{
"success": true,
"task": {
"id": "…",
"taskType": "CHATGPT",
"status": "QUEUED",
"priority": 1,
"createdAt": "…",
"idempotencyKey": "laptop-cafes-us-0001"
},
"credits": { "creditsToCharge": 0, "creditsCharged": 0 }
}Read the task with GET /v1/async/task/{id} every few seconds until status is COMPLETED or FAILED. Results stay available for 24 hours after a task finishes.
curl https://api.querying.ai/v1/async/task/$TASK_ID \
-H "Authorization: Bearer $QUERYING_API_KEY"A finished task carries the charged credits and the engine’s response. This one is real, trimmed for length.
{
"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.statusstringQUEUED, PROCESSING, then COMPLETED with the answer or FAILED with error.credits.creditsChargedintegerWith webhook.url, the finished task arrives at your server as a POST with the same task, credits and response that polling returns. A failed task arrives the same way, with response.error and 0 credits charged. Three headers sign every delivery:
querying-webhook-idstringquerying-webhook-timestampstringquerying-webhook-signaturestringv1, and a base64 HMAC-SHA256 of {id}.{timestamp}.{body}, keyed with the SHA-256 digest of your API key.Check the signature on the raw body, before parsing it, and accept the delivery when it matches:
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)Answer with a 2xx status within 30 seconds. Otherwise the delivery comes again after 2, 4, 8 and 16 minutes, five attempts in all, each with the same querying-webhook-id.
A refused request answers at once with success set to false and an error holding code, message and, for field errors, details. It stays out of the queue and costs 0 credits.
VALIDATION_ERRORHTTP 400details names the field.MISSING_API_KEYHTTP 401Authorization header is missing, or its key is unknown, expired or revoked.INSUFFICIENT_CREDITSHTTP 402KEY_SCOPE_DENIEDHTTP 403RESOURCE_ALREADY_EXISTSHTTP 409idempotencyKey already exists on your account, so the send stays one task. In a batch, the item counts as a success.PAYLOAD_TOO_LARGEHTTP 413REGION_UNSUPPORTEDHTTP 422country is outside the engine’s list of countries. Sending again gives the same answer, so details.retryable is false.PLAN_CONCURRENCY_LIMITHTTP 429Retry-After seconds.KEY_DAILY_CREDIT_LIMITHTTP 429Retry-After runs until the next midnight UTC.QUEUE_BACKPRESSUREHTTP 429Retry-After seconds.Each engine has its own credit price, and a task is charged when it completes. A failed task releases the credits it reserved.

Set country to CN or HK on CHATGPT, GEMINI and GOOGLE tasks to get the answers users in mainland China and Hong Kong see.

Set payload.location on GOOGLE, AIMODE and GOOGLE_SERP tasks to get the AI Overview, AI Mode answer and search results a user at that place sees.
Get new product updates in your inbox.