GuidesGAME APIS
Free video game APIs for JavaScript
We tested 12 video game APIs from a browser origin on 28 October 2026. CheapShark, GamerPower, FreeToGame, Speedrun.com and PokeAPI need no key and send Access-Control-Allow-Origin: *, so you call them directly. Epic's free games feed, the Steam store and Roblox answer without CORS headers but returned 200 through the free cors.dev proxy (no signup, about 600 requests a minute), while IGDB needs cors.dev Pro or a backend, RAWG and MobyGames need keys, and Giant Bomb's API is offline.
Game APIs tested from the browser
Each API below got a request with Origin: https://example.com, like a page on another site, and the same request through the free cors.dev proxy (https://proxy.cors.dev/ plus the full URL). The free proxy needs no signup, handles GET and HEAD at about 600 requests a minute per IP, forwards query-string parameters as they are and drops custom request headers, except credential headers such as Authorization, which get 400.
| API | Key | Free use | Browser CORS | Through cors.dev |
|---|---|---|---|---|
| CheapShark | None | Rate limited, 429 with Retry-After | Yes, any origin | Not needed |
| GamerPower | None | Up to 10 requests per second, attribution | Yes, any origin | Not needed |
| FreeToGame | None | Up to 10 requests per second, attribution | Yes, any origin | Not needed |
| Speedrun.com | None for reads | 100 requests a minute per IP | Yes, any origin | Not needed |
| PokeAPI | None | No rate limit, cache locally | Yes, any origin | Not needed |
| Epic Games free games | None, undocumented | Not documented | No | Free proxy, 200 |
| Steam store appdetails | None | See the Steam guide | No | Free proxy, 200 |
| Roblox games and users | None | Per endpoint, 1 to 1,200 a minute | No | Free proxy, 200 |
| RAWG | Free key in the URL | 100,000 monthly users, attribution | Preflight yes, 401 errors no | Free proxy forwards the key |
| IGDB | Twitch Client ID and token | 4 requests per second | No, preflight 401 | cors.dev Pro or a backend |
| MobyGames | Paid key in the URL | 720 an hour, 1 a second | No | Keep the key on a server |
| Giant Bomb | Key | API not currently available | No, 403 challenge | 403 challenge |
Five of the 12 need no key and no proxy, three more work through the free proxy, and the rest need a key, a backend or are offline.
Deals and free game APIs
CheapShark, GamerPower and FreeToGame need no key and answered with Access-Control-Allow-Origin: *, so a plain fetch() works. GamerPower's and FreeToGame's docs point to RapidAPI for CORS, but the direct calls worked in our test.
- CheapShark tracks PC game prices in USD across 14 active stores, Steam included, refreshed about once an hour. Its docs say requests "should come directly from the user's browser" to avoid rate limits; a
429carriesRetry-After, which page code cannot read because CheapShark exposes onlyContent-EncodingandX-Total-Page-Count, and bulk catalog scraping can earn a permanent block. The one condition for free use is to send users to deals throughhttps://www.cheapshark.com/redirect?dealID={id}. - GamerPower lists live giveaways of games, loot and betas for PC, Steam, Epic, GOG, consoles and mobile. Stay under 10 requests per second and credit GamerPower.com;
/giveaways?platform=pc&type=gamereturned 33,108 bytes. - FreeToGame covers 400+ free-to-play games with genre, platform, publisher and release date. It asks for under 10 requests per second and attribution with an active link;
/games?platform=browserreturned 35,711 bytes.
CheapShark rejects requests without a descriptive User-Agent: our server request got 400 "Missing or generic User-Agent header detected". Browsers send their own, so this only bites when you call it from a backend.
const API = 'https://www.cheapshark.com/api/1.0';
const params = new URLSearchParams({ storeID: '1', upperPrice: '15', sortBy: 'Savings', pageSize: '5' });
const [dealsResponse, storesResponse] = await Promise.all([fetch(`${API}/deals?${params}`), fetch(`${API}/stores`)]);
if (dealsResponse.status === 429) throw new Error('Rate limited by CheapShark, retry later');
if (!dealsResponse.ok || !storesResponse.ok) throw new Error(`CheapShark answered ${dealsResponse.status}`);
const deals = await dealsResponse.json();
const stores = Object.fromEntries((await storesResponse.json()).map((store) => [store.storeID, store.storeName]));
for (const deal of deals) {
// CheapShark asks you to send users through its redirect link
const link = `https://www.cheapshark.com/redirect?dealID=${deal.dealID}`;
console.log(`${deal.title}: $${deal.salePrice} (was $${deal.normalPrice}) on ${stores[deal.storeID]}`, link);
}Epic Games free games feed
Epic's weekly free games come from https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions?locale=en-US&country=US&allowCountries=US. It needs no key, but Epic does not document it, so the shape can change without notice. Direct, it answered 200 without an Access-Control-Allow-Origin header, so fetch() from a page fails; through the free proxy it returned the same 48,591 bytes.
The feed held 13 items under data.Catalog.searchStore.elements, and most were ordinary sales. A game is free when an offer in promotions.promotionalOffers (now) or promotions.upcomingPromotionalOffers (next) has discountSetting.discountPercentage set to 0, because the field is the share of the full price you pay. On 28 October 2026 that matched 2 games free until 29 October 15:00 UTC and 1 game free from then.
const EPIC = 'https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions?locale=en-US&country=US&allowCountries=US';
const response = await fetch('https://proxy.cors.dev/' + EPIC);
if (!response.ok) throw new Error(`Epic answered ${response.status}`);
const { data } = await response.json();
// discountPercentage is the share of the full price you pay, so 0 means free
const freeOffer = (groups) =>
(groups ?? []).flatMap((group) => group.promotionalOffers).find((offer) => offer.discountSetting.discountPercentage === 0);
for (const game of data.Catalog.searchStore.elements) {
const now = freeOffer(game.promotions?.promotionalOffers);
const next = freeOffer(game.promotions?.upcomingPromotionalOffers);
if (!now && !next) continue;
const slug = game.catalogNs?.mappings?.[0]?.pageSlug ?? game.productSlug;
const when = now ? `free until ${now.endDate}` : `free from ${next.startDate}`;
console.log(game.title, when, `https://store.epicgames.com/en-US/p/${slug}`);
}Build the store link from catalogNs.mappings[0].pageSlug as https://store.epicgames.com/en-US/p/{pageSlug}.
Game databases: RAWG, IGDB, MobyGames and Giant Bomb
RAWG has 500,000+ games on 50 platforms with screenshots, ratings, Metacritic scores and store links. It needs a free key in the key query parameter, is free for personal use with a visible link to RAWG on every page that shows its data, and free commercially up to 100,000 monthly active users or 500,000 page views a month.
RAWG's preflight allowed any origin, but its 401 answers ("The key parameter is not provided", "The API key is not found") carried no CORS header. In a browser a key problem therefore surfaces as a CORS error; through the free proxy the key parameter is forwarded and the 401 is readable. We had no valid key, so a successful response went untested, and a key in a URL is visible to anyone who opens your page.
- IGDB needs a Twitch Client ID and app token on every
POST, its preflight answered401, and its docs say it does not support browser requests. The free proxy refusesPOST; cors.dev Pro ($5 a month for 500,000 requests) forwards it for internal tools and bring-your-own-key apps, as the IGDB guide explains. - MobyGames is paid: the non-commercial Hobbyist plan costs $9.99 a month, or $7.99 billed annually, with 720 requests an hour and at most 1 a second. The
api_keyparameter is what MobyGames calls your private key, so keep it on a server. - Giant Bomb's API page lists its game, character, company and release APIs as "Not currently available" after the site left Fandom, and our requests got a
403Cloudflare challenge.
Speedrun.com, PokeAPI, Steam and Roblox
- Speedrun.com serves games, categories, leaderboards and world records without a key and with
Access-Control-Allow-Origin: *. It allows 100 requests a minute per IP and licenses content under CC BY-NC 4.0. - PokeAPI serves Pokemon, moves, items and game versions with CORS for any origin. It dropped rate limiting in November 2018, but its fair use policy asks you to cache locally and bans IPs that abuse it;
/pokemon/pikachualone is 309,106 bytes. - The Steam store's
appdetailsanswered without a CORS header (6,852 bytes) and with200through the free proxy. The Steam API guide lists which Steam endpoints need a key. - Roblox's public games, users and groups endpoints send no CORS headers; 13
GETendpoints answered200through the free proxy, covered in the Roblox API guide.
Good questions.
Which video game API is free with no key and works from JavaScript?
CheapShark, GamerPower, FreeToGame, Speedrun.com and PokeAPI need no key and send Access-Control-Allow-Origin: *, so fetch() works from any page. Follow each one's terms: CheapShark redirect links, attribution for GamerPower and FreeToGame, and local caching for PokeAPI.
Is there an Epic Games API for free games?
The free games list comes from store-site-backend-static.ak.epicgames.com/freeGamesPromotions, a store backend endpoint that Epic does not document and that needs no key. It sends no CORS header, so call it through https://proxy.cors.dev/ from a web page, and expect the format to change without notice.
Why does RAWG show a CORS error instead of a 401?
RAWG answers the preflight with Access-Control-Allow-Origin: *, but its 401 for a missing or wrong key comes back without that header, so the browser hides the error body. Check the key with curl, or route the request through the free cors.dev proxy to read the JSON error.
What is the best free alternative to the Giant Bomb API?
Giant Bomb lists its game data APIs as not currently available. RAWG covers 500,000+ games with a free key, and IGDB is free for non-commercial and commercial use but needs Twitch credentials and a backend or cors.dev Pro.
How do I get Steam game prices into a web page?
CheapShark returns Steam prices next to 13 other active stores with CORS for any origin, so you can call it directly; storeID=1 is Steam. For Steam's own store data, store.steampowered.com/api/appdetails works through the free cors.dev proxy.