The OAuth2 surface is split into two hosts: protocol endpoints at the issuer (Documentation Index
Fetch the complete documentation index at: https://docs.busha.io/llms.txt
Use this file to discover all available pages before exploring further.
login.busha.io) and the resource API (api.busha.io). OAuth app management — creating apps, revealing secrets, editing redirect URIs — is dashboard-only at app.busha.io.
| Method | Endpoint | Purpose |
|---|---|---|
GET | /oauth2/auth | Start an authorization request (browser redirect). |
POST | /oauth2/token | Exchange a code for tokens, or refresh an existing session. |
POST | /oauth2/revoke | Revoke an access or refresh token. |
GET | /.well-known/openid-configuration | OIDC discovery document. |
GET | /.well-known/jwks.json | Public keys for JWT signature verification. |
GET /oauth2/auth
Browser redirect — this is where you send the user’s browser to start authorization. Never call this server-to-server.
Required query parameters:
| Parameter | Value |
|---|---|
response_type | code |
client_id | Your app’s client_id |
redirect_uri | Byte-identical to a registered URI |
scope | Space-separated scope list |
state | CSRF guard — at least 16 random bytes, bound to the user’s session |
code_challenge | base64url(sha256(code_verifier)) |
code_challenge_method | S256 — plain is not accepted; missing challenges are rejected |
?code=...&state=...
User cancelled: Redirects with ?error=access_denied&state=...
POST /oauth2/token
Server-to-server. Authenticate with HTTP Basic using client_id:client_secret. Never call this from the browser.
Authorization code → tokens
Refresh token → new pair
id_tokenis returned only whenopenidis in the granted scopes.refresh_tokenis returned only whenoffline_accessis granted.redirect_urimust exactly match a registered URI.- Authorization codes are single-use and expire in 10 minutes.
- Token exchange is not idempotent — if your callback handler runs twice, the second call returns
invalid_grant.
authorization_code (with PKCE-S256) and refresh_token only. Implicit, resource-owner password, and client_credentials are not supported.
POST /oauth2/revoke
Revoke an access or refresh token. Call this when a user disconnects your integration.
200 with an empty body regardless of whether the token was valid — this is intentional to avoid leaking token validity information.
Revoking a refresh token kills future refreshes immediately but does not invalidate a currently-issued access token. The access token continues to validate until
exp.GET /.well-known/openid-configuration
The OIDC discovery document. Contains the canonical issuer string and the URLs of all protocol endpoints.
issuer value from this document at startup and pin your JWT validation against it. Do not hardcode the issuer string.
GET /.well-known/jwks.json
The public key set used to verify JWT signatures.
kid in a JWT header that is not present in your cache.