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

# Error Handling

> Handle iDenfy API errors, webhook failures, and edge cases with HTTP status codes, common error fixes, and retry best practices guide.

## HTTP Status Codes

| Code  | Meaning      | Action                                                                  |
| ----- | ------------ | ----------------------------------------------------------------------- |
| `200` | Success      | Process the response                                                    |
| `400` | Bad request  | Check request body — missing or invalid parameters                      |
| `401` | Unauthorized | Check your API Key and Secret                                           |
| `403` | Forbidden    | Your account lacks access to this endpoint or feature                   |
| `404` | Not found    | Invalid endpoint URL or resource doesn't exist                          |
| `409` | Conflict     | Duplicate `clientId` — this customer already has an active session      |
| `429` | Rate limited | Slow down — wait and retry with exponential backoff                     |
| `500` | Server error | iDenfy issue — retry after a short delay, contact support if persistent |

## Common Errors and Fixes

<AccordionGroup>
  <Accordion title="401 Unauthorized — 'Invalid credentials'">
    **Cause:** Wrong API Key or Secret, or using sandbox keys against production (or vice versa).

    **Fix:**

    1. Verify your API Key and Secret in [Dashboard → Settings → API Keys](/guides/dashboard/settings/api-keys)
    2. Ensure you're using the correct environment keys
    3. Check that the `Authorization` header is correctly Base64-encoded as `key:secret`
  </Accordion>

  <Accordion title="409 Conflict — 'Client ID already exists'">
    **Cause:** You're generating a token for a `clientId` that already has an active verification session.

    **Fix:**

    * Use a unique `clientId` per verification attempt
    * If your user needs to re-verify, either use a different `clientId` or wait for the previous session to expire
  </Accordion>

  <Accordion title="400 Bad Request — 'Invalid parameter'">
    **Cause:** A required field is missing or a field value is invalid.

    **Fix:**

    * Check the [session parameters](/kyc/generate-token) for required fields and valid values
    * Ensure `clientId` is a non-empty string
    * Ensure country codes use ISO 3166-1 alpha-2 format
  </Accordion>

  <Accordion title="Webhook not received">
    **Possible causes:**

    1. Webhook URL not configured — check [Dashboard → Settings → Webhooks](/guides/dashboard/settings/system-notifications-webhooks-emails)
    2. Your endpoint returned a non-2xx status — check server logs
    3. Firewall blocking iDenfy IPs — whitelist our [IP ranges](/security/ip-whitelisting)
    4. HTTPS certificate issue — ensure your cert is valid and not self-signed
    5. Webhook still processing — manual reviews can take several minutes
  </Accordion>

  <Accordion title="iFrame camera not working">
    **Cause:** Browser security policies restrict camera access in third-party iFrames.

    **Fix:**

    * Add `allow="camera; microphone"` to the iFrame tag
    * Ensure your page is served over HTTPS
    * Check that no `Permissions-Policy` header blocks camera access
    * Some browsers (Safari) have stricter iFrame policies — test across browsers
  </Accordion>
</AccordionGroup>

## Retry Strategy

For transient errors (429, 500, network timeouts), implement exponential backoff:

```python theme={"system"}
import time
import requests

def call_with_retry(url, payload, auth, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, json=payload, auth=auth)

        if response.status_code == 200:
            return response.json()
        elif response.status_code in (429, 500, 502, 503):
            wait = 2 ** attempt  # 1s, 2s, 4s
            time.sleep(wait)
        else:
            response.raise_for_status()

    raise Exception(f"Failed after {max_retries} retries")
```

## Full Error Reference

See [ID Error Messages](/kyc/id-error-messages) for the complete list of error codes and their descriptions.
