Authentication
Every call your app makes is authenticated with an application secret, sent as a Bearer token.
Application secrets
Create secrets on your app's page at thexive.com/developers/console. A secret looks like xive_sa_… and is shown once, when you create it. Xive stores only a hash, so a lost secret cannot be shown again. Create a new one and revoke the old.
- Send it on every request:
Authorization: Bearer xive_sa_… - Several secrets can be active at the same time, so you can rotate without downtime. Create the new secret, deploy it, then revoke the old one.
- A revoked secret stops working immediately.
- Keep secrets on your server. Never put one in a browser page, a mobile app, an OBS browser source or anything else you ship to users. Anyone holding the secret can act as your app on every channel that added it.
Up to 5 secrets can be live per app. A hub bot secret (xive_as_…) does not work here — Hubs are a separate product. If your app is suspended, every secret stops working until it is reinstated.
Client types
You pick a client type when you create an app, and it can’t be changed afterwards.
- Confidential: your app runs on a server you control and can keep a secret, like a chat bot or a web app. Confidential apps are issued secrets and can call every endpoint in these docs. If you’re unsure, pick this.
- Public: your app can’t keep a secret, like a mobile, desktop or browser app or a game plugin. Public apps are never issued a secret. They get tokens through OAuth with PKCE instead.
Base URL
All endpoints in these docs are relative to:
https://api.thexive.com
Requests and responses are JSON. Send Content-Type: application/json with a body.
Verify your secret
GET /api/apps/@me returns the app the secret belongs to.
curl https://api.thexive.com/api/apps/@me \ -H "Authorization: Bearer $XIVE_APP_SECRET"
{
"success": true,
"application": {
"id": "9b1f3c52-6a0e-4d7b-8f4e-2c1d5a7e9b30",
"client_id": "4f6c2a9e0d1b47c3a8e5f7b2c9d0e1a3",
"name": "ModHelper",
"icon_url": "https://media.xivecdn.com/…/icon.png"
}
}
application.id is your application id; you will see it in the gateway channel name (app:<id>) and as the author of your bot's chat messages (app:<id>). client_id is the public id used in the "Add to channel" link.
A missing, wrong or revoked secret gets 401 with {"success": false, "error": "Invalid application credential"}.
OAuth: signing users in
OAuth lets someone sign in to your app with their Xive account (“Sign in with Xive”), and lets your app act on their own channel with the permissions they approve, without being added to it first. It follows Twitch's authentication: the same flows, endpoints and response shapes.
Tokens are streaming-only. They work on the bot API and nothing else. No token can post, comment, send messages, change a profile or touch money, whatever it asks for.
| Token | Starts with | Lasts | Get it with |
|---|---|---|---|
| User access token | xive_ut_ | 4 hours | Authorization code (+ refresh) |
| Refresh token | xive_rt_ | 30 days (public clients) / 90 days (confidential), renewed on each refresh | Comes with a user token |
| App access token | xive_at_ | 30 days | Client credentials (confidential clients) |
Send any token as Authorization: Bearer …, exactly like a secret.
1. Send the user to authorize
https://thexive.com/oauth2/authorize ?client_id=YOUR_CLIENT_ID &redirect_uri=https://yourapp.example/auth/callback &response_type=code &scope=chat:read+user:read:email &state=RANDOM_VALUE &code_challenge=PKCE_CHALLENGE &code_challenge_method=S256
redirect_urimust exactly match one of your app's registered OAuth redirect URLs.scopeis optional. Without one, you get identity only (id, username, display name, avatar). Adduser:read:emailfor their email, and any channel scope to act on their own channel.state: a random value you check on the way back.- PKCE (
code_challenge= base64url(SHA-256(verifier)), methodS256) is required for public clients and recommended for everyone.
The user signs in if needed, sees your app (with a ✓ if it's verified) and what it asks for, and chooses. You get back ?code=…&scope=…&state=…, or ?error=access_denied&state=… if they cancel.
2. Exchange the code
curl -X POST https://api.thexive.com/api/oauth2/token \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=xive_sa_… \ -d code=CODE \ -d grant_type=authorization_code \ -d redirect_uri=https://yourapp.example/auth/callback \ -d code_verifier=PKCE_VERIFIER
{
"access_token": "xive_ut_…",
"refresh_token": "xive_rt_…",
"expires_in": 14400,
"scope": ["chat:read", "user:read:email"],
"token_type": "bearer"
}
A public client sends code_verifier and no secret. A confidential client sends client_secret (one of its xive_sa_ secrets); with PKCE it sends both. Codes work once and expire after 10 minutes.
3. Who signed in?
GET /api/apps/users with the user token and no parameters returns that user, with email if you have user:read:email. Use id as their stable identifier; usernames can change.
Refreshing
curl -X POST https://api.thexive.com/api/oauth2/token \ -d grant_type=refresh_token \ -d refresh_token=xive_rt_… \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=xive_sa_… # confidential clients only
You get a new access and refresh token; the old pair stops working at once. Store the new refresh token every time.
Validating
Check a token the way Twitch does, and do it when your app starts and then hourly:
curl https://api.thexive.com/api/oauth2/validate -H "Authorization: OAuth xive_ut_…"
{ "client_id": "…", "login": "pixelpanda", "scopes": ["chat:read"], "user_id": "1f9a3b6c-…", "expires_in": 13820 }
401 means the token expired or was revoked: the user disconnected your app, or it was suspended. Refresh it, or send the user through sign-in again.
Revoking
curl -X POST https://api.thexive.com/api/oauth2/revoke -d client_id=YOUR_CLIENT_ID -d token=xive_ut_…
Revoke tokens when a user signs out of your app. Users can also disconnect your app from their Xive account at any time.
App access tokens
A confidential client can swap its secret for a 30-day app token, so the secret itself can stay in a vault:
curl -X POST https://api.thexive.com/api/oauth2/token \ -d client_id=YOUR_CLIENT_ID -d client_secret=xive_sa_… -d grant_type=client_credentials
An app token can do what the secret can: everything on channels that added your app, plus the public lookups.
Errors
The OAuth endpoints answer errors in Twitch's shape: {"status": 400, "message": "Invalid authorization code"}. A wrong secret is 403; an unknown client, a reused or expired code, a wrong redirect_uri or a bad code_verifier is 400.