Geck InspectGeck Inspect Market
Developer

Public API

Read-only HTTP endpoints under geck-data.vercel.app. All return JSON unless noted. Rate limit: courteous use; we may throttle at the edge if a single IP hammers an endpoint.

Contract guarantees

What we promise about the endpoints below.

  • Adding fields is non-breaking. Consumers should ignore unknown keys.
  • Removing or renaming a field is a versioned change. We will add a v2 path before deprecating v1.
  • Cresteds only on every endpoint. Other species are filtered out at the source view (see migration 0010).
  • CORS open to any origin for the GET endpoints. POST endpoints require Bearer auth and are not in scope here.
  • Members only (since 13 Oct 2026): endpoints that return single listings or sellers. Send Authorization: Bearer <Supabase access token> for a signed-in account, or call them from a signed-in browser. Without it they answer 401. Aggregate prices stay public.

GET/data/market.json

Members only. Every recent priced crested listing with its seller, plus the breeder list.

Heavy payload (megabytes). Cache at the consumer; the snapshot updates roughly hourly.

GET/api/market/fair-price

Price estimate for a trait set. Either supply a canonical combo id or a comma-separated trait list. Returns p10/p25/p50/p75/p90 plus adjustment-factor multipliers for age, sex, weight, proven-breeder status.

ParamTypeNote
combostringCanonical combo id (lw-cap, axa-pin, etc). Either this or `traits`.
traitsstringComma-separated traits. Matched into a combo or used directly.
ageenumhatchling, juvenile, subadult, adult, proven_breeder, unknown
sexenummale, female, unknown
weightnumberGrams
provenbooltrue / false
recent_salesintIf > 0, include up to N recent comparable sales (price, date and days to sell; no listing, seller or link).

Documented at /docs/geck-inspect-integration.md; the contract is shared with the classifier app.

GET/api/market/temperature

Composite market temperature plus a weekly time series of listing volume, sold count, sell-through rate, median sold price and median days to sell. `score` is a number from 0 to 100 only when the data supports one: it is null whenever `status` is 'unavailable', which is the current state, and the response then carries `unavailable_reason` and a plain-English `unavailable_detail` naming the gate that failed. A client that reads `score` without checking `status` will treat a refusal to score as a zero.

Backs the floating temperature card on /market. The gates are, in order: no weeks in the view, no captured sale in the trailing window, too few captured sales, too few complete weeks to rank against, a baseline with no spread, and a current week not yet fully observed. Sales inferred from listings that stopped appearing are deliberately not counted toward the demand side.

GET/api/market/arbitrage

Members only. Legacy pHash pair candidates (MorphMarket image vs cross-platform image). Separate from the dashboard source axis.

Empty until a pHash worker has populated phash columns. Best-effort: pHash collisions exist; treat each row as a heads-up rather than a confirmation. Combo-level KR vs US asks live at /api/market/source-arbitrage instead.

GET/api/market/source-arbitrage

Combo-level ask vs ask: Feedle Air USD (Korea scheduled import) vs MorphMarket live listings. Matched by HIGH_VALUE_COMBOS on traits, not pHash. Hides rows with n<3 on either side. Altitude Exotics, TikisGeckos, and Feedle KRW are not in this table.

Ask vs ask, not sold. MorphMarket uses current_status=live; last_seen_at is not a 48h gate because catalogue leftovers still dominate that column. Feedle Air is not a MorphMarket click-buy.

GET/api/market/traits

Trait vocabulary observed in the database, with per-trait listing counts.

Used by the trait picker on /whats-it-worth.

GET/api/market/snapshot.csv

Members only. CSV mirror of /data/market.json, one row per listing.

ParamTypeNote
window_daysintDefaults to 90.

Returns Content-Type: text/csv. Suitable for sheets / Excel.

GET/api/stats

Lightweight global counts for the homepage hero and the /status route.

Example
/api/stats

Returns total listings, sellers, sold, etc.

GET/api/status.json

Per-stream ingest health snapshot. Reports lifetime + 7d counts and freshness per event stream.

Mirrors the /status page contents.

Not in scope here

The following endpoints exist but require auth and are not considered public. Treat them as implementation details that may change without notice:

  • /api/ingest - extension event firehose, Bearer auth.
  • /api/upload - dashboard drop-zone, session auth.
  • /api/alerts/* - alert lifecycle, owner-scoped.
  • /api/training/* - ML pipeline, admin only.
  • /api/trigger-scrape - admin only.

Found a bug or want a new endpoint? Open an issue on github.com/tennysonmilesperhour/geck-data.