Lifebots symbol
Lifebots.cloud
OAuth 2.0 API
Getting started

Authorization flow

Four steps get you from “Connect with LifeBots” to an access token. Pick your app type — the code changes to match.

1. Send the user to LifeBots

Redirect the user's browser to the authorize URL with your client_id, redirect URI, the scopes you want, and a random state.

// Remember state so the callback can prove the redirect is yours
const state = crypto.randomUUID()
sessionStorage.setItem('oauth_state', state)

const authUrl = new URL('https://lifebots.cloud/oauth/authorize')
authUrl.searchParams.set('client_id', 'your_client_id')
authUrl.searchParams.set('redirect_uri', 'https://yourapp.com/oauth/callback')
authUrl.searchParams.set('scope', 'read:profile bots:chat bots:groups') // space-separated
authUrl.searchParams.set('state', state)

window.location.href = authUrl.toString()

The user signs in, sees your app's name and the scopes, and approves. If they already approved the same scopes before, they're sent straight back. All authorize parameters →

2. Handle the redirect back

LifeBots redirects to your redirect_uri with ?code=…&state=…, or with ?error=access_denied if the user declined. Reject any redirect whose state isn't the one you stored.

// On https://yourapp.com/oauth/callback
const params = new URLSearchParams(window.location.search)

if (params.get('state') !== sessionStorage.getItem('oauth_state')) {
  throw new Error('State mismatch - ignore this redirect')
}
if (params.get('error')) {
  // access_denied: the user said no
  throw new Error(params.get('error_description') || params.get('error'))
}

const code = params.get('code') // single-use and short-lived: exchange it now

3. Exchange the code for tokens

Send the code with your client_secret, from your server.

// On your server - the client_secret must never reach a browser
const res = await fetch('https://api.lifebots.cloud/api/v1/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    client_id: 'your_client_id',
    client_secret: process.env.LIFEBOTS_CLIENT_SECRET,
    code,
    redirect_uri: 'https://yourapp.com/oauth/callback' // same as step 1
  })
})
const tokens = await res.json()
if (tokens.error) throw new Error(tokens.error_description)
Response
{
  "access_token": "lb_at_…",
  "token_type": "Bearer",
  "scope": "read:profile bots:chat bots:groups",
  "refresh_token": "lb_rt_…",
  "expires_in": 3600
}
  • refresh_token is only included if your app has token refresh turned on.
  • expires_in (seconds) is left out when your app's tokens never expire.

4. Refresh when the token expires

When a call fails with INVALID_TOKEN, trade the refresh token for a new pair. Tokens rotate: after a refresh the old access and refresh tokens are dead, so store the new ones before your next call.

const res = await fetch('https://api.lifebots.cloud/api/v1/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'refresh_token',
    client_id: 'your_client_id',
    client_secret: process.env.LIFEBOTS_CLIENT_SECRET,
    refresh_token: tokens.refresh_token
  })
})
const newTokens = await res.json()
// The old access AND refresh tokens stop working now - save the new pair.
Done with a user? Call POST /oauth/revoke so the token can't be used again.

Next: making requests with the token.

Lifebots symbol
Lifebots.cloud

Empowering Second Life experiences with intelligent bot automation and seamless group management solutions.

Product
Support
Company
Visit Us

© 2025 - 2026 LifeBots. Made with ❤️. All rights reserved.

LifeBots is not affiliated with Linden Research, Inc., or any of its affiliated entities or products, including, without limitation, Second Life (collectively, “Linden Lab”).

Initializing A New World of Second Life Bots...