OAuth Flow
EDS implements the Authorization Code flow. Your app redirects employees to EDS to log in, then receives a short-lived code it exchanges for a session token.
Authorization Code Flow
Your App
GET /oauth/authorize
Employee Logs In
Consent Screen
Redirect to Your App with Code
POST /oauth/token
Session Token Received
POST /oauth/introspect (repeat as needed)
Endpoints#
Start the OAuth flow
Exchange code for session token
Check if a session is valid
Revoke a session token
Mint a fresh Google access token for the user
Security Notes#
- *Always validate the state parameter in the callback to prevent CSRF attacks.
- *Exchange codes server-side — never expose your API key to the browser.
- *Store session tokens in httpOnly cookies to prevent XSS theft.
- *Call /api/v1/oauth/revoke when an employee logs out of your app.
- *When an employee is deactivated in EDS, all their active sessions are automatically revoked.
- *Authorization codes are single-use and expire after 5 minutes.
Error Codes#
| Code | Description |
|---|---|
| INVALID_REQUEST | Request body is missing or not valid JSON. |
| VALIDATION_ERROR | Request body failed schema validation (missing or invalid fields). |
| INVALID_GRANT | Authorization code is invalid, expired, already used, or redirect_uri doesn’t match. |
| UNAUTHORIZED | Missing or invalid API key in x-api-key header. |
| access_denied | Employee denied consent or their account is inactive (returned as redirect query param). |
| invalid_scope | Requested scope is not a known identifier or is not on the API key's allowlist (redirect query param on /authorize). |
| INVALID_SESSION | Session token is missing, expired, revoked, or its employee is no longer active (returned by /google/access-token). |
| INSUFFICIENT_SCOPE | Session was not issued with any Google scopes, or the requested scope is not a subset of the session's granted scopes. |
| GOOGLE_REAUTH_REQUIRED | User has revoked EDS at Google. Redirect them back through /authorize with the same scope to re-consent. |