> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopae.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Code Reference

> Complete list of error codes and their meanings

## Error Response Format

All errors follow RFC 7807 Problem Details for HTTP APIs:

```json theme={null}
{
  "title": "AUTH_INVALID_CREDENTIALS",
  "status": 401,
  "detail": "Invalid client credentials provided",
  "instance": "/token",
  "timestamp": "2024-01-20T10:30:00.000Z",
  "context": {
    "client_id": "example_client"
  },
  "doc_url": "https://docs.hopae.com/api-reference/error-codes#invalid-credentials"
}
```

### Response Fields

| Field       | Type   | Description                                              |
| ----------- | ------ | -------------------------------------------------------- |
| `title`     | string | Error code identifier (e.g., `AUTH_INVALID_CREDENTIALS`) |
| `status`    | number | HTTP status code                                         |
| `detail`    | string | Human-readable error description                         |
| `instance`  | string | The request path where the error occurred                |
| `timestamp` | string | ISO 8601 timestamp of when the error occurred            |
| `context`   | object | Additional context information (optional)                |
| `doc_url`   | string | Link to documentation for this error (optional)          |

## Error Code Structure

Error codes follow a string-based, domain-prefixed structure:

* **Format**: `CATEGORY_ERROR_NAME`
* **Categories**:
  * `AUTH_*` - Authentication errors
  * `VALIDATION_*` - Validation errors
  * `SESSION_*` - Session management errors
  * `PROVIDER_*` - Provider-specific errors
  * `SYSTEM_*` - System errors
  * `RESOURCE_*` - Resource errors

## Authentication Errors

<ResponseField name="Invalid Credentials" type="error">
  **Code**: `AUTH_INVALID_CREDENTIALS`
  **HTTP Status**: 401

  Invalid client credentials (Client ID or Client Secret incorrect)

  **Common Causes**:

  * Wrong Client ID or Client Secret
  * Using sandbox credentials in production or vice versa
  * Credentials have been rotated
</ResponseField>

<ResponseField name="Invalid Grant" type="error">
  **Code**: `AUTH_INVALID_GRANT`
  **HTTP Status**: 400

  Invalid grant provided (OAuth2 standard error)

  **Common Causes**:

  * Authorization code has expired
  * Authorization code has been used already
  * Code verifier mismatch in PKCE flow
</ResponseField>

<ResponseField name="Invalid Client" type="error">
  **Code**: `AUTH_INVALID_CLIENT`
  **HTTP Status**: 401

  Client authentication failed (OAuth2 standard error)

  **Common Causes**:

  * Client doesn't exist
  * Client is disabled
  * Authentication method not allowed for client
</ResponseField>

<ResponseField name="Forbidden" type="error">
  **Code**: `AUTH_FORBIDDEN`
  **HTTP Status**: 403

  Access denied. The authenticated user does not have permission to access the requested resource.

  **Common Causes**:

  * Unauthorized origin attempting access
  * Insufficient permissions for the resource
  * Action not allowed for the authenticated client

  **Example Response**:

  ```json theme={null}
  {
    "title": "AUTH_FORBIDDEN",
    "status": 403,
    "detail": "Access denied",
    "instance": "/apps/client_abc123",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "reason": "Unauthorized origin",
      "resource": "app",
      "action": "read"
    }
  }
  ```
</ResponseField>

## Validation Errors

<ResponseField name="Missing Parameter" type="error">
  **Code**: `VALIDATION_MISSING_PARAMETER`
  **HTTP Status**: 400

  Required parameter is missing from the request

  **Common Causes**:

  * Missing required query parameters
  * Missing required body fields
  * Empty request body
</ResponseField>

<ResponseField name="Invalid Parameter" type="error">
  **Code**: `VALIDATION_INVALID_PARAMETER`
  **HTTP Status**: 400

  Parameter value is invalid

  **Common Causes**:

  * Invalid format (e.g., email, URL)
  * Value out of allowed range
  * Unsupported parameter value
</ResponseField>

<ResponseField name="Missing User Data" type="error">
  **Code**: `VALIDATION_MISSING_USER_DATA`
  **HTTP Status**: 400

  Required user data is missing

  **Common Causes**:

  * Provider didn't return required attributes
  * User didn't consent to required scopes
</ResponseField>

<ResponseField name="Invalid User Data" type="error">
  **Code**: `VALIDATION_INVALID_USER_DATA`
  **HTTP Status**: 400

  User data format is invalid

  **Common Causes**:

  * Malformed data from provider
  * Data validation failed
</ResponseField>

<ResponseField name="Invalid PKCE" type="error">
  **Code**: `VALIDATION_INVALID_PKCE`
  **HTTP Status**: 400

  Invalid PKCE parameters

  **Common Causes**:

  * Missing code challenge
  * Invalid code verifier format
  * Code verifier doesn't match challenge
</ResponseField>

<ResponseField name="Redirect URI Required" type="error">
  **Code**: `VALIDATION_REDIRECT_URI_REQUIRED`
  **HTTP Status**: 400

  Redirect URI is required but not provided

  **Common Causes**:

  * No default redirect URI configured
  * Public client without redirect URI
</ResponseField>

<ResponseField name="Missing Client Secret" type="error">
  **Code**: `VALIDATION_MISSING_CLIENT_SECRET`
  **HTTP Status**: 400

  Client secret is required but not provided

  **Common Causes**:

  * Confidential client authenticating without secret
  * Wrong authentication method used
</ResponseField>

## Session Management Errors

<ResponseField name="Session Not Found" type="error">
  **Code**: `SESSION_NOT_FOUND`
  **HTTP Status**: 404

  Session does not exist

  **Common Causes**:

  * Invalid session ID
  * Session has expired
  * Session was deleted
</ResponseField>

<ResponseField name="Verification Not Found" type="error">
  **Code**: `SESSION_VERIFICATION_NOT_FOUND`
  **HTTP Status**: 404

  Verification session not found

  **Common Causes**:

  * Invalid verification ID
  * Verification has expired
  * Wrong environment (sandbox vs production)
</ResponseField>

<ResponseField name="Invalid Status Transition" type="error">
  **Code**: `SESSION_INVALID_STATUS_TRANSITION`
  **HTTP Status**: 409

  Invalid session status transition

  **Common Causes**:

  * Session already completed
  * Session was cancelled
  * Attempting invalid state change
</ResponseField>

<ResponseField name="Invalid Flow" type="error">
  **Code**: `SESSION_INVALID_FLOW`
  **HTTP Status**: 400

  Invalid verification flow

  **Common Causes**:

  * Unsupported flow type for provider
  * Flow parameters are invalid
  * Flow not enabled for application
</ResponseField>

## Provider Errors

<ResponseField name="Provider Not Found" type="error">
  **Code**: `PROVIDER_NOT_FOUND`
  **HTTP Status**: 404

  Provider not found

  **Common Causes**:

  * Invalid provider ID
  * Provider not available in region
  * Typo in provider identifier
</ResponseField>

<ResponseField name="Provider Not Enabled" type="error">
  **Code**: `PROVIDER_NOT_ENABLED`
  **HTTP Status**: 403

  Provider is not enabled for this application

  **Common Causes**:

  * Provider not configured in Console
  * Provider disabled for maintenance
  * Account doesn't have access to provider
</ResponseField>

<ResponseField name="Initialization Failed" type="error">
  **Code**: `PROVIDER_INITIALIZATION_FAILED`
  **HTTP Status**: 502

  Provider initialization failed

  **Common Causes**:

  * Provider service is down
  * Network connectivity issues
  * Invalid provider configuration
</ResponseField>

<ResponseField name="Provider Error" type="error">
  **Code**: `PROVIDER_ERROR`
  **HTTP Status**: 502

  Generic provider error

  **Common Causes**:

  * Provider returned an error
  * Provider timeout
  * Unexpected provider response
</ResponseField>

<ResponseField name="Provider Unavailable" type="error">
  **Code**: `PROVIDER_UNAVAILABLE`
  **HTTP Status**: 503

  Provider service is unavailable

  **Common Causes**:

  * Provider maintenance
  * Provider service outage
  * Rate limited by provider
</ResponseField>

<ResponseField name="Provider Configuration Error" type="error">
  **Code**: `PROVIDER_CONFIGURATION_ERROR`
  **HTTP Status**: 400

  The provider configuration is invalid or incomplete.

  **Common Causes**:

  * Missing required configuration values
  * Invalid configuration format
  * Incomplete provider setup

  **Example Response**:

  ```json theme={null}
  {
    "title": "PROVIDER_CONFIGURATION_ERROR",
    "status": 400,
    "detail": "Missing configuration 'apiSecret' for pass",
    "instance": "/verifications",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "providerId": "pass",
      "missingConfig": "apiSecret"
    }
  }
  ```
</ResponseField>

<ResponseField name="Provider Authentication Failed" type="error">
  **Code**: `PROVIDER_AUTHENTICATION_FAILED`
  **HTTP Status**: 401

  Authentication with the eID provider failed.

  **Common Causes**:

  * Invalid provider credentials
  * Provider API key expired
  * Authentication token invalid

  **Example Response**:

  ```json theme={null}
  {
    "title": "PROVIDER_AUTHENTICATION_FAILED",
    "status": 401,
    "detail": "Failed to initiate iPIN authentication: Invalid credentials",
    "instance": "/verifications",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "providerId": "ipin"
    }
  }
  ```
</ResponseField>

<ResponseField name="Provider Unexpected Response" type="error">
  **Code**: `PROVIDER_UNEXPECTED_RESPONSE`
  **HTTP Status**: 502

  The provider returned an unexpected or invalid response.

  **Common Causes**:

  * Empty response from provider
  * Malformed response data
  * Unexpected response format

  **Example Response**:

  ```json theme={null}
  {
    "title": "PROVIDER_UNEXPECTED_RESPONSE",
    "status": 502,
    "detail": "Empty response from identity verification",
    "instance": "/verifications",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "providerId": "pass"
    }
  }
  ```
</ResponseField>

## System Errors

<ResponseField name="Internal Error" type="error">
  **Code**: `SYSTEM_INTERNAL_ERROR`
  **HTTP Status**: 500

  Internal server error

  **Common Causes**:

  * Unexpected system error
  * Database connection issues
  * Configuration errors

  **Action**: Contact support if persists
</ResponseField>

<ResponseField name="Unsupported Mode" type="error">
  **Code**: `SYSTEM_UNSUPPORTED_MODE`
  **HTTP Status**: 501

  Requested mode or feature is not supported

  **Common Causes**:

  * Feature not implemented
  * Deprecated functionality
  * Invalid operation mode
</ResponseField>

## Resource Errors

Generic resource errors for CRUD operations.

<ResponseField name="Resource Not Found" type="error">
  **Code**: `RESOURCE_NOT_FOUND`
  **HTTP Status**: 404

  The requested resource was not found.

  **Common Causes**:

  * Invalid resource identifier
  * Resource has been deleted
  * Resource does not exist

  **Example Response**:

  ```json theme={null}
  {
    "title": "RESOURCE_NOT_FOUND",
    "status": 404,
    "detail": "App not found",
    "instance": "/apps/client_abc123",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "resource": "App",
      "identifier": "client_abc123"
    }
  }
  ```
</ResponseField>

<ResponseField name="Resource Conflict" type="error">
  **Code**: `RESOURCE_CONFLICT`
  **HTTP Status**: 409

  A conflict occurred with the current state of the resource (e.g., duplicate entry).

  **Common Causes**:

  * Resource already exists with the same identifier
  * Duplicate entry attempt
  * Concurrent modification conflict

  **Example Response**:

  ```json theme={null}
  {
    "title": "RESOURCE_CONFLICT",
    "status": 409,
    "detail": "App already exists",
    "instance": "/apps",
    "timestamp": "2024-01-20T10:30:00.000Z",
    "context": {
      "resource": "App",
      "identifier": "client_abc123"
    }
  }
  ```
</ResponseField>

## Error Categories

Errors are categorized for proper handling:

| Category  | HTTP Status Range | Description               | Retry Strategy                 |
| --------- | ----------------- | ------------------------- | ------------------------------ |
| `client`  | 400-499           | Client errors             | Do not retry automatically     |
| `failure` | 502-503           | External service failures | Retry with exponential backoff |
| `error`   | 500-501           | System errors             | Retry once after delay         |

## Error Handling Best Practices

### Retry Strategy

<Tabs>
  <Tab title="Retryable Errors">
    ```javascript theme={null}
    // Errors that can be retried
    const RETRYABLE_CODES = [
      'PROVIDER_INITIALIZATION_FAILED',
      'PROVIDER_ERROR',
      'PROVIDER_UNAVAILABLE',
      'PROVIDER_UNEXPECTED_RESPONSE',
      'SYSTEM_INTERNAL_ERROR',
    ];

    // Implement exponential backoff
    async function retryWithBackoff(fn, maxRetries = 3) {
      for (let i = 0; i < maxRetries; i++) {
        try {
          return await fn();
        } catch (error) {
          if (!RETRYABLE_CODES.includes(error.title)) {
            throw error;
          }
          if (i === maxRetries - 1) throw error;

          const delay = Math.min(1000 * Math.pow(2, i), 10000);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
      }
    }
    ```
  </Tab>

  <Tab title="Non-Retryable Errors">
    ```javascript theme={null}
    // Errors that should NOT be retried
    const NON_RETRYABLE_CODES = [
      'AUTH_INVALID_CREDENTIALS',
      'AUTH_INVALID_CLIENT',
      'AUTH_FORBIDDEN',
      'VALIDATION_MISSING_PARAMETER',
      'VALIDATION_INVALID_PARAMETER',
      'VALIDATION_STEP_NOT_APPLICABLE',
      'SESSION_INVALID_STATUS_TRANSITION',
      'PROVIDER_NOT_ENABLED',
      'RESOURCE_NOT_FOUND',
      'RESOURCE_CONFLICT',
      'IDEMPOTENCY_KEY_CONFLICT',
      'IDEMPOTENCY_REQUEST_IN_PROGRESS',
    ];

    // Handle immediately without retry
    function handleError(error) {
      if (NON_RETRYABLE_CODES.includes(error.title)) {
        // Log and return error to user
        console.error('Non-retryable error:', error);
        return { success: false, error };
      }
    }
    ```
  </Tab>
</Tabs>

### User Communication

| Error Code                          | User-Friendly Message                                                                |
| ----------------------------------- | ------------------------------------------------------------------------------------ |
| `AUTH_INVALID_CREDENTIALS`          | "Authentication failed. Please check your credentials."                              |
| `VALIDATION_MISSING_PARAMETER`      | "Some required information is missing. Please try again."                            |
| `SESSION_NOT_FOUND`                 | "Your session has expired. Please start over."                                       |
| `SESSION_INVALID_STATUS_TRANSITION` | "This verification has already been completed."                                      |
| `PROVIDER_NOT_ENABLED`              | "This identity provider is not available."                                           |
| `PROVIDER_UNAVAILABLE`              | "The identity service is temporarily unavailable. Please try again later."           |
| `SYSTEM_INTERNAL_ERROR`             | "Something went wrong on our end. Please try again."                                 |
| `RESOURCE_NOT_FOUND`                | "The requested resource was not found."                                              |
| `VALIDATION_STEP_NOT_APPLICABLE`    | "This step doesn't apply to the current flow. Please check the activation sequence." |
| `IDEMPOTENCY_KEY_CONFLICT`          | "Duplicate request detected with a different payload. Please retry with a new key."  |
| `IDEMPOTENCY_REQUEST_IN_PROGRESS`   | "A matching request is still processing. Please try again shortly."                  |

### Error Context

Always include relevant context when logging errors:

```javascript theme={null}
function logError(error, appContext) {
  console.error({
    // Error details from response
    title: error.title,
    status: error.status,
    detail: error.detail,
    instance: error.instance,
    timestamp: error.timestamp,
    context: error.context,
    // Application context
    verificationId: appContext.verificationId,
    userId: appContext.userId,
    provider: appContext.provider,
    environment: process.env.NODE_ENV,
    // Never log sensitive data
    // ❌ accessToken, clientSecret, userData
  });
}
```

## Support

For persistent errors or issues not covered here:

<Card title="Developer Support" icon="envelope">
  **Email**: [dev@hopae.com](mailto:dev@hopae.com)

  **Include in your report**:

  * Error code
  * Timestamp
  * Verification ID (if available)
  * Environment (Sandbox/Production)
  * Request ID from headers
</Card>
