Zoopia

Developer docs

Catalog API

Pull the list of games as JSON, render them however you like, and embed any of them with one script tag. Everything below works with a single read-only API key from your publisher panel.

Quick start

Three steps: get a key, fetch the catalog, drop in the embed snippet.

# 1. Fetch the catalog (key from your publisher panel)
curl "https://zoopiagames.com/api/public/catalog?locale=en&per_page=24" \
     -H "X-Api-Key: gfk_100002_xxxxxxxxxxxxxxxx"

# 2. Each game already ships with the snippet you need:
#    "embed_code": "<div data-gameforge-game=\"admin/arrow\"></div>
#                   <script src=\"https://zoopiagames.com/gf-embed.js\"></script>"

Games only run on domains you have added and verified in the publisher panel. Until then the catalog still lists them, but the game itself refuses to load.

Authentication

Every request carries your key, either as a header (preferred) or a query parameter. The key is read-only: it can list the catalog and nothing else. Rotate it from the panel if it leaks — the old key stops working immediately.

X-Api-Key: gfk_100002_xxxxxxxxxxxxxxxx      # header
?key=gfk_100002_xxxxxxxxxxxxxxxx           # or query parameter

Keys are tied to your publisher account. A suspended or not-yet-approved account gets 401.

GET /api/public/catalog

Returns the games you are allowed to publish, newest first.

ParameterDefaultNotes
localeenen, de, fr, no, tr, pl, es — titles/descriptions in that language, falling back to English
category(all)puzzle, action, arcade, platformer, sports, strategy, racing, casual
page11-based page number
per_page24max 100
{
  "publisher": { "pub_id": "100002", "name": "Your Company" },
  "locale": "en",
  "category": null,
  "total": 42,
  "page": 1,
  "per_page": 24,
  "games": [
    {
      "owner": "admin",
      "slug": "arrow-oyunu",
      "title": "Arrow Master",
      "description": "Aim, judge the wind, hit the target…",
      "category": "arcade",
      "tags": ["arrow", "aim", "arcade"],
      "thumb_url": "https://zoopiagames.com/api/thumb/admin/arrow-oyunu?v=…",
      "game_url": "https://cdn.example.com/gameforge-prod/admin/arrow-oyunu/live/index.html",
      "embed_code": "<div data-gameforge-game=\"admin/arrow-oyunu\"></div>\n<script src=\"https://zoopiagames.com/gf-embed.js\"></script>",
      "updated_at": "2026-09-18T10:12:00Z"
    }
  ]
}

thumb_url is the card image: an editor-made illustration when one exists, otherwise a real screenshot of the game. Use embed_code rather than building the iframe yourself — see below.

GET /api/public/categories

Categories that actually contain games for you, with counts — handy for building menus.

curl "https://zoopiagames.com/api/public/categories?locale=de" -H "X-Api-Key: …"

{ "locale": "de", "categories": [ { "category": "puzzle", "count": 12 }, … ] }

Embedding a game

Paste the snippet where the game should appear. The script creates the iframe, handles fullscreen and mobile layout, performs the authorization handshake from your page, and re-emits gameplay events so your analytics can listen.

<div data-gameforge-game="admin/arrow-oyunu"></div>
<script src="https://zoopiagames.com/gf-embed.js"></script>

<script>
  // Optional: react to what happens inside the game
  window.addEventListener('gf:game_start', e => console.log('started', e.detail))
  window.addEventListener('gf:game_over',  e => console.log('score', e.detail.data.score))
</script>

The handshake must run on your page, not inside the iframe — that is how our server sees your real domain. If you build the iframe manually the game will not load.

Caching & rate limits

  • Responses carry Cache-Control: public, max-age=300 and an ETag. Send If-None-Match and you get a cheap 304.
  • Cache on your side too — the catalog changes rarely. A block or an unpublish takes effect on our side immediately, so a stale copy may briefly list a game that has stopped loading.
  • 120 requests per minute per publisher. Over that you get 429.

Errors

StatuscodeWhat to do
401bad_api_keyKey is wrong, or the publisher account is not approved yet.
429rate_limitedBack off and reuse your cached copy.
4xx/5xx—Body is always JSON with an "error" field.

Need a key?

Register in the publisher panel, add your domain, publish our ads.txt lines and hit Verify.

Open publisher panel