Error code dictionary
The error codes you may hit while integrating, what causes them and how to fix them.
These are the error codes you may run into while integrating, their causes, and how to fix them. Errors that come back through the browser are carried in the query string of the callback URL; token and API errors are carried in the JSON body.
Authorization request GET /oauth/authorize
| Code | Cause | Fix |
|---|---|---|
unsupported_response_type | response_type is not code | Fix it to response_type=code. No other value is supported |
invalid_request | One of client_id, redirect_uri or state is empty | All three are required. Forgetting state is the most common mistake |
pkce_required | code_challenge is missing | PKCE is required, not optional. See STEP 5 of Integrate in 5 minutes |
invalid_code_challenge_method | code_challenge_method is not S256 | Only S256 is accepted. plain is not supported |
unauthorized_client | No client matches the client_id | Check that you copied the value from My account exactly |
invalid_scope | The scope is empty or not on the allowed list | You can only use the ones listed in the Scope reference |
insufficient_scope | You requested a scope that has not been granted to this service | service.domain.read needs to be granted by an administrator |
access_denied | The service or client is not active — domain not verified, callback not registered, or blocked | Check the service status in My account. It must be “Active” |
invalid_redirect_uri | redirect_uri differs from the registered callback | It must match character for character. Check the trailing slash, http/https and the port |
Token exchange POST /oauth/token
| Code | HTTP | Cause · fix |
|---|---|---|
unsupported_grant_type | 400 | grant_type accepts only authorization_code or refresh_token |
invalid_request | 400 | A required parameter is missing. Check whether you left out code_verifier |
invalid_client | 401 | client_id/client_secret mismatch. Try copying the secret again |
invalid_grant | 400 | The code was already used or is older than 10 minutes, or it does not exist. A code is single-use |
invalid_grant+ pkce verification failed | 400 | code_verifier does not match the code_challenge used in the authorization request. Check that you are sending the value you stored in the session, unchanged |
invalid_redirect_uri | 400 | The redirect_uri in the token request differs from the one in the authorization request. You must send the same value both times |
server_error | 500 | An internal server error. If it keeps happening, please contact us |
User info GET /oauth/userinfo · GET /oauth/domain-info
| Code | HTTP | Cause · fix |
|---|---|---|
invalid_token | 401 | The token is missing, expired (1 hour by default) or revoked. Get a new one with the refresh_token |
insufficient_scope | 403 | /oauth/domain-info requires service.domain.read |
Common situations
“I'm sure it's right, but I keep getting invalid_redirect_uri”
Most of the time it is the trailing slash. If the registered value is https://example.com/oauth/callback
and your request has https://example.com/oauth/callback/, it is treated as a different value.
The surest way is to copy the string registered in My account and paste it in.
“Sign-in works, but email doesn't arrive”
It is most likely not a scope problem. Email is included in profile.basic and provided by default, but
it can be turned off per service. See the email policy in the Scope reference.
“I keep getting access_denied”
Check the status of the service, not the client. An authorization request is accepted only when all three are in place: domain verification complete, callback URL registered, and status “Active”.