The change
What is implemented
Every engine runs asynchronously; there is no endpoint that blocks until an answer arrives.
Where behavior differs
1. Limits are per credential, per account and per key
1. Limits are per credential, per account and per key
There is no per-key requests-per-second limiter, but three limits apply:
- The edge allows 1,200 requests per minute per
Authorizationcredential and returns429above that. - Your plan caps how many tasks your account can have queued or processing at once. Over the cap, submit returns
429 PLAN_CONCURRENCY_LIMIT. - A key can carry a daily credit limit. Over it, submit returns
429 KEY_DAILY_CREDIT_LIMITuntil the next UTC midnight.
2. Credits are per engine, and polling reports them
2. Credits are per engine, and polling reports them
Each engine has its own price: for example 1 credit for ChatGPT and Perplexity, 1.25 for Gemini and Google AI Overviews. The engine catalog lists every price.Submit responses report
{ "creditsToCharge": 0, "creditsCharged": 0 }. Once a task is COMPLETED, polling and the webhook report the captured charge. Failed tasks are not charged.3. Some engine and region pairs are rejected at submit
3. Some engine and region pairs are rejected at submit
An engine and country with no route returns
422 REGION_UNSUPPORTED immediately, instead of accepting a task that will fail. Retrying the same pair does not help.A client that assumes every well-formed submission is accepted needs a branch for 422. See Regions and location.4. Unsupported include flags are ignored or rejected
4. Unsupported include flags are ignored or rejected
payload.include flags are not honored by every engine. An unsupported markdown, rawResponse or searchQueries flag is ignored. An unsupported html or analysis flag returns 422, and an unsupported citationAnalysis flag returns 400. Check the support matrix before you send them.5. Webhooks are signed
5. Webhooks are signed
Every webhook carries
querying-webhook-id, querying-webhook-timestamp and querying-webhook-signature headers. Your existing receiver keeps working if it ignores them, but you should verify them. See Webhooks.6. A failed task adds a top-level error string
6. A failed task adds a top-level error string
GET /v1/async/task/{id} on a FAILED task returns a top-level error field. It is a plain string, not the { code, message, timestamp } object used by request errors.body.error as a failed request will misread a failed task. Branch on task.status.Map engines to task types
GOOGLE returns a results-page envelope with the AI Overview in a nullable aioverview member. See Google AI Overviews.
Verify the cutover
Run your current integration and querying.ai in parallel for a while and diff the fields you consume, usuallyresponse.text, response.sources[] and response.markdown. A shadow comparison catches differences a schema check misses, such as a source list in a different order.