Recipe prompt
Review the comparison scope
Accept a list of product or company URLs, or use Search to propose candidates. Confirm their identities and relevance before adding them to the comparison. A similar name or a search result alone does not establish that two products compete. Write down the comparison question, geography, and intended product variant. For a pricing comparison, collect both the displayed billing basis and any conditions such as annual commitment, seat minimums, usage tiers, promotions, or taxes.Collect a fixed set of facts
Use a server-side key from the Quickstart. Pick the request by how well you know the source page.
Both guides include TypeScript, Python, Ruby, Go, PHP, and cURL examples. See credits for request pricing.
For a known pricing page, describe the fields as CSS rules. The following body returns the page’s Markdown and a
plans list from one visit:
Scrape request body
parsed.data.plans is an array of objects with string values. A rule that matches nothing returns null for an item and [] for a list, so a missing price stays unknown. Convert price into amount and currency in your application and keep the original string. maxAgeMs: 0 forces a fresh capture, so the observation time is the response time. With the default cache window, subtract cache_metadata.age_ms instead. Store the final url, request_id, and the raw parsed.data with each row.
When the selectors are unknown or the fact needs interpretation, send a research task. Name the page in task so research starts there, and use placeholder values so an unstated field returns null:
Answers request body
task when the page lists several. Use ultra when the task spans several pages or asks for a comparison. Store sources, the original json_content values, key_metadata.credits_consumed, and the time the request completed. If you send timeoutOpts.behavior: "return-partial", keep the partial marker with the row and review it before accepting.
sources lists the pages and search results that contributed, not a citation per field. For a claim that needs an exact source, verify a supporting excerpt on the page and retain that URL with the field. Scrape with formats.markdown gives you the page text for that check. Record a blocked page or failed request as a failed attempt, not as a missing price.
Normalize without hiding commercial differences
Convert the raw result into a reviewed application model. Keep annual commitments and monthly billing in different groups, even when both pages display a monthly equivalent.comparison.ts
market and variant only after review. The grouping function is conservative: identical keys identify rows eligible for further comparison, not proof that their features or service levels are equivalent. Keep rows without a group visible as incomplete rather than ranking them as the cheapest offer.
If you convert currency, save the exchange-rate source, date, and original amount. If you normalize a package price, retain the package quantity and the conversion rule. A simple comparison can avoid these conversions and show the original prices with their stated basis.
Separate facts from interpretation
Render a table with the plan, observed price, commercial conditions, source link, observation time, and freshness state. Keep analytical conclusions in a separate section that cites the rows it uses.
A generated opinion should not be written back into sourced-fact fields. This workflow also does not supply SEO or GEO visibility metrics, ranking lift, or a validated competitor ranking; those require separate data and analysis.
Refresh and review changes
Use Monitors on the reviewed source pages, or schedule fresh Scrape requests withmaxAgeMs: 0. A detected change can queue a new observation for the affected row. Compare it with the previous snapshot before accepting changes to plan identity, currency, or billing basis.
Store attempts independently from accepted facts, as in the dataset workflow. A timeout must not erase the last known price or be described as a price removal.
Try two compatible offers, one annual-commitment offer, an unstated price, and a failed refresh. Check that only compatible rows share a group, every fact has a source and time, and no interpretation appears as a sourced fact.
Structured datasets
Persist observations and refresh records without duplicates.
Website change digests
Turn source changes into a reviewable research feed.