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
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.
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
});
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.
| Scope | Purpose |
|---|---|
channel:read | Read channel information authorized by the user. |
channel:edit | Edit the authorized user's channel where supported. |
channel:streamkey | Sensitive access to the authorized creator's stream key. Request only when genuinely required. |
bot:send | Send messages through an authorized bot integration. |
bot:moderation | Bot moderation capability where the client and channel grant it. Privileged moderation internals are not documented on this public page. |
Public REST APIs
These endpoints are useful for discovery and public stream information and do not expose admin configuration.
Returns NekoLive channels grouped into live and offline channel lists.
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.
/api/games?search=Minecraft searches names containing the supplied text.
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.
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}`);
}
});
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.
- Sign into the NekoLive account that owns the bot.
- Create a bot token with a bot name and display name.
- Store the returned token securely on your bot server.
- Make sure that bot is allowed in the target channel.
- Listen to the channel WebSocket for incoming events.
- Send replies through
POST /api/chatbot/with the bot token.
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.
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);
Lists bots owned by the signed-in account. Existing tokens are masked rather than returned in full.
Rotates the token for a bot owned by the signed-in account. Replace the old secret immediately in your bot service.
Requests verification review for your own bot. Internal review/approval endpoints are deliberately omitted from public documentation.
Send a bot message
Use Authorization: Bearer <BOT_TOKEN> and JSON containing message and channel. The bot must have active permission for that target channel.
Security checklist
Generate a random state value, bind it to the browser session and reject callbacks whose state does not match.
Client secrets, refresh tokens and chatbot tokens should be environment variables or secrets-manager values.
Production callback URLs and API requests should use HTTPS. Do not send tokens over plaintext HTTP.
Request only the OAuth scopes your application actually needs and grant bots only the channels they should access.
If a chatbot token is exposed, regenerate it immediately. If OAuth credentials are exposed, rotate them through the normal developer process.
Undocumented internal/admin routes can change and are not part of the public integration contract.