> For the complete documentation index, see [llms.txt](https://docs.autentique.com.br/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.autentique.com.br/api/integration-basics/oauth2/oauth-errors-and-security.md).

# OAuth errors and security

OAuth errors can occur during authorization, token exchange or refresh, and GraphQL API calls.

Do not try to fix an error by reusing old authorization codes, sessions, or tokens. When an attempt cannot be recovered securely, start a new authorization.

### Errors during authorization

These errors are returned to the redirect URL.

| Situation                     | What to do                                                                                                                                                                                                           |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error=access_denied`         | The user may have denied access, deselected all permissions, or received a request without valid scopes. Explain that the connection was not completed and offer another attempt only if the user wants to continue. |
| `error=login_required`        | This may happen when the request uses `prompt=none`. This parameter is not supported. Start a standard browser authorization without `prompt=none`.                                                                  |
| `error=invalid_scope`         | Confirm that the scopes exist, are enabled for the OAuth application, and were sent separated by spaces.                                                                                                             |
| `error=invalid_client`        | Check the Client ID, confirm that the OAuth application is still active, and verify that the redirect URL exactly matches the registered value.                                                                      |
| Missing or mismatched `state` | Discard the callback and the authorization session. Do not use the received authorization code.                                                                                                                      |

Receiving fewer permissions than requested is not necessarily an error. A user may grant only a subset. Your integration must operate within the access actually granted.

### Errors during authorization code exchange

The `/oauth/token` endpoint returns an OAuth error and, in some cases, a `hint` with more details.

| Situation                                               | What to do                                                                                                  |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `error=invalid_client` or HTTP 401                      | Check the Client ID and Client Secret, and confirm that the OAuth application is active.                    |
| `error=invalid_request` indicating an invalid URL       | Send exactly the same `redirect_uri` that was registered and used when authorization began.                 |
| Missing, expired, revoked, or reused authorization code | Start a new authorization. Authorization codes are temporary and single-use.                                |
| Authorization code issued to another client             | Use the credentials for the same OAuth application that started authorization.                              |
| Missing or malformed `code_verifier`                    | Send the verifier from the same attempt, with 43 to 128 characters.                                         |
| `error=invalid_grant` with a PKCE verification failure  | The `code_verifier` does not match the `code_challenge`. Discard the attempt and start a new authorization. |

### Errors during refresh

If the `refresh_token` is rejected:

1. Confirm that the integration is using the latest value.
2. Check whether another request has already refreshed the tokens.
3. Stop automatic retries with the same value.
4. Ask the user to authorize again if the token expired or was revoked.

Do not indefinitely retry a refresh request that returned an error. This will not recover the token and can hide a concurrency or revocation problem.

### Errors from the GraphQL API

| Response                                        | Possible cause                                                                                                                            |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| HTTP 401 with `{"message":"unauthorized"}`      | The `access_token` is missing, invalid, expired, or revoked. Try refreshing the tokens. If refresh fails, request a new authorization.    |
| HTTP 200 with `errors[].message="Unauthorized"` | The token was accepted, but the required permission was not granted or the operation does not support OAuth. Check the operation's scope. |

Because GraphQL can return errors with HTTP 200, also inspect the response's `errors` field.

### Security checklist

Before releasing the integration, confirm:

* [ ] The Client Secret exists only on the backend.
* [ ] Redirect URLs use HTTPS in production.
* [ ] The redirect URL sent and received is compared exactly with the registered value.
* [ ] Every authorization creates new `state` and PKCE values.
* [ ] The callback rejects missing or mismatched `state`.
* [ ] An authorization code is never reused.
* [ ] The integration requests only the permissions it needs.
* [ ] Tokens are stored securely and never appear in URLs or logs.
* [ ] Refresh stores the new `refresh_token` before releasing other requests.
* [ ] The integration can revoke and delete access it no longer needs.

### If credentials are exposed

If you suspect that the Client Secret was exposed:

1. Create a new OAuth application.
2. Update the integration with the new credentials.
3. Confirm that the new OAuth application works.
4. Revoke the compromised OAuth application.

Revocation disables the OAuth application and its tokens.

Also revoke an OAuth application when:

* the integration is discontinued;
* it no longer needs to access users' accounts;
* unexpected behavior suggests misuse of credentials or tokens.

After containing the incident, remove credentials from logs, repositories, and tools where they may have been recorded, and review how the exposure happened.
