Skip to documentation
Watchtower Developers Manage tokens
Publisher API v1

Your games.
Your stream data.

Access live streaming activity, session history, and analytics for your games.

Base URLhttps://api.watchtowr.gg/api/v1

Every token is read-only and scoped to one publisher account. You don’t need to pass a publisher ID. All responses are JSON and timestamps use UTC.

These endpoints report detected game activity, including plays outside your campaigns. They do not report campaign eligibility, verified rewards, or spend.

Authentication

API access must first be enabled for your publisher account by Watchtower. Once enabled, open Manage → API in your publisher dashboard and create a token. Owners and admins can create, regenerate, and delete tokens.

Copy the secret when it appears: you can only see it once. Send it in the Authorization header with every request.

First request
curl 'https://api.watchtowr.gg/api/v1/streams/live' \
  -H "Authorization: Bearer $WATCHTOWER_API_TOKEN"
Keep the token on your server.

Your backend polls Watchtower, caches the result, and sends only the fields your public page needs. Never put your token in browser JavaScript or a public repository.

Regenerating immediately replaces the old token. Deleting immediately revokes it. Update your server’s secret after regenerating. You can create up to 20 active tokens per account.

Polling & limits

Poll live streams every 30–60 seconds. Watchtower caches data for 30 seconds; polling more often won’t make the feed fresher. meta.generatedAt is the snapshot time, not the last time a creator was seen.

The limit is 60 requests per token per minute, shared across endpoints. Responses include RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset (seconds). On a 429, wait for the number of seconds in Retry-After.

Use one scheduled poll on your backend, then serve its cached result to visitors. Back off on temporary errors; if you show a previous result, mark when it was last updated.

Server-side JavaScript
const response = await fetch(
  'https://api.watchtowr.gg/api/v1/streams/live?limit=100',
  { headers: { Authorization: `Bearer ${process.env.WATCHTOWER_API_TOKEN}` } }
);

if (response.status === 429) {
  const retryAfter = Number(response.headers.get('Retry-After')) || 60;
  throw new Error(`Retry after ${retryAfter} seconds`);
}
if (!response.ok) throw new Error(`Watchtower returned ${response.status}`);

const { data, pagination, meta } = await response.json();
// Cache data on your server and expose only public display fields.
// If pagination.hasMore, fetch the next page using pagination.nextOffset.

Errors

Errors use a stable envelope with a machine-readable code and a message. Unknown or repeated query parameters are rejected.

Error response
{
  "status": "error",
  "error": {
    "code": "invalid_api_token",
    "message": "A valid API bearer token is required"
  }
}
StatusWhat to do
400Check the parameter names, values, and time window.
401Check the bearer token and that API access is enabled for your publisher account. Deleted and regenerated tokens stop working immediately.
404Check the endpoint path and version.
405Use GET. The external API is read-only.
429Wait for Retry-After seconds.
503Retry with backoff. Do not treat unavailable data as an empty live feed.