API Authentication
The complete guide to getting an access token — Personal Access Token, password grant, and authorization code — with setup steps, lifetimes, and troubleshooting.
Every API call is authenticated with an OAuth 2.0 Bearer token:
Authorization: Bearer <bearer-token>
There are two scenarios:
- API authentication — your server calls our APIs directly. Use a Personal Access Token (simplest — generated in the dashboard) or client password credentials (one request with app credentials plus a user's sign-in).
- Browser sign-in — people sign in to Review Management from your platform; they enter their password on our page, never in your app.
Every method yields a token with the access level of the user behind it: an account user's token sees that account, a partner Owner or Admin's token has partner-level access. All three tokens can also open the portal with no second sign-in (the rs-sso-login handoff). JumpCloud is separate — see JumpCloud SSO.
Choose your method
| # | Method | Best when | Token lifetime | Needs app credentials? |
|---|---|---|---|---|
| 1 | Personal Access Token | Calling the API as yourself — scripts, integrations, testing | Never expires (rotate by regenerating) | No |
| 2 | Password grant (client password credentials) | Your server holds a user's credentials — trusted, first-party integrations | 24 hours + 30-day refresh token | Yes |
| 3 | Authorization code (browser sign-in) | Other people sign in to your app — they enter their password on our page, never in yours | 24 hours + 30-day refresh token | Yes |
Before you start
Everything below uses these two addresses:
- Base URL:
https://production-api.shoutaboutus.com - Portal: your portal URL (or your white label domain)
The Personal Access Token method needs no app credentials — it's generated directly on the API Keys page. The other two methods use app credentials, which give you three things:
| Item | What it is |
|---|---|
client_id | Your app's public identifier. Safe to include in URLs. |
client_secret | Your app's password. Shown only once when the credentials are created — store it somewhere safe, server-side only. |
redirect_uri | The page on your app where users return after signing in, e.g. https://yourapp.com/callback. Needed for browser sign-in only, and it must match exactly later — including https and any trailing slash. Leave blank for the other methods. |
Create your app credentials
Needed for the password grant and browser sign-in (skip this for the Personal Access Token):
- Sign in to the dashboard and open the API Keys page.
- Click Add credentials on the App credentials card, give your app a name, and enter your callback URL (browser sign-in only).
- Copy the
client_idandclient_secretshown — the secret is displayed only this once. If you lose it, create new credentials and update your app.
1 · Personal Access Token
A long-lived token tied to your own user account — ideal for calling our APIs from scripts and integrations without any sign-in flow.
Generate it from the dashboard:
- Open the API Keys page.
- Click Manage token on the Personal access token card.
- Click Generate token, then Copy token.
Unlike a client secret, the token stays viewable — reopen the dialog any time to copy it again. Each user has one active Personal Access Token; the dialog shows when it was generated.
Use it — a worked example:
curl -s "https://production-api.shoutaboutus.com/api/v1/verify-token" \
-H "Authorization: Bearer <your-personal-access-token>" \
-H "Accept: application/json"A successful response returns your user and account details — you're ready to call the rest of the API. The same token also opens the portal via the rs-sso-login handoff (not JumpCloud).
Validity and rotation:
- The token does not expire — it stays valid until you regenerate it.
- Click Regenerate token to rotate it at any time — the previous token stops working the moment the new one is created, so update your integration straight after. Rotating periodically is good practice for a long-lived key.
- A temporary account lock (from failed sign-in attempts) does not disable an existing token. To cut off access immediately, regenerate the token or call
GET /api/v1/sso/revoking-tokenwith the token as the Bearer header.
2 · Password grant (client password credentials)
Your server exchanges a user's email and password for a token directly — no browser, no redirect. The token acts as that user, with the same access level and refresh token as browser sign-in.
Use this only where you legitimately hold the credentials — your own account, or a trusted internal integration. When other people sign in to your app, use browser sign-in (method 3) so they never type their Review Management password into your app.
Request a token from your server — POST https://production-api.shoutaboutus.com/oauth/token as application/x-www-form-urlencoded (note: this endpoint sits at the server root, not under /api/v1):
grant_type=password
client_id=<client-id>
client_secret=<client-secret>
username=<user-email>
password=<user-password>
scope=*
You get back:
{
"token_type": "Bearer",
"expires_in": 86400,
"access_token": "<access-token>",
"refresh_token": "<refresh-token>"
}access_token— valid for 24 hours (expires_inis in seconds).refresh_token— get fresh access tokens for up to 30 days without asking the user to sign in again (see Keeping the session alive below).- Accounts that are temporarily locked or restricted to SSO sign-in are rejected with
invalid_grant— the same response as a wrong password. Tokens issued before a lock keep working until they expire or are revoked.
Use it like any other token — send Authorization: Bearer <access-token> on API calls, or hand the user off to the portal (see Browser sign-in step 4).
Endpoint reference: OAuth 2.0 — Password Grant.
3 · Authorization code (browser sign-in)
Users sign in with their Review Management email and password on our page, and your server receives a token that acts as that user. Four steps:
Step 1 — Send the user to our sign-in page. When the user clicks "Sign in with Review Management" in your app, open this URL in their browser:
https://production-api.shoutaboutus.com/oauth/authorize
?client_id=<client-id>
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=*
&state=<random-string>
stateis a random text you make up and remember for this sign-in attempt. You'll check it again in step 2 — it proves the response really belongs to your request.scopemust be*— it's the only value we accept today.- If the user isn't signed in yet, they sign in first, then approve your app's access on the authorization screen.
- A user whose account is temporarily locked (after repeated failed sign-ins) can't pass this screen until the lock clears — locks start at 1 minute and grow to a 15-minute maximum, then lift automatically.
Step 2 — The user comes back with a code. After approving, the user lands back on your redirect_uri, like https://yourapp.com/callback?code=…&state=…. First check that state matches the value you sent in step 1. The code is single-use and expires after about 10 minutes — exchange it straight away.
Step 3 — Swap the code for a token. From your server (not the browser), send POST https://production-api.shoutaboutus.com/oauth/token with these form fields:
grant_type=authorization_code
client_id=<client-id>
client_secret=<client-secret>
redirect_uri=https://yourapp.com/callback
code=<code-from-step-2>
The response is the same shape as the password grant: an access_token valid 24 hours and a refresh_token valid 30 days.
Step 4 — Use the token. Two ways:
- Call our APIs — add
Authorization: Bearer <access-token>to each request. A good first call:GET /api/v1/verify-token. - Open Review Management already signed in — hand the user's browser to
<portal-url>/rs-sso-login/?token=<access-token>. The portal validates the token and starts the user's session (SSO portal login).
Full endpoint walkthrough: Browser sign-in — Review Management login.
Keeping the session alive
Getting a new token when it expires — for the password grant and browser sign-in: send grant_type=refresh_token with your refresh_token, client_id and client_secret to the same /oauth/token address. No user interaction needed. Refresh tokens work for 30 days. Personal Access Tokens have no refresh token — regenerate from the dashboard instead.
Signing the user out — cancel a token before it expires (for example on logout):
GET https://production-api.shoutaboutus.com/api/v1/sso/revoking-token
Authorization: Bearer <access-token>
Checklist before going live
- Your
redirect_uriis registered and matches exactly what your app sends (browser sign-in). - You check
statewhen the user returns (browser sign-in, step 2) — it protects your users against forged sign-ins. - Tokens live on your server only — never in page URLs or browser storage. The one exception is the one-time portal handoff link.
client_secretnever appears in logs, error messages, or anything sent to the browser.
Troubleshooting & common questions
Which method should I use?
Calling our APIs as yourself → Personal Access Token. Your server acting for a user whose credentials you hold → password grant. Other people signing in to your app → browser sign-in. All three produce a user token; the access level always follows the user behind it.
I lost my client_secret. Can I see it again?
No — it's shown only once, when the credentials are created. Create new credentials and update your app. (Personal Access Tokens are different: they stay viewable in the dashboard.)
Does locking an account cut off its tokens?
No. A temporary lock (from repeated failed sign-ins) stops new sign-ins and new password-based token requests, but tokens issued earlier keep working until they expire. To cut off access immediately, revoke the token or regenerate the Personal Access Token.
I get an invalid_scope error.
Use scope=* — named scopes aren't supported.
The sign-in page says my redirect URI is invalid.
The redirect_uri in your sign-in URL must match one of the callback URLs saved with your credentials, character for character — including https:// and any trailing slash. Edit the credentials on the API Keys page to update the saved URLs.
The token exchange fails with invalid_grant.
For browser sign-in: the one-time code was already used or has expired (codes last about 10 minutes) — restart from step 1. For the password grant: the email or password is wrong, or the account is temporarily locked or restricted to SSO sign-in.
How do I know which sign-in methods a user's account supports?
Call Discover auth methods with the user's email address — the response lists the sign-in methods available for that account.
Updated about 2 hours ago
