Marketplace API

Every game with verified revenue, as JSON. No key, no sign-up, no rate-limit paperwork — it is the same data the pages show, and it is more useful to us in your tool than locked in ours.

Two endpoints

GET/api/market/v1/listings

Every verified game, filterable and paged.

GET/api/market/v1/listings/{slug}

One game, plus up to a year of daily revenue history. Add ?history=0 to skip the series.

Responses are CORS-open (Access-Control-Allow-Origin: *) and cached for five minutes, so you can call them straight from a browser.

Query parameters

genre
One of puzzle, action, arcade, casual, strategy, rpg, simulation, sports, idle, multiplayer, educational, other.
platform
One of web, ios, android, steam, console, roblox, discord, telegram, unity_asset, other.
for_sale
`true` for games actually on sale, `false` for directory-only profiles. Omit for both.
min_mrr
Minimum MRR in **cents**, matching `mrr_cents`.
max_price
Maximum asking price in whole USD.
sort
`mrr` (default), `growth` or `newest`.
limit
1–100, default 50.
offset
For paging; compare `offset + data.length` against `total`.

Money and percentages

Anything read from a payment provider is in whole cents and named *_cents. Anything a human typed — the asking price — is in whole USD. Rates are in basis points: growth_bps: 1250 is +12.5%. The field names carry the unit so nothing depends on reading this page.

net_churn_bps is net logo churn — new subscribers offset cancellations, so a growing game can read 0. It is computed from our own snapshots 30 days apart, not supplied by the provider.

Example

GET /api/market/v1/listings?genre=puzzle&for_sale=true

{
  "object": "list",
  "total": 128,
  "limit": 50,
  "offset": 0,
  "has_more": true,
  "data": [
    {
      "object": "listing",
      "slug": "word-ladder",
      "url": "https://playrallyarena.com/market/word-ladder",
      "name": "Word Ladder",
      "tagline": "A daily word puzzle with a paid streak pass.",
      "genre": "puzzle",
      "platforms": ["web", "ios"],
      "for_sale": true,
      "asking_price_usd": 48000,
      "revenue_multiple": 3.2,
      "mrr_cents": 125000,
      "revenue_30d_cents": 131400,
      "growth_bps": 1250,
      "net_churn_bps": 210,
      "customers": 843,
      "subscriptions": 611,
      "verified": true,
      "verified_provider": "stripe",
      "verified_at": "2026-09-22T09:00:00.000Z"
    }
  ]
}

GET /api/market/v1/listings/word-ladder

{
  "object": "listing",
  "slug": "word-ladder",
  "mrr_cents": 125000,
  "history": [
    { "date": "2026-09-20", "mrr_cents": 123000, "revenue_30d_cents": 129800, "subscriptions": 604 },
    { "date": "2026-09-21", "mrr_cents": 124200, "revenue_30d_cents": 130600, "subscriptions": 608 },
    { "date": "2026-09-22", "mrr_cents": 125000, "revenue_30d_cents": 131400, "subscriptions": 611 }
  ]
}

What it will never return

  • Anything about a seller’s payment account beyond the aggregates — no keys, no customer records, no invoice lines.
  • The identity of a game listed anonymously. Anonymised here exactly as it is in HTML; an open API must not be the hole a seller’s identity leaks through.
  • Offers, buyer details or anything from a private negotiation.

Built something with it? Tell us and we will link it here.