> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.id.me/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.id.me/_mcp/server.

# Error codes

> OAuth 2.0 error codes

This page documents the error codes returned by ID.me's OAuth 2.0 endpoints during authorization, logout, and token exchange flows.

> **Note**
>
> These error codes apply to both OAuth 2.0 and OpenID Connect integrations, as OIDC uses the same underlying OAuth 2.0 endpoints

## Authorization code and implicit token flow

If the authorization request cannot be completed, ID.me appends error parameters to your `redirect_uri` when redirecting the user.

All responses are returned with **HTTP 200**.

**`Example`**

```html Example
https://example.com/callback?error=invalid_scope&error_description=scope+cant+be+resolved+to+an+existing+policy+for+the+client
```

### Error codes

| Error                       | Description                                                                               |
| --------------------------- | ----------------------------------------------------------------------------------------- |
| invalid\_request            | `client_id`, `response_type`, or `redirect_uri` is missing                                |
| invalid\_client             | `client_id` cannot be resolved to an application (OAuth client value mismatch)            |
| invalid\_scope              | `scope` cannot be resolved to an existing policy for the client                           |
| invalid\_redirect\_uri      | `redirect_uri` cannot be resolved to any of the configured redirect URIs for the consumer |
| unsupported\_response\_type | `response_type` is not `code` or `token`                                                  |

## Logout

If a logout request is malformed or cannot be processed, ID.me returns error parameters on the redirect.

All responses are returned with **HTTP 200**.

### Error codes

| Error                  | Description                                                                               |
| ---------------------- | ----------------------------------------------------------------------------------------- |
| invalid\_request       | `client_id` or `redirect_uri` is missing                                                  |
| invalid\_client        | `client_id` cannot be resolved to a consumer                                              |
| invalid\_redirect\_uri | `redirect_uri` cannot be resolved to any of the configured redirect URIs for the consumer |

## Token exchange and refresh

When exchanging an authorization code for an access token, refreshing a token, or using the password grant, errors are returned in the JSON response body.

All responses are returned with **HTTP 400** (Bad Request).

**`Example`**

```json Example
{
  "error": "invalid_grant",
  "error_description": "The provided authorization grant is expired or revoked"
}
```

### All grant types

The following errors apply regardless of grant type:

| Error                | Description                                                       |
| -------------------- | ----------------------------------------------------------------- |
| invalid\_request     | `scope`, `grant_type`, `client_id`, or `client_secret` is missing |
| invalid\_client      | `client_id` and `client_secret` cannot be resolved to a consumer  |
| invalid\_scope       | `scope` cannot be resolved to an existing policy for the client   |
| unauthorized\_client | Consumer is not allowed to use the provided `grant_type`          |

### Authorization code

| Error                  | Description                                                                                           |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| invalid\_request       | `code` or `redirect_uri` is missing                                                                   |
| invalid\_grant         | The code provided does not match any existing grants                                                  |
| invalid\_redirect\_uri | `redirect_uri` cannot be resolved to any of the configured redirect URIs for the consumer             |
| invalid\_grant         | The provided authorization grant is invalid                                                           |
| invalid\_grant         | The provided authorization grant does not match the redirection URI used in the authorization request |
| invalid\_grant         | The provided authorization grant was issued to another client                                         |
| invalid\_grant         | The provided authorization grant is expired or revoked                                                |

> **Note**
>
> The `invalid_grant` error may be returned for several distinct reasons. Use the `error_description` field in the response to determine the specific cause.

### Password grant

| Error                    | Description                                             |
| ------------------------ | ------------------------------------------------------- |
| invalid\_request         | `email` or `password` is missing                        |
| invalid\_resource\_owner | User cannot be authenticated with the given credentials |

### Refresh token

| Error            | Description                                             |
| ---------------- | ------------------------------------------------------- |
| invalid\_request | `refresh_token` is missing                              |
| invalid\_grant   | The refresh token provided is invalid                   |
| invalid\_grant   | The refresh token provided has already been used        |
| invalid\_grant   | The refresh token provided was issued to another client |
| invalid\_grant   | The refresh token provided has expired                  |

> **Best practice**
>
> * Always check for the `error` parameter in redirect URI responses and handle it gracefully
> * Log error codes and descriptions to assist with debugging and support requests
> * Use the `error_description` field to differentiate between multiple causes of the same error code, especially `invalid_grant`
> * Map error codes to user-friendly messages rather than exposing raw error strings to end users
> * Handle `access_denied` explicitly, as this indicates the user denied the authorization request and should be routed back to an appropriate page in your application