API documentation
Integrate OAuth 2.0 authorization code flow with Sushii OAuth.
Raw file (recommended)
https://oauth.sushii.dev/sushii-oauth-integration.mdGitHub raw (same content)
https://raw.githubusercontent.com/codingsushi79/oauth.sushii.dev/main/public/sushii-oauth-integration.mdPrompt to copy
Integrate Sushii OAuth into this app using the official integration guide:
https://oauth.sushii.dev/sushii-oauth-integration.md
Use authorization code flow. Store client_id and client_secret in env vars.
My redirect URI is: https://yourapp.com/auth/callback
My stack is: [your framework]Sushii OAuth is a universal identity layer. You create a project in the console, receive a client_id and client_secret, then redirect users to our authorize endpoint. After the user picks a sign-in method and authenticates, they return to your redirect URI with an authorization code you exchange for user data.
Redirect the user's browser to:
https://oauth.sushii.dev/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&state=RANDOM_STATE- client_id — from your console
- redirect_uri — must match a registered URI exactly
- response_type — must be
code - state — CSRF token you verify on callback
The user sees your project name, available sign-in methods, and a clear list of data fields your app will receive (email, name, avatar, provider ID — whatever you configured). They pick a provider and complete authentication.
On success, the user is redirected to your redirect_uri:
YOUR_REDIRECT_URI?code=AUTHORIZATION_CODE&state=RANDOM_STATEVerify state matches what you sent. The code expires in 5 minutes and is single-use.
Exchange the authorization code server-side. Never expose your client secret in client-side code.
POST https://oauth.sushii.dev/api/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&redirect_uri=YOUR_REDIRECT_URISuccessful response:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"provider": "google",
"user": {
"email": "user@example.com",
"name": "Jane Doe"
}
}If you configure a webhook URL, we POST a signed event to your server immediately after authentication — before redirecting the user. This lets you provision accounts server-side in real time.
Headers
X-Sushii-Timestamp— Unix timestamp (seconds)X-Sushii-Signature— HMAC-SHA256 hex digest
Signature verification
const signed = timestamp + "." + rawBody;
const expected = HMAC_SHA256(client_secret, signed);
// Compare expected to X-Sushii-Signature using timing-safe comparePayload
{
"event": "auth.completed",
"project_id": "uuid",
"provider": "github",
"user": { "email": "...", "name": "..." },
"timestamp": "2026-06-09T12:00:00.000Z"
}Reject requests older than 5 minutes. Always verify the signature before trusting payload data.
Every project starts on the Basic plan with 3,000 successful sign-ins per month (UTC).
Pro — self-service upgrade
- 10,000 requests/month
- $5/month or $54/year (10% off)
- Upgrade from your project page in the console
Ultra — high volume
- 50,000 requests/month
- $25/month or $270/year (10% off)
- Choose Ultra when creating a project, then subscribe
Each project has a monthly limit on successful OAuth sign-ins (default 3,000). Usage resets on the 1st of each month (UTC). View your current usage in the console.
- Store client secrets in environment variables only.
- Always validate redirect URIs and state on your backend.
- Use HTTPS for redirect URIs and webhooks in production.
- Authorization codes and access tokens are single-use / time-limited.
- Upstream OAuth credentials (Google, GitHub, Discord, Twitch, GitLab) are managed platform-wide — integrators never need their own provider keys.
Ready to integrate? Create an account and open the console.