Skip to main content
AI agents read the HTML your server sends. They run no scripts, so prices, reviews and specs a script draws never reach them, and they read the text inside an image only from its alt text. AI Rendering renders each page you publish as a person sees it, removes the scripts and writes the text of each image into its alt text. Your CDN downloads these copies and answers AI agents with them. People, search engines and every other request reach your site as before, and querying.ai is never on the path of a request to your site. GEO Score measures the gap: rendering.score is the share of a page a copy carries. Once your CDN sends the copy, the agents that get it read that much.

How it works

  1. Connect your site. You get a site key once. It can only read your site’s copies.
  2. Publish pages. Send a page URL. querying.ai renders it from your site’s country, keeps the copy, and renders the page again every refreshDays days (28 by default).
  3. Sync the copies. Every 10 minutes your CDN reads the copy list with the site key, downloads new copies and drops the ones no longer listed.
  4. Answer AI agents. When an AI agent sends a GET, your CDN answers with the stored copy. A page without a copy, an expired copy and any error go to your origin.

Connect a site

Keep the key: only this response has it, and your CDN sends it. POST /v1/ai-rendering/sites/{id}/key gives a new one and stops the old one at once. Change them later with PATCH /v1/ai-rendering/sites/{id}.

Publish a page

The page is being rendered:
A render takes about 30 seconds. Follow it with GET /v1/async/task/{taskId}, or read the page’s status from GET /v1/ai-rendering/sites/{id}:
  • ready: the copy is in your copy list. copy is its HTML file.
  • rendering: the first copy is being made.
  • failed: the first render failed. The page is rendered again at refreshAt.
  • expired: the copy expired and left the list until the next render.
A site holds up to 1,000 pages. Sending a published page again renders it now. A page is its path and query, without tracking parameters such as utm_* and gclid. DELETE /v1/ai-rendering/sites/{id}/pages/{pageId} takes a page down. To publish the copy a GEO Score made without rendering again, send its task id: { "taskId": "0b6c1f7e-…" }. It must be a completed GEO Score of your account, scored from the site’s country.

Set up your CDN

Save this as ai-rendering.mjs beside your CDN code. syncCopies brings a store in line with your copy list, and copyFor answers an AI agent’s GET from it:
The Worker keeps copies in Workers KV and syncs them every 10 minutes on a cron trigger. Each copy expires in KV with its file.
wrangler.toml:
cloudflare-worker.mjs:
On the Workers Free plan, KV takes 1,000 writes a day, so the first sync of a large site can take more than a day.
Check a published page as ChatGPT would open it, once the next sync has run. The copy carries X-Querying-Rendering: HIT:

The copy list

Your CDN reads GET https://api.querying.ai/v1/ai-rendering/copies with the site key in X-Querying-Site-Key:
It lists every published page whose copy has not expired. copy downloads without a key. renderedAt changes when the page is rendered again, so download a copy only when its renderedAt is new. Drop the stored copies of pages the list no longer has. The list and the downloads are free.

Agents

AGENTS in the module chooses who gets the copy, by a token anywhere in the User-Agent, case-insensitively.
  • Default: the agents a person sends to a page while asking a question (chatgpt-user, codex, claude-user, claude-code, perplexity-user, gemini-deep-research, duckassistbot, amzn-user, mistralai-user) and ChatGPT search’s crawler, oai-searchbot. ChatGPT search answers from the page its crawler keeps, which is what GEO Score’s score measures. Its index changes after OpenAI crawls the page again.
  • Add if you want: claude-searchbot and perplexitybot.
  • Leave out: training crawlers (GPTBot, ClaudeBot) and web search crawlers (Googlebot, Bingbot). Googlebot runs scripts itself.

Stay within search engine rules

Sending bots different content from people is cloaking. Google does not treat a page rendered for bots as cloaking as long as the content is similar (Dynamic rendering). OpenAI has published no cloaking policy, so hold the copy to Google’s rule:
  • The copy is the page a person’s browser drew. querying.ai removes scripts and adds only the text inside images, in their alt text, the place an image’s text belongs.
  • It goes out at the page’s own URL.
  • It stays current. querying.ai renders it again every refreshDays, and the module stops sending a copy when it expires.
  • If you edit a copy, only remove or correct: fix a misread character, drop a pop-up. Do not add claims, prices or links people do not see.

What the copy is

The copy is the HTML a person’s browser drew after the page was scrolled to the end: the text scripts loaded, each frame’s page in place, every script removed except structured data (JSON-LD), and the text of each large image added to its alt text. Links and image sources stay absolute, so the copy reads like the page. It is the page at its last render: a price or stock change reaches agents at the next render, at most refreshDays later, plus the time until your CDN syncs. Image text is copied as it was read, so a misread character goes out as read.

Billing

A render costs 5 credits, plus 5 for each image whose text is read and 2 for each image your account read in the last 90 days (the same file, read the same way), at most 12 images. Submitting holds 65 credits and completion charges what the render used. A failed render is not charged. A refresh is charged the same, to the site’s account, and an account without the credits waits an hour before the page is tried again. Connecting a site, publishing a GEO Score’s copy, the copy list and downloading copies are free. Your CDN sends the copies, so agent traffic costs nothing at querying.ai. See Credits and limits.

Errors

The endpoints are in the API reference.