Grail

API reference

A compact map of the surface. All responses are JSON; all authenticated endpoints take a Bearer key.

Comps

  • GET /v1/scrape

    Sold (or active) listings for a keyword, cleaned and summarized.

  • GET /v1/sold

    Alias for a sold-only scrape.

  • POST /v1/scrape/bulk

    Up to 25 queries in one call, each cache-first and metered once.

  • POST /v1/scrape/jobs

    Enqueue bulk/bursty work; returns 202 + job_id.

  • GET /v1/scrape/jobs/{job_id}

    Poll an async job.

Intelligence

  • GET /api/research

    Grade-by-grade single-card research (raw/PSA 9/PSA 10), honest-by-construction.

  • POST /v1/shipping/rates

    Observed shipping for a keyword + a labelled landed-cost estimate.

Account

  • GET /v1/status

    Service status, limits and capabilities.

  • GET /v1/usage

    Current key usage, plan, quotas and reset window.

  • GET /v1/ledger/stats

    Corpus size and cache stats.

  • GET /api/account/keys

    List your API keys (dashboard; session-authenticated).

  • POST /api/account/keys

    Create an API key.

  • POST /api/account/keys/{id}/rotate

    Rotate a key.

  • POST /api/account/keys/{id}/revoke

    Revoke a key immediately.

Machine-readable schema

The full OpenAPI 3.1 document is served at /openapi.json — use it to generate typed clients (openapi-generator, orval, etc.). A live reference UI is not published yet; the schema is the source of truth.

Response headers

Every metered /v1 response tells you exactly where you stand — read these instead of guessing:

HeaderMeaning
X-Usage-LimitMonthly request allowance on the current plan.
X-Usage-RemainingRequests left this calendar month.
X-RateLimit-LimitAllowed requests per minute (or “unlimited”).
X-RateLimit-RemainingRequests left in the current minute window.
X-RateLimit-ResetSeconds until the per-minute window resets.
X-CacheWhether this call was served from corpus or went live.

Pagination

A standard call returns up to 240 cleaned rows in one response — enough for most comps. When you need the deep tail, use Max Mode (async paging) instead of looping page after page.

Errors & retries

Stable error codes and the retry policy live on the errors page. The rule: retry 5xx with backoff + jitter; never retry 400 or 401.

Full parameter list for /v1/scrape is on the overview page.