Building an app or AI assistant that other people connect to their account? Let them sign in and click Allow, instead of copying an API key.
Use OAuth when people connect their own account to something you built: an AI assistant, a reporting tool, an agency dashboard. They sign in with us, see exactly what your app is asking for, and click Allow. Your app never sees their password, nobody has to copy a key around, and they can disconnect it whenever they like.
Only reading your own account? An API key is simpler: see Authentication.
Using an MCP client? It probably does all of this for you.
Claude, ChatGPT and most other MCP clients find our sign-in server on their own: give them the server address and they open the Allow page for the person. The steps below are for when you build the connection yourself.
Send your app's name and the address we should send people back to. You can register up to 10 return addresses. Keep the client id: it is not a secret, and there is no client secret.
First make a code verifier, a long random secret your app keeps, and its SHA-256 hash, the code challenge. Only the challenge goes in the link. Add a random state too, so you can check the answer is for the request you made.
Then open this link in their browser:
The page shows your app's name, where they will be sent back to, and what it can read: businesses, scans, rankings, reviews, listings and campaigns. A box, ticked to start with, lets it start scans and campaigns too, which use their credits. If they untick it, your app can only read.
We send them back to your return address with a code, your state, and our address as iss. Check that the state is yours before you go on. The code works once, for 10 minutes.
If they click Cancel, you get error=access_denied instead of a code.
Send the code with the code verifier from step 2. The answer has an access token, which lasts 1 hour, and a refresh token.
Send the access token as a Bearer token, just like an API key, to the MCP server or the REST endpoints.
When the access token runs out, use the refresh token to get a new pair. Each refresh token works once and lasts 90 days: always save the new one from the answer.
To disconnect from your side, revoke the refresh token. Its access token stops working too. The answer is always 200.
People can also see and disconnect every connected app themselves, in their dashboard under Settings > AI Assistants. After that, your tokens are refused with 401 and they have to connect again.
Everything starts at the two discovery documents, which list the others.
| Method | Path | What it is for |
|---|---|---|
| GET | /.well-known/oauth-protected-resource | Says which sign-in server protects the MCP server. Most clients start here. |
| GET | /.well-known/oauth-authorization-server | Lists every endpoint below and what they support. |
| POST | /oauth/register | Registers your app and gives it a client id. |
| GET | /oauth/authorize | The page where the person signs in and clicks Allow. |
| POST | /oauth/token | Swaps the code for tokens, and later refreshes them. |
| POST | /oauth/revoke | Ends a connection by revoking its token. |
The token and registration endpoints answer errors the standard OAuth way: an error code and a description you can log.
invalid_grant The code or refresh token is wrong, expired or already used, or the code verifier does not match. Start the sign-in again.invalid_client The client id is unknown, or the code was issued to another app.invalid_request A required field is missing.unsupported_grant_type Use authorization_code or refresh_token.invalid_redirect_uri A return address breaks the rules above (registration only).