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

# Error Handling

> Common error scenarios and troubleshooting guide

# Error Handling

Comprehensive guide to handling errors across the customer lifecycle flows.

## Error Response Format

All API errors follow a consistent format:

```json theme={null}
{
  "code": 400,
  "message": "Human-readable error message",
  "data": {
    "error": "Error type",
    "details": "Detailed explanation",
    "field": "Affected field (if applicable)",
    "suggestions": ["Suggested fix 1", "Suggested fix 2"]
  }
}
```

***

## HTTP Status Codes

| Code  | Description           | Common Causes                            |
| ----- | --------------------- | ---------------------------------------- |
| `400` | Bad Request           | Validation errors, missing fields        |
| `401` | Unauthorized          | Invalid/expired token, wrong credentials |
| `403` | Forbidden             | Insufficient permissions, role mismatch  |
| `404` | Not Found             | Resource doesn't exist                   |
| `409` | Conflict              | Duplicate resource, state conflict       |
| `422` | Unprocessable Entity  | Business rule violation                  |
| `429` | Too Many Requests     | Rate limit exceeded                      |
| `500` | Internal Server Error | Server-side error                        |

***

## Registration Errors

### Password Mismatch (400)

```json theme={null}
{
  "code": 400,
  "message": "Request validation failed",
  "data": {
    "errors": [
      {
        "field": "matchingPassword",
        "message": "Password and matching password must be identical"
      }
    ]
  }
}
```

**Solution:** Ensure `password` and `matchingPassword` fields contain identical values.

***

### Invalid Categorization (400)

```json theme={null}
{
  "code": 400,
  "message": "Categorization validation failed",
  "data": {
    "error": "Invalid categorization",
    "details": "Feature 'ENHANCED_AML_MONITORING' requires mandatory key 'riskLevel'",
    "missingKeys": ["riskLevel"],
    "invalidValues": {
      "monitoring": "HOURLY is not in allowed values: [WEEKLY, DAILY, REAL_TIME]"
    }
  }
}
```

**Solution:**

1. Call `GET /categorization/hierarchy/{tenantId}` to get available options
2. Check `mandatoryKeys` for the feature
3. Ensure all mandatory keys are provided
4. Validate values against `allowedValues`

***

### Tenant Access Denied (403)

```json theme={null}
{
  "code": 403,
  "message": "Tenant access denied or categorization not available",
  "data": {
    "error": "Tenant access denied",
    "tenantId": "97e7ff29-15f3-49ef-9681-3bbfcce4f6cd"
  }
}
```

**Solution:** Verify the `X-Tenant-ID` header matches your assigned tenant and that categorization is enabled for your tenant.

***

### Organization Already Exists (409)

```json theme={null}
{
  "code": 409,
  "message": "Organization already exists",
  "data": {
    "error": "Duplicate organization",
    "registrationNumber": "REG123456789",
    "existingOrganizationId": "org-880e8400..."
  }
}
```

**Solution:** Use a unique registration number or retrieve the existing organization.

***

## Authentication Errors

### Invalid Credentials (401)

```json theme={null}
{
  "code": 401,
  "message": "Authentication failed",
  "data": {
    "success": false,
    "errorType": "AUTHENTICATION",
    "message": "Invalid username or password",
    "attempts": 3,
    "maxAttempts": 5,
    "lockoutTime": null
  }
}
```

**Solution:** Verify username (email) and password are correct.

***

### Account Locked (401)

```json theme={null}
{
  "code": 401,
  "message": "Account locked",
  "data": {
    "success": false,
    "errorType": "AUTHENTICATION",
    "message": "Account locked due to multiple failed login attempts",
    "attempts": 5,
    "maxAttempts": 5,
    "lockoutTime": "2026-01-13T11:30:00.000Z",
    "lockoutDuration": "30 minutes"
  }
}
```

**Solution:** Wait for lockout period to expire (30 minutes) or contact support.

***

### Token Expired (401)

```json theme={null}
{
  "code": 401,
  "message": "Token expired",
  "data": {
    "error": "JWT_EXPIRED",
    "expiredAt": "2026-01-13T12:00:00.000Z"
  }
}
```

**Solution:** Obtain a new token via the session creation endpoint.

***

## Verification Errors

### Insufficient Permission (403)

```json theme={null}
{
  "code": 403,
  "message": "Access denied: Only COMPLIANCE_OFFICER or ADMIN_USER can initiate verification",
  "data": {
    "userId": "user-660e8400...",
    "currentRoles": ["EMPLOYEE", "TRANSACTION_APPROVER"],
    "requiredRoles": ["COMPLIANCE_OFFICER", "ADMIN_USER"]
  }
}
```

**Solution:** Use an account with `COMPLIANCE_OFFICER` or `ADMIN_USER` role.

***

## Activation Errors

### Missing Consents (400)

```json theme={null}
{
  "code": 400,
  "message": "Missing required consents",
  "data": {
    "activationStatus": "CONSENT_REQUIRED",
    "customerId": "cust-550e8400...",
    "missingConsentTypes": ["PRIVACY_POLICY", "DATA_PROCESSING"],
    "missingConsentDetails": {
      "PRIVACY_POLICY": {
        "consentType": "PRIVACY_POLICY",
        "status": "MISSING",
        "acceptUrl": "/api/v2.1/customer/individual/{customerId}/consents/privacy"
      }
    },
    "totalRequiredConsents": 3,
    "totalMissingConsents": 2,
    "nextSteps": [
      "Accept Privacy Policy",
      "Accept Data Processing Agreement",
      "Retry activation"
    ]
  }
}
```

**Solution:** Accept all missing consents using the provided `acceptUrl` endpoints.

***

### Not Verified (422)

```json theme={null}
{
  "code": 422,
  "message": "Customer not verified",
  "data": {
    "activationStatus": "VERIFICATION_REQUIRED",
    "verificationStatus": "PENDING_REVIEW",
    "reason": "Customer verification must be APPROVED before activation",
    "estimatedCompletionTime": "1-2 business days"
  }
}
```

**Solution:** Wait for verification to be approved before attempting activation.

***

### Missing ADMIN\_USER Role (400)

```json theme={null}
{
  "code": 400,
  "message": "Missing required role 'ADMIN_USER' for BUSINESS_TYPE_CLIENT_TO_TENANT organization. At least one employee must have this role."
}
```

**Solution:** Ensure the first employee added has the `ADMIN_USER` role.

***

## Transaction Errors

### Insufficient Balance (400)

```json theme={null}
{
  "code": 400,
  "message": "Insufficient balance",
  "data": {
    "availableBalance": "100000",
    "requestedAmount": "150000",
    "currency": "EUR"
  }
}
```

**Solution:** Top up the wallet or reduce the transaction amount.

***

### Limit Exceeded (400)

```json theme={null}
{
  "code": 400,
  "message": "Transaction limit exceeded",
  "data": {
    "limitType": "DAILY",
    "limit": "5000",
    "currentUsage": "4500",
    "requestedAmount": "1000",
    "currency": "EUR"
  }
}
```

**Solution:** Wait for limit reset or use a smaller amount.

***

### Beneficiary Not Found (404)

```json theme={null}
{
  "code": 404,
  "message": "Beneficiary not found",
  "data": {
    "iban": "GB82WEST12345698765432",
    "suggestion": "Add beneficiary before making transfer"
  }
}
```

**Solution:** Add the beneficiary using the beneficiaries endpoint before attempting the transfer.

***

## Troubleshooting Checklist

### Registration Issues

* [ ] Valid email format
* [ ] Password meets requirements (8+ chars, mixed case, numbers, special)
* [ ] `password` matches `matchingPassword`
* [ ] Valid tenant ID in header
* [ ] Categorization values match allowed values

### Authentication Issues

* [ ] Correct username (email)
* [ ] Correct password
* [ ] Valid tenant key and secret
* [ ] Account not locked
* [ ] Token not expired

### Activation Issues

* [ ] Verification status is `APPROVED`
* [ ] All three consents accepted (Terms, Privacy, Data Processing)
* [ ] Customer not already active
* [ ] For B2B: At least one employee with `ADMIN_USER` role

### Transaction Issues

* [ ] Wallet is `ACTIVE`
* [ ] Sufficient balance
* [ ] Within transaction limits
* [ ] Beneficiary exists and is active
* [ ] Valid payment consent in place

***

## Error Handling Best Practices

1. **Parse error responses** - Always check the `data` object for detailed information
2. **Handle retries carefully** - Don't retry on 400/403/422 errors
3. **Log error details** - Store `code`, `message`, and `data` for debugging
4. **Show user-friendly messages** - Map technical errors to user-friendly text
5. **Implement exponential backoff** - For 429 and 500 errors
