Skip to content

Authentication

Send one credential in the Authorization header. Each operation states which credential types it accepts.

Failures use the standard error response. The Authentication HTTP API and OAuth2 HTTP API document how credentials are issued and revoked.

Credential types are not interchangeable

User session tokens, bot tokens, OAuth2 access tokens and webhook tokens are separate credentials. A value issued as one kind is never accepted as another.

Credential handling

Anyone holding a credential can act as its owner. Keep credentials out of logs, analytics, crash reports and source code, and keep them only as long as you need them. Always use TLS.

Never put an Authorization credential in a URL. For webhook URLs and upload URLs, treat the complete URL as a secret: do not expose it through redirects, logs or referrers.

Authorization header

Use one of the forms below. The scheme prefix is case-sensitive and must be followed by exactly one space.

Authorization schemes

Value Name Accepted by
Bot <token> Bot token Operations open to bots (see Bot tokens)
Bearer <token> User session token Every user operation
<token> User session token Same as Bearer <token>; the prefix may be omitted
Bearer <token> OAuth2 access token Only the operations listed under OAuth2 access tokens, each with its required scope

A user session token and an OAuth2 access token both use the Bearer scheme. TEBHOS tells them apart by the token's format. Sending a valid OAuth2 access token to an operation that is not listed for access tokens returns 403 ACCESS_DENIED.

# User session
curl https://tebhos.com/api/v1/users/@me \
  -H "Authorization: Bearer $TEBHOS_SESSION_TOKEN"

# Bot
curl https://tebhos.com/api/v1/users/@me \
  -H "Authorization: Bot $TEBHOS_BOT_TOKEN"

Token formats

Treat every token as an opaque string and send it unchanged.

Token Format
User session token An opaque 40-character ASCII string (a short fixed prefix followed by 36 letters and digits)
Bot token <application_id>.<secret>, where application_id is the application's snowflake
OAuth2 access token An opaque string returned by POST /oauth2/token

A secret is shown once

A bot token and an OAuth2 client secret are returned only by the response that creates or resets them. TEBHOS stores only a hash and cannot show the value again.

Resetting invalidates the previous value immediately

POST /oauth2/applications/{id}/bot/reset-token replaces the bot token, and POST /oauth2/applications/{id}/client-secret/reset replaces the client secret. The previous value stops working at once. See Applications.

User session tokens

A user session token authenticates an ordinary user account. Login and registration issue it. A session lasts until it is revoked: by logging out, by ending the session from the session list, by resetting the password, or by ending all sessions. A revoked session token is rejected immediately with 401 UNAUTHORIZED.

The Gateway accepts a session token in the Identify command.

Bot tokens

A bot token authenticates the bot account of an application. The bot account's user ID is the application ID. TEBHOS verifies the token by looking up the application named before the dot and checking the secret after it.

A bot can use every operation that accepts bot tokens, which covers the common bot workload: reading and sending messages, reactions, channels, members, roles and similar guild resources. An operation reserved for ordinary user accounts only accepts a user session token and answers a valid bot token with 403 ACCESS_DENIED (an invalid one with 401 UNAUTHORIZED). The Bots guide walks through a complete bot.

Two operations are bot-only:

  • GET /gateway/bot returns the Gateway URL for a bot and answers any credential other than a valid bot token with 401 UNAUTHORIZED. See Gateway HTTP API.
  • GET /applications/@me returns the application that owns the bot token. See Applications.

On HTTP a bot token must carry the Bot prefix. Without it the value is read as a user session token and the request fails with 401 UNAUTHORIZED.

The Gateway accepts a bot token in Identify, either bare or with the same Bot prefix.

OAuth2 access tokens

An OAuth2 access token is issued to an application by the authorization code flow in the OAuth2 HTTP API. It is sent as Authorization: Bearer <token> and is limited to the scopes it was granted.

TEBHOS accepts an access token on the OAuth2 resource operations and on a small set of read operations, each with a required scope:

Operation Scope
GET /oauth2/@me Any; the user object is included only with identify, and email only with email
GET /oauth2/userinfo identify (email adds the address)
GET /users/@me identify. email is null unless the token also holds email, and account-security and billing fields are neutralised
GET /users/@me/guilds guilds
GET /guilds/{guild_id} guilds
GET /guilds/{guild_id}/roles guilds
GET /users/@me/connections connections

On these operations the token acts as the user it was issued to, with the same membership and permission checks as a session.

Situation Response
Valid access token without the operation's scope 403 MISSING_OAUTH_SCOPE; the error body carries required_scope with the missing scope name
Valid access token on any operation not listed above 403 ACCESS_DENIED
Unknown, expired or revoked access token 401 UNAUTHORIZED
{
  "code": "MISSING_OAUTH_SCOPE",
  "message": "Missing required OAuth2 scope: guilds",
  "required_scope": "guilds"
}

GET /oauth2/userinfo answers a token without the identify scope with 403 MISSING_OAUTH_SCOPE as well, but without the required_scope field.

Authorization outcomes

Situation Response
Missing Authorization header on a protected operation 401 UNAUTHORIZED
Malformed header, unknown, expired or revoked credential 401 UNAUTHORIZED
Valid bot token on a user-only operation 403 ACCESS_DENIED
Valid OAuth2 access token on an operation that does not accept access tokens 403 ACCESS_DENIED
Valid OAuth2 access token without the operation's scope 403 MISSING_OAUTH_SCOPE
Valid identity without the required permission or access 403 FORBIDDEN or a more specific code such as MISSING_PERMISSIONS or MISSING_ACCESS
Operation that requires recent re-verification 403 SUDO_MODE_REQUIRED (see Sudo mode)

A 401 has no WWW-Authenticate header, so clients must read the code in the body. The message is human-readable and may be localized; do not parse it.

A credential can also change the behaviour of an operation that does not require one: it selects the caller's own rate limit buckets instead of the IP-based ones.

Failed authentication

Authentication errors do not say whether a credential was unknown, expired, revoked or malformed. Stop retrying a rejected credential and obtain a new one. Repeated failed logins are throttled by the login rate limits described in Rate limits.

A login from a new location can be held for email confirmation. POST /auth/login then returns 403 with the code IP_AUTHORIZATION_REQUIRED and a ticket; see Authentication HTTP API.

Sudo mode

Some sensitive account operations, such as changing a password, deleting the account, resetting a bot token or managing multi-factor authentication, require the account holder to re-verify. Such an operation returns 403 SUDO_MODE_REQUIRED when no proof is present.

TEBHOS accepts two forms of proof:

  • Inline proof in the request body of the sensitive operation: mfa_code (a TOTP or backup code) for an account with multi-factor authentication, a sudo_proof obtained from a passkey assertion, or password for an account without multi-factor authentication.
  • A sudo grant created by POST /auth/sudo. A grant lasts five minutes and is bound to the session that created it, so it does not elevate requests made with another session.

Multi-factor authentication documents the accepted methods. Sudo mode applies to user session tokens only; operations that require it are not available to bots.

Gateway authentication

Send a bot token or a user session token in the Identify command, not in an Authorization header. An invalid or revoked credential closes the connection with close code 4004 (authentication failed). See Opcodes and close codes.

Other credential surfaces

A webhook execution operation carries the webhook ID and token in its path and needs no Authorization header. Webhooks defines that contract.

Public media routes such as avatars, icons and attachments are addressed by their path and read no Authorization header. Upload URLs returned by Attachment uploads are themselves the credential for one upload and must be used without an Authorization header.