Games & Comics — entry 007 of 75

CheapShark

Verified Aug 2026

CheapShark's keyless JSON API aggregates PC game deals across roughly three dozen storefronts (Steam, GOG, Epic, Humble Store, and more), returning live and historical-low prices, percentage savings, and Metacritic scores per deal. Separate /games and /stores endpoints support price-history lookups by title or Steam AppID; live testing confirmed open CORS and no documented rate limit or paid tier.

CheapShark is a keyless JSON API that aggregates PC game deals across roughly three dozen storefronts. A live GET this run against /deals?storeID=1&upperPrice=15&pageSize=1 returned a genuine 582 B one-item deal array at HTTP 200, with content-type: application/json and access-control-allow-origin: * — no key, signup, or header beyond a normal request.

game-dealsprice-trackingsteamno-auth
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreeNo paid tier — free for the documented use case.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score88out of 100
Authentication25/25No authentication required
Pricing20/20Free to use
Docs14/20Documentation URL provided
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 88 on greatapis.com
<a href="https://greatapis.com/api/cheapshark/"><img src="https://greatapis.com/badge/cheapshark.svg" alt="Scored 88 on greatapis.com"></a>

Auth quickstart

  1. No API key, signup, or credit card required — the live GET above returned real deal data with no auth header of any kind attached, and the response still carried access-control-allow-origin: * for direct browser use.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Find a cheap Steam deal under $15

GEThttps://www.cheapshark.com/api/1.0/deals?storeID=1&upperPrice=15&pageSize=1

200 application/json

[
  {
    "internalName": "BATTLEFIELD3",
    "title": "Battlefield 3",
    "metacriticLink": "/game/battlefield-3/",
    "dealID": "FhBKK4XJ0dmqH9xN1YideiIrjTWPk6dXxgGVFlJzO7s%3D",
    "storeID": "1",
    "gameID": "1684",
    "salePrice": "3.99",
    "normalPrice": "39.99",
    "isOnSale": "1",
    "savings": "90.022506",
    "metacriticScore": "89",
    "steamRatingText": "Mixed",
    "steamRatingPercent": "69",
    "steamRatingCount": "5351",
    "steamAppID": "1238820",
    "releaseDate": 1319500800,
    "lastChange": 1785437943,
    "dealRating": "9.7",
    "thumb": "https://shared.fastly.steamstatic.com/store_item_assets/steam/apps/1238820/capsule_231x87.jpg?t=1777326004"
  }
]

A live GET this run against /deals?id=FhBKK4XJ0dmqH9xN1YideiIrjTWPk6dXxgGVFlJzO7s%3D (the dealID above, passed back verbatim) returned HTTP 200 with a 531 B {gameInfo, cheaperStores, cheapestPrice} object — the price-history lookup for that specific deal.

Try it

Developer reference

Base URLhttps://www.cheapshark.com/api/1.0
Key endpoints
  • GET/deals
  • GET/games
  • GET/stores

Gotchas & limits

  • dealID values come back already percent-encoded — confirmed live above with FhBKK4XJ0dmqH9xN1YideiIrjTWPk6dXxgGVFlJzO7s%3D. Pass that string straight back as ?id= and it works (200, 531 B); let an HTTP client URL-encode it a second time (...%253D) and a live GET this run returned HTTP 404 whose entire body is the 2-byte array [] — an empty result, not an error object. dealIDs rotate, so re-derive a fresh one rather than reusing this one verbatim.
  • Every price/rating field is a JSON string, not a number — confirmed live above: "salePrice":"3.99", "storeID":"1", "savings":"90.022506", "metacriticScore":"89". Meanwhile releaseDate and lastChange on the same object are real integers (unix epoch). Code that assumes numeric fields are consistently typed within one payload will get a string where it expects a number.
  • pageSize is silently capped — a live GET this run with pageSize=200 and a separate one with pageSize=60 both returned exactly 60 items, with no error, no warning field, and no 400. /deals also exposes x-total-page-count (3000 live this run) via access-control-expose-headers, but that count is a page ceiling at the current pageSize, not a promise that every page is full.
  • An unknown route is not a JSON error — a live GET this run against /api/1.0/nosuchendpoint returned HTTP 404 with content-type: text/html; charset=utf-8 and an 11,735 B branded HTML page. Code that does JSON.parse() unconditionally on a non-200 will throw on this path specifically.
  • The same /games endpoint returns different top-level shapes depending on the query — a live GET this run against /games?title=batman returned an array of summaries, while /games?id=612 returned a single object ({info, cheapestPriceEver, deals: [...]}). steamAppID is also inconsistent within one array response: null on "LEGO Batman", a real string ("502820") on "Batman: Arkham VR".

Availability

Uptime100%
Median latency69 ms
Last checkUp · 400 · Sep 2026

3 checks since Aug 2026. A person runs this check by hand, not an automated monitor.

Changelog

  • Sep 2026gained a docs link

See every tracked change ↗ ·Subscribe with RSS ↗