FAQ
Frequently asked questions about the platform
Which AI surfaces can I capture today, and which are on the roadmap?
Live in v1: ChatGPT, Perplexity, Gemini, Copilot, Google AI Overview, Google AI Mode, Google Search, and Google News, plus Claude. ChatGPT and Perplexity capture browser-first using real consumer-UI sessions (guest today); Gemini, Copilot and the Google surfaces render the consumer UI from guest sessions (with a managed vendor backup lane as an explicit fallback if a login wall appears). Claude is live via the official Anthropic API through the OpenRouter gateway; live browser capture for Claude is on the roadmap. The remaining login-walled surfaces (Meta AI, DeepSeek, Amazon Rufus, and Grok) are phase-2 and labeled as such everywhere. We never present a phase-2 surface as live.
What is the Envelope, and what does a response actually contain?
Every capture, regardless of surface, returns one canonical, versioned Envelope. It carries the answer (text, markdown, and structured blocks), with any sources and citations the surface showed preserved inline in the answer. It also carries lane-free provenance (login state, requested vs effective region, the observed model label with its confidence, whether web search fired, and whether the surface was present at all) alongside structured evidence — the citations the surface showed and the search queries it fanned out (brand mentions are forthcoming). For consumer-UI captures you can opt into a proof-of-page HTML snapshot with include.html, referenced by URL in the Envelope. The same parser reads every provider, so you integrate one contract instead of N.
Is the API synchronous or asynchronous?
Both, on one endpoint, and the default follows your request. A single surface and region with no webhook runs synchronously: POST /v1/search blocks briefly and returns the Envelope inline in one 200 (bounded server-side; if the wait runs long it degrades gracefully to a 202 you can poll). The moment you ask for more than one child (multiple surfaces or regions) or attach a webhook, the durable async path takes over: a 202 with a parent jobId and one child job per (surface × region), which you poll at GET /v1/jobs/:id or receive as an HMAC-signed webhook per child. Force either way explicitly with ?mode=sync (or the Prefer: wait header) or ?mode=async. Same request body, no sync surcharge.
Why browser-first instead of calling the model APIs?
A vendor model API returns generated text, not what a real person sees in the product. The consumer products run their own retrieval, ranking, ads, shopping, and UI on top of a model, and that surface is what your customers and competitors actually look at. By default we capture through real stealth-browser sessions (Patchright-driven Bright Data Scraping Browser). Those are real consumer-UI sessions, guest today, with logged-in capture for login-walled surfaces on the roadmap, so you get what a person actually sees, not a sanitized model response.
Why is Claude served via the official API and not the browser?
Claude requires a signed-in session to reach its consumer UI, and that capture path isn't live yet, so today Claude is served through the official Anthropic API via the OpenRouter gateway, which returns fast. Live browser capture of Claude is on the roadmap, with no integration change on your side when it ships.
How long do you keep results and artifacts?
The parsed Envelope — answer, provenance, and evidence — is the durable record we keep for every capture. For consumer-UI (browser) surfaces you can additionally opt into a proof-of-page HTML snapshot by setting include.html (or ?include=html): the Envelope then carries a top-level html URL you fetch back at GET /v1/artifacts/:key, so you can show exactly what the page looked like at capture time. It is opt-in, not an always-on raw blob, and official-API surfaces (like Claude) have no page to snapshot. Either way the structured result stays reproducible long after the live page has changed.
Do you meter credits, and how does accounting work?
Accounting happens at the child-job level: each (surface, region) pair is materialized as one child and counted exactly once, never blended. A search targeting 2 surfaces in 2 regions is 4 counted units, not 1. Read your ledger at GET /v1/usage, grouped by surface and region. Replaying an Idempotency-Key returns the original job and burns no new unit. Charges are per successful capture, so narrowing to a city or reading a job inline rather than polling doesn't change what it costs.
Is there a free tier to try it?
Yes. New accounts start with 500 free credits and a self-serve API key, no sales call. That is enough to run real fan-outs across multiple surfaces and regions and see the actual Envelope and its provenance before you commit.
Can I target a specific country or city?
Yes. Pass a regions array of { country, state?, city?, language?, location? } objects; each region fans out into its own child job so one request captures the same prompt across many markets. country is the only required field, an ISO 3166-1 alpha-2 code (US, GB, DE, not USA or UK); state is an optional sub-national code or name (e.g. NY), city an optional city name, and language an optional BCP-47 hint — country/state/city resolve to a city-level residential exit (all best-effort and surface-dependent). For precise local rank tracking, the Google surfaces also take location, a Google Ads geotarget canonical name (e.g. "Buffalo,New York,United States") applied as a uule to pin the answer to one of ~100k named localities, independent of the exit IP. We record both the region and locality you requested and the ones the surface effectively served, so you can verify geo fidelity instead of trusting it. Omitting regions defaults to a single untargeted (global) capture.
What happens if a surface returns no answer?
We tell you rather than guessing. The child still reaches a terminal completed status, provenance.surfacePresent is false, and warnings includes "surface_absent". The verbatim upstream payload is still kept in R2, so you can see exactly what came back. We report the absence, we never fabricate an answer to fill it.
How are webhooks signed and verified?
Attach webhook: { url, secret } to any search and we POST each child's terminal result, one delivery per (surface × region), with type job.completed, job.partial, or job.failed and the exact same Envelope in result. Each delivery is signed over `${timestamp}.${body}`, not the body alone: X-AISearch-Signature is the lowercase-hex HMAC-SHA256 of that string keyed by your secret, and X-AISearch-Timestamp carries the unix-seconds timestamp. To verify, capture the raw bytes, reject a timestamp skewed more than ~5 minutes, recompute the HMAC over `${timestamp}.${rawBody}`, and compare in constant time before trusting a delivery. The url is SSRF-guarded (public http(s) only, re-checked before every send), retries replay the same signed body, so dedupe on the event id.
How do rate limits and concurrency work?
Two independent budgets, both per key: a submit-rate limit (X-RateLimit-* headers, flat 1,000 req/s on every plan) governs how fast you POST, and a sync concurrency ceiling (X-Concurrency-Limit / X-Concurrency-Running) governs how many synchronous captures run at once — that ceiling scales with your plan, from 1 on Free up to 135 on Enterprise. Async submits admit into a separate queue instead (X-Concurrency-Queued) and drain as capacity frees up. Exceeding the submit rate returns 429 RATE_LIMIT_EXCEEDED with Retry-After; a full sync budget returns 429 CONCURRENCY_LIMIT_EXCEEDED; a full async queue returns 429 QUEUE_CAPACITY_EXCEEDED. Throttle on X-Concurrency-Running/X-Concurrency-Queued, not just request rate. A 4-surface × 2-region async request is 8 children, i.e. 8 queue admissions. There is no retention clock to race: limits govern throughput, never how long a finished result survives.
Is there an official SDK, and how do I get started?
Not yet, but the docs ship copy-paste Node and Python clients for the full submit → poll → read round-trip, plus a signed-webhook receiver. Base URL is https://api.aisearchapi.dev; authenticate with Authorization: Bearer <API_KEY>. Grab a key, spend your 500 free credits on a real fan-out, and read the structured results back.
If you have any questions, please contact us
Contact us