Docs · api

REST API

Developer-facing REST API overview for Lynx Relay.

The Godot SDK is the recommended integration path for early builds. This page only documents endpoints a game developer or game build needs; admin-only management endpoints are intentionally not listed here.

Base URL:

https://api.lynxrelay.space

Health

Security note: Runtime Godot/API requests use the Game Key. Developer self-service actions use the Game Admin Password. Do not embed the Game Admin Password in a shipped Godot build, public website, or public repository.

GET /health

Authentication

Runtime game API requests use the registered game’s Game Key:

Authorization: Bearer GAME_KEY
X-Game-Id: game.example

Developer self-service event join endpoints use the private Game Admin Password together with the Game ID in the path:

Authorization: Bearer GAME_ADMIN_PASSWORD

Do not use the global admin token or the Game Admin Password in a public game build.

Runtime request limits

Lynx applies runtime limits to protect the shared infrastructure from accidental request spam, such as calling the API from _process() or a very short timer.

Current limits:

Increment relay:        30 requests / minute / player installation / game / event
Sync relay:             4 requests / 5 seconds / player installation / game / event
Claim reward:           10 requests / minute / player installation / game / event
Register installation:  10 requests / minute / game
Recover installation:   10 requests / minute / installation

The increment limit is per player installation, not shared by the whole game. For example, Player A and Player B each get their own increment request budget for the same event.

If a limit is reached, the API returns:

429 Too Many Requests

Example response:

{
  "error": "Rate limit exceeded",
  "code": "rate_limited",
  "retry_after_seconds": 30
}

The Godot SDK queues runtime increments and retries after the server cooldown. Custom integrations should do the same instead of retrying in a tight loop.

List public events

GET /v1/public/events

Use this to show currently available public events.

List public games

GET /v1/public/games

Use this to show public games registered for Lynx Relay.

Check joined events for a game

GET /v1/games/{game_id}/events
Authorization: Bearer GAME_ADMIN_PASSWORD

This returns the events your game is connected to.

Join a public event

POST /v1/games/{game_id}/events/{event_id}/join
Authorization: Bearer GAME_ADMIN_PASSWORD
Content-Type: application/json

Example body:

{
  "contribution_label": "Collect embers",
  "reward_label": "Sunfall Chest"
}

Example event ID:

sunfall

Register installation

POST /v1/installations/register
Authorization: Bearer GAME_KEY
X-Game-Id: game.example
Content-Type: application/json

Example body:

{
  "tracked_relays": ["sunfall"]
}

Example response:

{
  "installation_id": "...",
  "installation_token": "...",
  "state_token": "...",
  "state_version": 1,
  "baseline_claims": {
    "sunfall": 0
  }
}

Store the installation ID, installation token, and state token locally in the game save/config.

Recover installation state

GET /v1/installations/state
Authorization: Bearer GAME_KEY
X-Game-Id: game.example
X-Installation-Id: INSTALLATION_ID
X-Installation-Token: INSTALLATION_TOKEN

Use this if the local state token needs to be recovered from the server.

Read relay

GET /v1/relays/{relay_id}

Example:

GET /v1/relays/sunfall

Example relay state:

{
  "relay_id": "sunfall",
  "value": 206,
  "target": 220,
  "completion_version": 1,
  "previous_target": 100,
  "next_required": 120
}

Increment relay

POST /v1/relays/{relay_id}/increment
Authorization: Bearer GAME_KEY
X-Game-Id: game.example
Idempotency-Key: UNIQUE_ACTION_ID
Content-Type: application/json

Example body:

{
  "amount": 1,
  "client_id": "local-install-or-save-id"
}

The game must be linked to the event before it can increment that relay.

amount must stay within the event’s configured minimum and maximum increment range. Do not combine many player actions into one oversized amount unless the event was configured to allow that. If many actions happen quickly, queue them client-side and send valid increment requests at a safe pace.

Sync relay and check reward availability

POST /v1/relays/{relay_id}/sync
Authorization: Bearer GAME_KEY
X-Game-Id: game.example
X-Installation-Id: INSTALLATION_ID
X-Installation-Token: INSTALLATION_TOKEN
Idempotency-Key: UNIQUE_SYNC_ID
Content-Type: application/json

Example body:

{
  "state_token": "ENCRYPTED_STATE_TOKEN"
}

Example response:

{
  "relay": {
    "relay_id": "sunfall",
    "value": 206,
    "target": 220,
    "completion_version": 3
  },
  "claim": {
    "available": true,
    "completion_count": 3,
    "from_version": 0,
    "to_version": 3,
    "state_token": "UPDATED_STATE_TOKEN"
  }
}

Complete a reward claim

POST /v1/relays/{relay_id}/claim
Authorization: Bearer GAME_KEY
X-Game-Id: game.example
X-Installation-Id: INSTALLATION_ID
X-Installation-Token: INSTALLATION_TOKEN
Idempotency-Key: UNIQUE_CLAIM_ID
Content-Type: application/json

Example body:

{
  "state_token": "ENCRYPTED_STATE_TOKEN"
}

Call this only after the game has granted and saved the local reward successfully.

Security note

Game Keys are runtime credentials for relay/reward requests from your game. They do not grant admin permissions.

Game Admin Passwords are private credentials for trusted admin/developer actions. They must not be embedded in exported game clients or public frontend code.

Lynx is not a player database and does not store player profiles. The API should only receive the minimal event progress and reward completion data required for the integration to work.