GGR Data
API documentation · v1.0.0

The same dataset, machine-readable.

Everything the terminal shows, available to your models over HTTP — with the unit, the period, the serving tier and the regulator document that produced it riding on every single row. Seven documented endpoints. No modelled numbers, no blended tiers; derived values are labelled as derived.

01Start here

ThingValue
Base URLhttps://api.ggrdata.com/v1
Interactive docsapi.ggrdata.com/v1/docs — public, no key needed
Machine contractGET /v1/openapi.json — public, OpenAPI 3.1.0
AuthAuthorization: Bearer ggr_live_…
VerbsRead-only GET, plus one POST for the gravity forecast
ErrorsRFC 7807 application/problem+json

Keys are issued with a subscription, not self-served. Access is arranged directly — there is no signup form and no public data endpoint. The docs page, the index and the console shell are the only keyless surfaces, and none of them returns data.

# 1. What can I query?  (the catalog is the coverage disclosure, machine-readable)
curl -H "Authorization: Bearer $GGR_API_KEY" https://api.ggrdata.com/v1/catalog

# 2. Pull a series (JSON, cursor-paged)
curl -H "Authorization: Bearer $GGR_API_KEY" \
  "https://api.ggrdata.com/v1/series?state=NJ&vertical=igaming&from=2025-01"

# 3. Same rows as CSV (next page rides the X-Next-Cursor response header)
curl -H "Authorization: Bearer $GGR_API_KEY" \
  "https://api.ggrdata.com/v1/series?state=NJ&vertical=igaming&format=csv" -o nj_igaming.csv

02The seven documented endpoints

This is the whole published contract — six reads and one forecast. The set is pinned by a contract test, so it cannot drift without the suite failing.

EndpointSummaryWhat it is for
GET /v1/catalog The queryable universe Every state × vertical × metric × grain × date range we serve, with its unit and currency. This is the coverage gate, made machine-readable — exactly what the product surfaces, nothing more.
GET /v1/series Observed series rows The core read. Filter by state, vertical, metric, segment type, segment and date window. JSON or CSV.
GET /v1/operators Operator rollups + parent mapping Skins and brands resolved to the operating company that owns them.
GET /v1/properties Canonical property registry The property list with geography and capacity summaries.
GET /v1/coverage Freshness per cell Frontier, cadence and known gaps per series — what is current, what is late, what is deliberately absent.
GET /v1/usage Your quota state Your own key's requests and rows consumed today, against its limits.
POST /v1/gravity/forecast Site revenue forecast (premium) The casino gravity model. Keyed and invite-only. See the model specification.

Every one of the seven requires a key. The published OpenAPI carries a single document-level security requirement and no operation opts out of it. An unauthenticated call returns 401 with WWW-Authenticate: Bearer — there is no anonymous tier and no sample data endpoint. The gravity forecast is documented publicly but is not open: access stays keyed and invite-only.

Two classes of forecast subject, and the counts are never added together. Seventeen states are calibrated: the model is fitted, or admitted on transfer, against the monthly property-level revenue their regulators publish. Six — California, Nevada, Arizona, Oregon, Colorado and Mississippi — are served as a position-method class, because none of the six publishes gaming revenue at property grain: California by statute (Business and Professions Code §19821 and the tribal-state compacts keep device counts and revenue confidential), Nevada because the Control Board reports win by area rather than by licensee, Arizona and Oregon because their tribal floors report devices and not win, Colorado because the Division of Gaming publishes adjusted gross proceeds by town, and Mississippi because the Gaming Commission publishes gross gaming revenue by region. A position-method response runs on parameters transferred from the Iowa fit and carries three fields the calibrated states do not: assumptions.calibration, which names the transfer, names that state’s own supply source by document and edition, and counts the competitor floors in your choice set by how their position counts were sourced (regulator census, operator statement, operator lower bound, square-footage derived, directory band); forecast.annual_gaming_revenue_usd.supply_sensitivity, two deterministic re-runs — directory-band competitors dropped, operator lower bounds raised to their caps — that widen the served P10–P90 until it contains both; and envelope, a published revenue-per-position rail. The rail differs by state and says which it is: California’s is the NIGC Sacramento region, flagged outside 0.5× to 2.0×; Nevada’s, Colorado’s and Mississippi’s are their own regulator’s trailing-twelve-month total for your pin’s own area — win by area, adjusted gross proceeds by town, gross gaming revenue by region — over that area’s positions, on the same two-sided test, and each names the quantity it actually read rather than borrowing another state’s word for it; Arizona and Oregon get the NIGC Phoenix and Portland regions, which each span four jurisdictions, so their figure is served as a ceiling and tested one-sided — a pin above it is flagged, a pin below it is not evidence of anything.

The supply sensitivity is not only a position-method field. It is a property of the FLOORS your pin is scored against, not of the state the pin fell in. A calibrated-state pin whose competitor set carries estimated position counts — operator lower bounds, operator approximations, directory bands, square-footage derivations or stale exacts — gets the same two deterministic re-runs and the same widened band, plus assumptions.competitor_supply_basis saying how many floors and in which direction the estimate biases the answer. Lower bounds understate competing supply, so they bias a new entrant’s forecast high.

Nevada is served as a locals market. A Las Vegas Strip pin returns a refusal, not a forecast: the Strip’s demand is visitors and this model allocates the trips of people who live within a drive, so the honest answer is that it is the wrong instrument. Henderson, Summerlin, North Las Vegas and the Boulder Strip are served. Nevada, Colorado and Mississippi responses also carry market_check — the model’s own sum over your pin’s published area beside the total the regulator published for it, and the ratio between them. Nothing in the forecast is fitted to that ratio; when the check cannot be computed the field is null with a stated reason rather than absent, and the reason distinguishes a deployment’s own database permissions from a gap in what the regulator published — we do not blame a regulator for something our own role did. Everything a calibrated response carries, a position-method response also carries. The model specification sets out each state’s supply source and the California supply ladder.

03What a row carries

API consumers pipe rows straight into models, so a silently dropped unit or a missing provenance link is worse here than anywhere in the UI. Every row carries the same twelve fields:

state · vertical · metric · grain · period_start · period_end
segment · segment_type · value · unit · source_url · as_of
  • value + unit — nothing is silently rescaled. usd_mm is millions of US dollars; count is physical units. International rows stay in native currency — we never fabricate an FX rate.
  • segment_type — the serving tier, and each market feed serves exactly one, never blended: state_total, property, operator, brand, property_provider, region, location_type.
  • source_url + as_of — the regulator document the row came from, and when we ingested it. Restatements happen upstream; as_of is how you tell.

The catalog is the reference. Which states, verticals, metrics, units and grains exist is read from /v1/catalog, never hardcoded in your client. It is derived from the same configuration that gates the dashboard, and a drift between the two fails the test suite.

04Paging, quotas and limits

Paging

Cursor-paged. Default 1,000 rows per page, maximum 10,000. In CSV mode the next cursor rides the X-Next-Cursor response header.

Quotas

Quotas are set per key, not per plan tier, and your key reports its own: GET /v1/usage returns your limits, today's requests, rows consumed, rows remaining and the seconds until reset. The daily row counter resets at UTC midnight and the cap is firm rather than soft — a grant clamps to what remains.

ControlBehaviour
Requests / minuteRolling 60-second window, per key. Exceeded → 429 with Retry-After.
Rows / dayReserved before serving, resets at UTC midnight. Exceeded → 429, and the message names your cap.
Standard issued key60 requests/min · 500,000 rows/day
Trial keyManually issued, expires after 7 days

Errors

StatusMeaning
400Unknown combination — the error names the catalog so you can self-serve the fix (/series)
401Missing or unknown API key
403Key revoked, or trial expired
429Rate or row quota exceeded — Retry-After is set; check GET /v1/usage

05Coverage, honestly labelled

The API inherits the product's disclosure rules rather than smoothing them over for machine consumption:

  • Primary source or blank. Where a regulator does not publish, the market feed is absent from the catalog. Nothing is interpolated to fill a hole.
  • Native currency, never converted. International rows serve in the regulator's own currency. No FX is applied anywhere in the serving path.
  • One serving tier per market feed, never blended. A market feed that serves property-level rows does not also serve a state total under the same key — you always know which grain you have.
  • Definitions are not summed. Different jurisdictions measure different things; the catalog carries each market feed's metric and unit so totals are yours to construct deliberately, not ours to imply.
  • /v1/coverage sells the gaps. Freshness, cadence and known holes are a first-class endpoint, not a footnote.

Full jurisdiction-by-jurisdiction coverage — US states, distributed/route gaming, tribal and international — is on the coverage section of the home page.

06Access

Keys are issued directly, against a subscription — there is no self-serve signup while coverage is being verified jurisdiction by jurisdiction. Pricing is on the pricing page.

access@ggrdata.com — tell us what you want to pull and we will tell you honestly whether we cover it.

browse the live contract at api.ggrdata.com/v1/docs · no key required to read the docs

Get started

Tell us what you want to pull.

Keys are issued directly. Tell us who you are and which series you need, and we will tell you honestly whether we cover them.

Request access