Sign in with Sangho (OAuth2)
“Sign in with Sangho” lets your platform authenticate its users through their existing Sangho account, without ever handling their password — just like “Sign in with Google”. Sangho acts as an identity provider (OAuth2 authorization code flow with mandatory PKCE), separate from the pk_/sk_ API keys that authenticate your server calls to the Sangho API.
Canonical host: accounts.sangho.com. Integrations already configured on dash.sangho.com/o/… keep working (backward compatibility), but every new integration must use accounts.sangho.com.
1. Create an OAuth client
An OAuth client is created self-service from the API Keys tab of your Sangho dashboard: name, description, redirect URI. The client_secret (SANGHO_SECRET on your platform) is shown only once, at creation — store it immediately in your secrets manager.
A self-service client is never “trusted by default”: the Sangho consent screen is always shown each time a new user signs in. This is expected, not a configuration error.
2. Authorization flow (PKCE required)
| Step | Endpoint | Description |
|---|---|---|
| 1. Redirect the user | GET /o/authorize/ | With client_id, redirect_uri, response_type=code, scope, state, code_challenge, code_challenge_method=S256 |
| 2. Consent | — | The user signs in to Sangho (if needed) and then authorizes your application |
| 3. Callback | your redirect_uri | Sangho redirects with ?code=…&state=… (check state against CSRF) |
| 4. Exchange the code | POST /o/token/ | grant_type=authorization_code, code, redirect_uri, client_id, code_verifier |
| 5. Refresh | POST /o/token/ | grant_type=refresh_token, refresh_token, client_id |
| 6. Revoke | POST /o/revoke_token/ | token, client_id — invalidates an access or refresh token |
PKCE (code_challenge/code_verifier, S256 method) is mandatory, even for a confidential server-side client — the request is rejected without it. Access tokens expire after 1 hour, refresh tokens after 30 days.
3. Scopes and user profile
| Scope | Claims returned by /o/userinfo/ |
|---|---|
| profile | name, given_name, family_name, picture |
| email, email_verified |
GET /o/userinfo/ (with Authorization: Bearer <access_token>) always returns sub: a stable, opaque identifier (UUID), never the email address — use it as the long-term identity key on your platform, since an email can change.
4. Revocation and suspension
An OAuth client owner can suspend their client from the dashboard (suspend/activate): no new authorization or token exchange is accepted for that client_id, but an access token that has already been issued remains valid until it expires naturally (no immediate retroactive revocation) — like most OAuth2 providers.