---
title: "Games free to claim right now, across all stores ($0.02 per pull; conditional checks free)"
method: GET
path: "/v1/free-games"
---

# Games free to claim right now, across all stores ($0.02 per pull; conditional checks free)

`GET /v1/free-games`

## Request

- Base URL: `https://soren.com`
- URL: `https://soren.com/v1/free-games`
- Auth: none declared

Paid per pull. With a live token and If-None-Match, an unchanged feed returns 304 free; a changed feed returns 402.

## Headers

- `If-None-Match` string
- `Authorization` string
- `X-Payment` string

## Response `200`

Feed payload plus a fresh 24h access token. ILLUSTRATIVE EXAMPLE - values are representative, not live data. Note gog here shows status 'unavailable' with free_count null: that means we could NOT check, and must never be rendered as 'nothing is free on GOG'.

- Feed
  - `version` string, required: SHA-256 of the canonical form {"offers":<free_games as published>,"coverage":[[store,status,free_count],...] sorted by store}, hex-encoded. Changes only when content changes, never on a mere refresh — so an unchanged version means nothing to do, and a mismatch means the payload was modified after publication.
  - `updated_at` string, date-time, required
  - `free_games` Offer[], required
    - `title` string, required
    - `store` 'steam' | 'epic' | 'gog' | 'itch', required
    - `igdb_id` integer, nullable
    - `claim_url` string, uri, required
    - `starts_at` string, date-time, nullable: Null where the store does not publish a start time. Never substituted with our detection time.
    - `ends_at` string, date-time, nullable
    - `original_price_cents` integer, nullable: What the game normally costs, in minor units of `currency` (1999 = $19.99). Lets you rank by value rather than by row count — "3 games worth $60 are free" is a more useful answer than "20 games are free", and this catalogue is dominated by low-priced indie titles. null means the store does not publish a price, which is NOT the same as zero: a permanently free-to-play title would be 0.
    - `currency` string, nullable: ISO 4217 code for original_price_cents. null when the price is unknown.
    - `source` string: The exact endpoint and test that confirmed this entry, e.g. 'epic:freeGamesPromotions (discountPercentage === 0, active window)'. Static per store, so it is included in the version hash.
    - `first_seen` string, date-time, nullable: When this offer was first observed. Set once and stable thereafter. There is deliberately no per-offer verified_at: every offer from a store is confirmed in the same pass, so it would duplicate stores[].verified_at exactly, and being a per-run timestamp it would change the version on every pass and bill every conditional poll.
  - `stores` object, required
  - `verification` object: How to recompute `version` yourself. Present so integrity can be checked rather than trusted.
  - `signature` object, nullable: Ed25519 signature over the `version` string. Public key at https://soren.com/signing-key.json. Proves the payload originated from Soren; combine with recomputing the hash, which proves the content matches what was signed.
  - `contract` object: Machine-readable statement of what is guaranteed within this major version: fields never removed or retyped, additions possible without notice, meanings never silently changed, canonical hash form fixed, 180 days' deprecation notice. Full text at https://soren.com/contract.md.

## Other responses

- `304`: Nothing changed since your version. Empty body. NOT BILLED - the common case.
- `402`: Payment required - either you hold no live token, or the feed changed. NOT BILLED. Follows the x402 spec, so `error` is a STRING here, unlike other error responses. Deliberately reveals nothing about feed contents.
- `429`: Rate limited. Wait Retry-After seconds.
- `503`: Feed unpublished or stale. We fail rather than serve data we cannot vouch for.

---

[API](https://skmtc.dev/soren/apis/soren-free-games-api.md) · [All operations](https://skmtc.dev/soren/apis/soren-free-games-api/llms.txt) · [OpenAPI document](https://skmtc.dev/soren/apis/soren-free-games-api/revisions/00402cfcf30d?raw)
