OAuth & Social Login API
REST API endpoints for OAuth provider configuration and social login flows.
OAuth & Social Login API
HelloJohn supports OAuth 2.0 / OIDC-based social login. Providers are configured per tenant. The authentication flow follows the standard Authorization Code flow with PKCE.
OAuth Flow Overview
1. Frontend redirects user → /v1/auth/oauth/:provider/authorize
2. User authenticates with provider
3. Provider redirects back → /v1/auth/oauth/:provider/callback
4. HelloJohn issues access + refresh tokens
5. User is redirected to your redirect_uri with tokensGET /v1/auth/oauth/:provider/authorize
Initiate an OAuth login flow. This is a redirect endpoint — navigate the user's browser to this URL.
Path parameters:
| Parameter | Description |
|---|---|
provider | google, github, microsoft, apple, facebook, twitter, linkedin, discord |
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
redirect_uri | string | ✅ | Where to send the user after auth |
state | string | ✅ | Random string for CSRF protection |
code_challenge | string | ✅ | PKCE challenge (SHA-256 of code_verifier) |
code_challenge_method | string | ✅ | Must be S256 |
connection_id | string | — | For SSO with a specific connection |
organization_id | string | — | Pre-select organization context |
https://api.hellojohn.dev/v1/auth/oauth/google/authorize
?redirect_uri=https://app.example.com/auth/callback
&state=abc123
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256Using SDK (recommended):
import { HelloJohn } from "@hellojohn/js";
const hj = new HelloJohn({ publishableKey: "pk_live_..." });
// Initiates redirect automatically
await hj.oauth.signIn("google", {
redirectUri: "https://app.example.com/auth/callback",
});POST /v1/auth/oauth/:provider/callback
Exchange the authorization code for tokens. Called server-side or from the redirect handler.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
code | string | ✅ | Authorization code from provider |
code_verifier | string | ✅ | PKCE code verifier |
redirect_uri | string | ✅ | Must match the original redirect_uri |
state | string | ✅ | Must match the original state |
curl -X POST "https://api.hellojohn.dev/v1/auth/oauth/google/callback" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"code": "4/0AeaYSHAB...",
"code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"redirect_uri": "https://app.example.com/auth/callback",
"state": "abc123"
}'Response: 200 OK
{
"access_token": "eyJhbGciOiJFZERTQSJ9...",
"refresh_token": "rt_01HABCDEF...",
"expires_in": 3600,
"user": {
"id": "usr_01HABCDEF123456",
"email": "alice@example.com",
"name": "Alice Smith",
"avatar_url": "https://lh3.googleusercontent.com/...",
"created": false
}
}The user.created flag indicates whether a new account was created (true) or an existing account was signed into (false).
OAuth Provider Object
{
"id": "op_01HABCDEF111000",
"provider": "google",
"enabled": true,
"client_id": "123456789.apps.googleusercontent.com",
"scopes": ["openid", "email", "profile"],
"created_at": "2024-01-10T09:00:00Z"
}GET /v1/oauth/providers
List all configured OAuth providers for the tenant.
curl "https://api.hellojohn.dev/v1/oauth/providers" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Response:
{
"data": [
{
"id": "op_01HABCDEF111000",
"provider": "google",
"enabled": true,
"client_id": "123456789.apps.googleusercontent.com",
"scopes": ["openid", "email", "profile"]
}
]
}POST /v1/oauth/providers
Add a new OAuth provider.
Body:
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | ✅ | Provider name |
client_id | string | ✅ | OAuth app client ID |
client_secret | string | ✅ | OAuth app client secret |
scopes | array | — | Additional scopes beyond openid email profile |
curl -X POST "https://api.hellojohn.dev/v1/oauth/providers" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"provider": "github",
"client_id": "Ov23lixxxxxxxx",
"client_secret": "secret_xxxx"
}'Response: 201 Created — Returns provider object (without client_secret).
PATCH /v1/oauth/providers/:id
Update an existing provider configuration.
Body (all optional):
| Field | Type | Description |
|---|---|---|
client_id | string | New client ID |
client_secret | string | New client secret |
scopes | array | New scopes list |
enabled | boolean | Enable or disable the provider |
DELETE /v1/oauth/providers/:id
Remove an OAuth provider. Users who signed up with this provider will retain their account but cannot use this provider to sign in until it's re-added.
Response: 204 No Content
GET /v1/users/:user_id/oauth/connections
List all OAuth connections for a user (which providers they've authenticated with).
curl "https://api.hellojohn.dev/v1/users/usr_01HABCDEF123456/oauth/connections" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Response:
{
"data": [
{
"id": "con_01HABCDEF222111",
"provider": "google",
"provider_user_id": "109876543210",
"email": "alice@gmail.com",
"connected_at": "2024-01-10T09:00:00Z"
}
]
}DELETE /v1/users/:user_id/oauth/connections/:connection_id
Disconnect a user's OAuth connection. The user must have a password or another connection to sign in.
Response: 204 No Content