N NekoLive Developer Docs
Public developer documentation

Build with NekoLive

Integrate NekoLive account authorization, discover channels and games, consume live status, listen to chat, or build a chatbot that can post through a user-owned bot token.

OAuth2 REST API WebSocket chat Chatbots https://nekolive.co.uk
Public docs only. Admin routes, internal service endpoints, moderation-control internals, database details, media-node control APIs, private keys and privileged server configuration are intentionally not documented here.

OAuth2

NekoLive provides an OAuth2 authorization server under https://nekolive.co.uk/oauth2. Third-party applications should use the authorization-code flow so the user signs in on NekoLive and explicitly approves requested scopes.

GEThttps://nekolive.co.uk/oauth2/authorize
POSThttps://nekolive.co.uk/oauth2/token
POSThttps://nekolive.co.uk/oauth2/refresh_token
OAuth clients must have a registered client_id, redirect URI and permitted scopes. There is currently no public self-service client-registration API documented here; obtain/register client credentials through the normal NekoLive developer process.

Authorization-code flow

1. Generate state

Create a cryptographically random state value and keep it in the user's server-side session.

const crypto = require('crypto');
const state = crypto.randomBytes(24).toString('hex');

const authorize = new URL('https://nekolive.co.uk/oauth2/authorize');
authorize.searchParams.set('response_type', 'code');
authorize.searchParams.set('client_id', process.env.NEKOLIVE_CLIENT_ID);
authorize.searchParams.set('redirect_uri', 'https://your-app.example/oauth/nekolive/callback');
authorize.searchParams.set('scope', 'channel:read');
authorize.searchParams.set('state', state);

// Redirect the browser to authorize.toString()

2. User approves access

NekoLive signs the user in if needed, validates the client/redirect URI and displays the requested scopes. On approval your redirect URI receives code, state and scope query parameters.

3. Verify state and exchange the code

const body = new URLSearchParams({
  grant_type: 'authorization_code',
  code: req.query.code,
  redirect_uri: 'https://your-app.example/oauth/nekolive/callback',
  client_id: process.env.NEKOLIVE_CLIENT_ID,
  client_secret: process.env.NEKOLIVE_CLIENT_SECRET
});

const response = await fetch('https://nekolive.co.uk/oauth2/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body
});

const tokens = await response.json();

4. Refresh access later

const body = new URLSearchParams({
  grant_type: 'refresh_token',
  refresh_token: savedRefreshToken,
  client_id: process.env.NEKOLIVE_CLIENT_ID,
  client_secret: process.env.NEKOLIVE_CLIENT_SECRET
});

const response = await fetch('https://nekolive.co.uk/oauth2/refresh_token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body
});
Keep client_secret, access tokens and refresh tokens on your backend. Never ship a confidential client secret in browser JavaScript, a desktop bundle, a public repository or a mobile APK.

OAuth scopes

Scopes are space-separated in the authorization request and must also be allowed for the registered OAuth client.

ScopePurpose
channel:readRead channel information authorized by the user.
channel:editEdit the authorized user's channel where supported.
channel:streamkeySensitive access to the authorized creator's stream key. Request only when genuinely required.
bot:sendSend messages through an authorized bot integration.
bot:moderationBot moderation capability where the client and channel grant it. Privileged moderation internals are not documented on this public page.
Ask for the smallest set of scopes your application needs. Users should not be asked to approve unrelated permissions.

Public REST APIs

These endpoints are useful for discovery and public stream information and do not expose admin configuration.

GET/api/channels

Returns NekoLive channels grouped into live and offline channel lists.

GET/api/channels/stream/:name

Returns current public stream state for a channel. Depending on the source it may include values such as live state, platform, viewer count, title, game and public playback information. Mature/subscriber-only channels can return a restricted response instead of playback details.

const stream = await fetch(
  'https://nekolive.co.uk/api/channels/stream/nekosunevr'
).then(r => r.json());

console.log(stream.live, stream.title, stream.game);

Game catalogue

The public game catalogue is the same catalogue used by NekoLive channel/category selection.

GET/api/games?search=:text
Search

/api/games?search=Minecraft searches names containing the supplied text.

Response

Returns JSON shaped as { "games": [...] }, ordered by name.

const result = await fetch(
  'https://nekolive.co.uk/api/games?search=Call%20of%20Duty'
).then(r => r.json());

for (const game of result.games) {
  console.log(game.name);
}

Chat WebSocket

NekoLive channel pages connect to the public chat WebSocket using a channel path. The WebSocket host is deployment-configured, so integrations should use the public WebSocket hostname supplied for the current NekoLive deployment rather than assuming it is the same HTTP host.

WSSwss://<public-chat-host>/channel/:channelName

Chat events are JSON. Common public messages include chat_message, chat_emotes, system_message and presence/user-list events.

const ws = new WebSocket(
  'wss://PUBLIC_CHAT_HOST/channel/nekosunevr'
);

ws.addEventListener('open', () => {
  // Use the authentication/login mechanism appropriate for your integration.
  // A read-only listener can simply process public server events.
});

ws.addEventListener('message', event => {
  const data = JSON.parse(event.data);
  if (data.type === 'chat_message' || data.type === 'chat_emotes') {
    console.log(`${data.displayName || data.username}: ${data.message}`);
  }
});
Do not imitate another user's username or construct privileged moderation commands yourself. For automated sending, use the supported chatbot token API below so NekoLive can apply bot identity and channel permissions.

Build your own NekoLive chatbot

A chatbot normally has two parts: a WebSocket listener for incoming public chat events, and the NekoLive chatbot REST endpoint for sending messages as a registered bot identity.

  1. Sign into the NekoLive account that owns the bot.
  2. Create a bot token with a bot name and display name.
  3. Store the returned token securely on your bot server.
  4. Make sure that bot is allowed in the target channel.
  5. Listen to the channel WebSocket for incoming events.
  6. Send replies through POST /api/chatbot/ with the bot token.
Bot messages sent through the supported API are emitted with the bot role. Verified bots can also receive the verified-bot role from NekoLive.

Minimal Node.js bot

const BOT_TOKEN = process.env.NEKOLIVE_BOT_TOKEN;
const CHANNEL = 'your-channel';

async function sendMessage(message) {
  const response = await fetch('https://nekolive.co.uk/api/chatbot/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${BOT_TOKEN}`
    },
    body: JSON.stringify({
      channel: CHANNEL,
      message
    })
  });

  if (!response.ok) {
    throw new Error(`NekoLive bot send failed: ${response.status}`);
  }
  return response.json();
}

// Pair this with the WebSocket listener shown above.
// Example command handler:
async function onChatMessage(event) {
  if (event.type !== 'chat_message') return;
  if (String(event.message || '').trim() === '!hello') {
    await sendMessage('Hello from my NekoLive bot!');
  }
}

Bot token management

These endpoints operate on bots owned by the currently signed-in NekoLive account. They are user-facing bot-management actions, not admin APIs.

POST/api/chatbot/tokens

Create a bot. Requires an authenticated NekoLive browser/session and returns the newly generated token.

fetch('/api/chatbot/tokens', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    botName: 'mybot',
    displayName: 'My Bot'
  })
}).then(r => r.json()).then(console.log);
GET/api/chatbot/tokens

Lists bots owned by the signed-in account. Existing tokens are masked rather than returned in full.

POST/api/chatbot/tokens/:id/regenerate

Rotates the token for a bot owned by the signed-in account. Replace the old secret immediately in your bot service.

POST/api/chatbot/tokens/:id/verify/request

Requests verification review for your own bot. Internal review/approval endpoints are deliberately omitted from public documentation.

Send a bot message

POST/api/chatbot/

Use Authorization: Bearer <BOT_TOKEN> and JSON containing message and channel. The bot must have active permission for that target channel.

Security checklist

OAuth state

Generate a random state value, bind it to the browser session and reject callbacks whose state does not match.

Secrets stay server-side

Client secrets, refresh tokens and chatbot tokens should be environment variables or secrets-manager values.

Use HTTPS

Production callback URLs and API requests should use HTTPS. Do not send tokens over plaintext HTTP.

Least privilege

Request only the OAuth scopes your application actually needs and grant bots only the channels they should access.

Rotate leaked tokens

If a chatbot token is exposed, regenerate it immediately. If OAuth credentials are exposed, rotate them through the normal developer process.

Do not depend on private APIs

Undocumented internal/admin routes can change and are not part of the public integration contract.