Grail

Changelog

What shipped.

Dated, factual, and limited to things that actually deployed. Specifics beat adjectives.

Faster, more reliable answers — and a cleaner web app

  • —Fixed a cache bug where a transient thin result could be served as a "complete" answer for 15 minutes — a query now never shows fewer sales than actually exist.
  • —Acquisition latency: median cold query ~4s (was ~20-30s); sustained 30/30 reliability with zero blocks.
  • —Redesigned the web app as a cleaner market-data workspace — same workflows, sharper surface.
  • —Search-engine foundations: structured data (Organization, WebSite, Breadcrumbs) and proper crawl hygiene across the public pages.

Marketplaces, batch, and account controls

  • —All 8 eBay marketplaces wired end-to-end — per-site URL, cookie domain, locale, and correct currency on every row.
  • —Async batch: POST /v1/scrape/batch queues up to 100 keywords; poll the job for results.
  • —Bulk filters now match single search (condition, aspect filter).
  • —Dashboard: API key rotate + revoke, six-month usage history, and a working shipping-rates tool.

Relevance that generalizes

  • —Category-agnostic relevance cleaning — any product keyword, not just cards.
  • —Card-identity matching is auto-gated: it only engages when the query looks like a card.
  • —Shipping rates API: observed seller shipping + a clearly labelled estimate.
  • —MCP connector (search_sold, card_research, shipping_rates, usage).

Owned acquisition + cache-first serving

  • —Owned authenticated session fleet with rotation-on-block and pacing.
  • —Cache-first serving path — reads can be answered from the corpus at ~$0.
  • —Persistence seam (SQLAlchemy + Alembic): SQLite in dev, managed Postgres in prod.