OAuth authorization
Implement the Login with Blooio flow: authorize, exchange the code for tokens, and refresh them.
Blooio Apps use the OAuth 2.0 authorization code flow (with PKCE for public clients). This is the "Log in with Blooio" flow.
Base URL for OAuth endpoints: https://api.blooio.com
The authorization code flow end to end: authorize, exchange, and refresh. Click a step for details.
1. Redirect the user to authorize
Send the user to the authorize URL. They sign in to Blooio, pick which organizations to install your app on, and approve the requested scopes.
GET https://api.blooio.com/oauth/authorize
?client_id=bloapp_...
&redirect_uri=https://app.example.com/auth/callback
&response_type=code
&scope=messages:read messages:write contacts:read
&state=RANDOM_ANTI_CSRF_VALUEPublic (Native / SPA) clients must add PKCE:
&code_challenge=BASE64URL(SHA256(code_verifier))
&code_challenge_method=S256| Parameter | Required | Notes |
|---|---|---|
client_id |
yes | Your app's client ID. |
redirect_uri |
yes | Must exactly match a registered redirect URI. |
response_type |
yes | Always code. |
scope |
recommended | Space-delimited scopes; a subset of what your app registered. |
state |
recommended | Opaque value echoed back — verify it to prevent CSRF. |
code_challenge / code_challenge_method |
public clients | PKCE; S256 recommended. |
After the user approves, Blooio redirects to your redirect_uri with a single-use code (and your state):
https://app.example.com/auth/callback?code=blo_ac_...&state=RANDOM_ANTI_CSRF_VALUE2. Exchange the code for tokens
Exchange the authorization code for an access token and refresh token. Confidential clients authenticate with their secret; public clients send the PKCE code_verifier.
curl -X POST https://api.blooio.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "blo_ac_...",
"redirect_uri": "https://app.example.com/auth/callback",
"client_id": "bloapp_...",
"client_secret": "blosec_...",
"code_verifier": "ORIGINAL_PKCE_VERIFIER"
}'Response:
{
"access_token": "blo_at_...",
"refresh_token": "blo_rt_...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "messages:read messages:write contacts:read"
}Access tokens are short-lived; refresh tokens are long-lived. Store both securely.
3. Refresh an access token
curl -X POST https://api.blooio.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "blo_rt_...",
"client_id": "bloapp_...",
"client_secret": "blosec_..."
}'4. Revoke a token
curl -X POST https://api.blooio.com/oauth/revoke \
-H "Content-Type: application/json" \
-d '{ "token": "blo_at_...", "client_id": "bloapp_...", "client_secret": "blosec_..." }'Users can also revoke your app's access at any time from each organization's Integrations page, which immediately invalidates the tokens tied to that install.
Scopes
Scopes are grouped by resource. Request only what you need — sensitive scopes get a warning on the consent screen.
| Scope | Grants |
|---|---|
messages:read / messages:write |
Read / send messages, reactions, polls. |
chats:read / chats:write |
Read / manage chats, typing, read receipts. |
channels:read / channels:write |
Read / manage channels. |
contacts:read / contacts:write |
Read / manage contacts, identities, tags. |
numbers:read / numbers:manage |
Read numbers & risk / buy & remove numbers. |
apikeys:read / apikeys:manage |
Read / manage API keys. |
members:read / members:write |
Read / manage team members. |
webhooks:read / webhooks:write |
Read / manage webhooks. |
billing:read / billing:write |
Read / manage billing & payment methods. |
groups:read / groups:write |
Read / manage groups. |
events:read |
Read the org's event/audit log. |