WenBot home Developer API

WenBot Developer API

Pull your WenBot data into your own website — wager leaderboards, store items, giveaways and viewer points. Read-only, and free with the Elite plan.

Getting started

The API is available to streamers on Elite and above (Agency includes everything Elite has). Everything is a GET request that returns JSON.

  1. Open your dashboardSettings & AccountDeveloper API.
  2. Create a key. Copy it — it is shown once and never again.
  3. Send it with every request, as shown below.

The base URL is https://wenbot.gg/api/v1.

API keys

There are two kinds, and the difference matters:

The two key types and where each one belongs
KeyWhere it goesWhat it reads
PUBLISHABLE
wb_pk_live_…
Safe in your website's front-end JavaScript. Only what your public portal already shows: leaderboards, store, giveaways.
SECRET
wb_sk_live_…
Your server only. Never in a web page. Everything above, plus viewer points and redemption history.

Lock your publishable key to your domain. In the dashboard, set the origin (for example https://yoursite.com). Without it, anyone who views your page source can use your key and spend your monthly quota.

A secret key never receives CORS headers, so a browser cannot use one even if it is pasted into a page. That is deliberate — it fails loudly rather than working insecurely.

Authentication

Secret keys go in the Authorization header. Never put one in a URL — query strings end up in server logs, browser history and Referer headers.

curl https://wenbot.gg/api/v1/viewer/someviewer \
  -H "Authorization: Bearer wb_sk_live_YOUR_KEY"

Publishable keys may use the same header, an X-API-Key header, or a ?key= query parameter — whichever your site makes easiest.

fetch("https://wenbot.gg/api/v1/leaderboard", {
  headers: { "X-API-Key": "wb_pk_live_YOUR_KEY" }
})
  .then(r => r.json())
  .then(res => console.log(res.data));

Rate limits & quota

Limits applied per key and per channel
LimitValueOn exceed
Requests per minute60, per key429 rate_limited
Requests per month100,000, per channel429 quota_exceeded

Public responses carry Cache-Control: public, max-age=120. Respect it rather than polling — the underlying data refreshes about every two minutes, so a tighter loop burns your quota without returning anything new. Your current usage is shown on the Developer API page in your dashboard.

The monthly quota resets at the start of each calendar month (UTC). If your site genuinely needs more, get in touch and it can be raised for your channel.

Responses

Every response has the same envelope, so you can branch on ok before anything else.

{ "ok": true, "data": { … } }

{ "ok": false, "error": { "code": "plan_required", "message": "…" } }

Public responses also include cachedAt, a millisecond timestamp telling you how fresh the underlying data is.

Public endpoints

These work with either key type. They return the same data your public portal shows.

GET/channelPUBLISHABLE

Your channel's display name, currency name, live status and which features are enabled.

GET/leaderboardPUBLISHABLE

The current wager leaderboard, any additional boards, and the period countdown.

GET/leaderboard/historyPUBLISHABLE

Past leaderboard periods and their archived winners.

GET/storePUBLISHABLE

Your store catalogue: items, cost and stock.

GET/giveawayPUBLISHABLE

The active giveaway if one is running, plus recent winners.

GET/points/topPUBLISHABLE

Your points leaderboard. Optional ?limit= (1–100, default 25).

Viewer endpoints

Secret key only. These return data about individual viewers, so they are never usable from a browser. Call them from your server and pass the result to your page.

GET/viewer/{username}SECRET

A viewer's points balance, raffle tickets, wins and verification status in your channel.

{
  "ok": true,
  "data": {
    "username": "someviewer",
    "points": 2850,
    "raffleTickets": 3,
    "wins": 1,
    "verified": true,
    "firstSeenAt": 1756000000000,
    "lastSeenAt": 1789000000000
  }
}
GET/viewer/{username}/redemptionsSECRET

That viewer's store redemption history, newest first. Optional ?limit= (1–100, default 25).

Error codes

Every error the API can return, and what to do about it
CodeHTTPWhat it means
invalid_key401The key is missing or not recognised.
revoked_key401This key was revoked in the dashboard. Create a new one.
wrong_key_type403A viewer endpoint was called with a publishable key.
plan_required403API access needs Elite or above, or the feature needs a higher plan on your channel.
origin_not_allowed403The request came from a domain not on the key's allowed list.
rate_limited429More than 60 requests in a minute. Back off and retry.
quota_exceeded429The monthly quota is used up. It resets next month.
not_found404No such endpoint, viewer, or no portal data for the channel yet.
server_error500Something broke on our end. Retry shortly.

Full example

A leaderboard on your own site, using a publishable key locked to your domain:

<div id="board">Loading…</div>

<script>
fetch("https://wenbot.gg/api/v1/leaderboard", {
  headers: { "X-API-Key": "wb_pk_live_YOUR_KEY" }
})
  .then(function (r) { return r.json(); })
  .then(function (res) {
    if (!res.ok) throw new Error(res.error.code);
    var rows = (res.data.primary && res.data.primary.entries) || [];
    document.getElementById("board").innerHTML = rows.map(function (e, i) {
      return "<div>" + (i + 1) + ". " + e.username + " — $" + e.wagered + "</div>";
    }).join("");
  })
  .catch(function (err) {
    document.getElementById("board").textContent = "Leaderboard unavailable";
    console.error(err);
  });
</script>

And a points balance, which must run on your server:

// Node — the secret key stays here, never in the page
const r = await fetch(
  "https://wenbot.gg/api/v1/viewer/" + encodeURIComponent(username),
  { headers: { Authorization: "Bearer " + process.env.WENBOT_SECRET_KEY } }
);
const res = await r.json();
if (res.ok) console.log(res.data.points);

Something missing? This is v1 and it is read-only on purpose. If you need an endpoint that is not here, say so — the surface grows based on what people actually build.