OAuth for apps
Build a third-party app that other SaaSFlow companies can install — OAuth 2.1 + PKCE.
If you're building an integration that other SaaSFlow companies install on their own account (not your own scripts), use the OAuth flow. SaaSFlow is the authorization server; your app is the client.
At a glance
- Flow: OAuth 2.1 Authorization Code + PKCE.
- Authorization server:
https://api.saasflow.com/auth - Scopes:
saasflow:read,saasflow:write. - Token type: JWT bearer.
Register your app
OAuth client registration is currently a manual step — email support@saasflow.com with:
- App name
- Redirect URI(s)
- Logo (optional, shown on the consent screen)
- Requested scopes
You'll receive a client_id to use in the flow below.
The flow
Generate PKCE pair
import { randomBytes, createHash } from 'crypto';
function base64url(buf: Buffer) {
return buf.toString('base64').replace(/=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
}
const verifier = base64url(randomBytes(32));
const challenge = base64url(createHash('sha256').update(verifier).digest());
const state = base64url(randomBytes(16));Redirect to the authorize endpoint
https://api.saasflow.com/auth/oauth2/authorize?
response_type=code
& client_id=YOUR_CLIENT_ID
& redirect_uri=https%3A%2F%2Fyour-app.com%2Foauth%2Fcallback
& scope=saasflow%3Aread%20saasflow%3Awrite
& state=STATE
& code_challenge=CHALLENGE
& code_challenge_method=S256The user signs in at app.saasflow.com (if not already), picks which company to grant
access to, and approves the scopes.
Handle the callback
SaaSFlow redirects to your redirect_uri with code and state. Verify state
matches what you sent.
Exchange code for token
POST https://api.saasflow.com/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=THE_CODE
&redirect_uri=https://your-app.com/oauth/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=THE_VERIFIERResponse:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"scope": "saasflow:read saasflow:write",
"expires_in": 3600,
"refresh_token": "..."
}Call the API
curl https://api.saasflow.com/companies \
-H "Authorization: Bearer eyJ..."Refresh
When expires_in runs out, POST the same /auth/oauth2/token endpoint with
grant_type=refresh_token and the stored refresh_token.
Permission scoping
A token's effective permissions are the intersection of:
- The granted scope (
saasflow:readorsaasflow:write). - The granting user's permissions at consent time.
- Live revocation status (we re-check the consent grant on every request).
*:manage permissions are never granted via OAuth. Use an API key created by an owner
for admin operations.
userinfo
GET https://api.saasflow.com/auth/oauth2/userinfo
Authorization: Bearer eyJ...Returns { sub, email, name } for the user that granted consent.
Revocation
Users can revoke your app from Settings → Company settings → API keys in the
SaaSFlow app. The next request with that token returns 401.