Authentication
The OAuth 2.0 authorization-code flow: the install URL, the callback, the code exchange, calling the API, refreshing tokens and revocation.
Blue Reacher uses the OAuth 2.0 authorization-code flow with stateless JWT tokens. This page covers the moving parts. To send a text message from your own server with one header instead, use a dashboard key on POST /v1/send. The per-endpoint pages give the exact request and response shapes.
Roles
| Role | Who |
|---|---|
| Resource owner | The Blue Reacher user whose data you read and write. |
| Client | Your app, registered on the Custom integration page or by Blue Reacher support. It holds a client_id and a client_secret. |
| Authorization server | Blue Reacher. It issues codes and tokens. |
| Resource server | The Blue Reacher API. It validates the Bearer token on every call. |
1. The install URL
https://app.bluereacher.com/integrations/install/<CLIENT_ID>?redirect_uri=<YOUR_CALLBACK>&state=<RANDOM>This is a dashboard URL, not an API URL. Redirect the user's browser to it. The user sees a consent screen listing the scopes your app requests. If they are not signed in, Blue Reacher sends them to the login page first and brings them back after sign-in.
state is optional. It is passed through untouched and returned on the callback, so use it as your CSRF token.
2. The callback
On Install, the browser comes back to your redirect_uri with a code:
HTTP/1.1 302 Found
Location: https://your-app.com/oauth/callback?code=4f8a7e1d2c9b3a5f6e0d1c2b7a8f9e6d&state=<YOUR_STATE>Authorization codes are short, opaque, single-use and expire 10 minutes after consent. Exchange the code right away. A second exchange with the same code is rejected, so treat a code as consumed the moment you use it.
On Cancel, the browser comes back with an error and no code:
HTTP/1.1 302 Found
Location: https://your-app.com/oauth/callback?error=access_denied&error_description=The+user+declined+the+installation.&state=<YOUR_STATE>Nothing is installed. Let the user start again from the install URL.
3. Exchange the code
Server to server. Send the code with your client_id and client_secret.
curl -X POST https://api.bluereacher.com/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "<CODE_FROM_CALLBACK>",
"client_id": "<YOUR_CLIENT_ID>",
"client_secret": "<YOUR_CLIENT_SECRET>",
"redirect_uri": "https://your-app.com/oauth/callback"
}'{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400,
"scopes": ["contacts.read", "contacts.write"]
}
}Store both tokens in your database, keyed by the installing user.
| Status | Body | Meaning |
|---|---|---|
400 | {"success": false, "message": "Invalid or expired authorization code"} | The code is wrong, or older than 10 minutes. |
400 | {"success": false, "message": "Authorization code has already been used. Re-start the install to get a fresh code."} | The code was exchanged before. |
If the exchange times out or returns a 5xx, retry it once. If the retry reports the code as already used, the first attempt was processed and its tokens cannot be recovered. Send the user through the install URL again.
4. Calling the API
Send the access token in the Authorization header on every request.
curl https://api.bluereacher.com/v1/integration/me \
-H "Authorization: Bearer <ACCESS_TOKEN>"Tokens are bound to the installer. A token can only reach the workspaces, contacts and messages that belong to the user who installed your app. Every endpoint declares the scope it needs. See Scopes.
5. Refresh
When the API answers 401, the access token has expired or is invalid. Call the token endpoint with your stored refresh token to get a fresh pair.
curl -X POST https://api.bluereacher.com/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "refresh_token",
"refresh_token": "<REFRESH_TOKEN>",
"client_id": "<YOUR_CLIENT_ID>",
"client_secret": "<YOUR_CLIENT_SECRET>"
}'The response has the same shape as the code exchange. Replace both stored tokens with the new values.
- Access tokens last 24 hours (
expires_in). Refresh tokens last 365 days. - Every refresh returns a new refresh token, but tokens are stateless signed JWTs, so the previous refresh token is not invalidated by rotation. It stays usable until its own expiry, or until the installation is revoked. Keep only the newest pair.
- Because the old token stays valid, a refresh that times out or returns a
5xxis safe to retry with exponential backoff. - The token endpoint is outside the per-installation rate limits and never answers
429.
Token formats and the JWT claims are on Token format.
Revocation
Blue Reacher can revoke an installation at any time. Every token issued for that install then fails with 401 on the next request. The user has to go through the install URL again to re-consent and get fresh tokens.
There is no client-facing uninstall endpoint yet. If you drop an installation on your side, discard its tokens and contact support to have the installation suspended.
Keep secrets on the server
The client_secret, access tokens and refresh tokens are production credentials. Keep them server-side, never in browser or mobile code, never in a repository. Store them in environment variables or a secret manager.

