Bot API docs

Login with Voicaw

Your website can let people log in with their Voicaw account. It's Discord's OAuth2 authorisation code grant, so a site that logs people in with Discord works with Voicaw by changing three addresses and its client id and secret. The only scope is identify: the person's id, username, display name and picture.

Setting up

  1. Make an application in the Developer Portal (every application also has a bot; you don't have to use it).
  2. Under OAuth2, make a client secret and copy it: it's shown once. It belongs on your server only, never in a web page or an app.
  3. Add your redirects: the exact addresses people come back to after logging in. They must be https (or http://localhost / 127.0.0.1 while testing), without a #fragment. Up to 10.

The addresses

WhatDiscord'sVoicaw's
Authorise (people's browser)https://discord.com/oauth2/authorizehttps://app.voicaw.com/oauth2/authorize
Token (your server)https://discord.com/api/oauth2/tokenhttps://api.voicaw.com/api/v10/oauth2/token
Who logged inhttps://discord.com/api/users/@mehttps://api.voicaw.com/api/v10/users/@me
Pictureshttps://cdn.discordapp.com/avatars/{id}/{avatar}.pnghttps://api.voicaw.com/api/cdn/avatars/{id}/{avatar}.png, or the user's avatar_url

Note the /api/v10: Voicaw's API has no unversioned /api/users/@me.

The flow

1. Send the person to the authorise page:

https://app.voicaw.com/oauth2/authorize?client_id=123&response_type=code&scope=identify
    &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&state=RANDOM

They log in to Voicaw if they aren't already, see your application, what it will know and where they'll go, and choose Authorise or Cancel. redirect_uri must be one of your redirects exactly (you may leave it out if you have only one). Make state a random value tied to the person's session and check it when they come back. With prompt=none, someone who has already let your application in goes straight back without being asked again.

2. They come back to your redirect with a code, or with error=access_denied if they cancelled:

https://example.com/callback?code=CODE&state=RANDOM

3. Your server trades the code for a token (a form, or JSON; the client id and secret in the body or as HTTP Basic):

POST /api/v10/oauth2/token
Content-Type: application/x-www-form-urlencoded

client_id=123&client_secret=SECRET&grant_type=authorization_code&code=CODE
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
{ "access_token": "…", "token_type": "Bearer", "expires_in": 604800, "refresh_token": "…", "scope": "identify" }

A code works once, within 10 minutes, for the application it was made for and with the same redirect_uri.

4. Ask who it is:

GET /api/v10/users/@me
Authorization: Bearer ACCESS_TOKEN
{ "id": "42", "username": "alice", "discriminator": "0", "global_name": "Alice", "avatar": "a1b2c3", "bot": false,
  "avatar_url": "https://…/profile-pics/42/a1b2c3.webp", "mfa_enabled": false, "locale": "en-GB", … }

Ids are Voicaw's (decimal strings, not snowflakes). There's no email: Voicaw doesn't have people's email addresses.

Tokens

EndpointNotes
POST /oauth2/tokengrant_type=authorization_code (code, redirect_uri) or refresh_token (refresh_token). Every answer has a new refresh token; the old pair stops working.
POST /oauth2/token/revoketoken (access or refresh): it and its pair stop working.
GET /users/@meWith Bearer: the person (identify).
GET /oauth2/@meWith Bearer: { application, scopes, expires, user }.

Access tokens last 7 days. A refresh token works once, until it's revoked, or until 30 days after its access token ran out. A login token opens only the two endpoints above: everything else in the bot API wants a bot token. Tokens stop working when the person removes your application under Settings → Authorised apps, when their account is deleted or suspended, and when you delete the application. Resetting the client secret doesn't log anyone out.

Errors are OAuth2's, not the bot API's:

{ "error": "invalid_grant", "error_description": "Invalid \"code\" in request." }

invalid_client (401: wrong id or secret), invalid_grant (a used, expired or someone else's code or refresh token), invalid_request, unsupported_grant_type. The token endpoints take 30 requests a minute from one address. Mistakes in the authorise link go back to your redirect as error=invalid_scope or unsupported_response_type; an unknown client or redirect is shown to the person instead, and they're never sent there.