Skip to main content

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

Comprehensive guide to handling errors across the customer lifecycle flows.

Error Response Format

All API errors follow a consistent format:
{
  "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

CodeDescriptionCommon Causes
400Bad RequestValidation errors, missing fields
401UnauthorizedInvalid/expired token, wrong credentials
403ForbiddenInsufficient permissions, role mismatch
404Not FoundResource doesn’t exist
409ConflictDuplicate resource, state conflict
422Unprocessable EntityBusiness rule violation
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer-side error

Registration Errors

Password Mismatch (400)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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)

{
  "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