Skip to main content
POST
https://sandbox.finhub.cloud
/
api
/
v2.1
/
customer
/
individual
/
registration
Individual Customer Registration
curl --request POST \
  --url https://sandbox.finhub.cloud/api/v2.1/customer/individual/registration \
  --header 'Authorization: <authorization>' \
  --header 'Content-Type: <content-type>' \
  --header 'User-Agent: <user-agent>' \
  --header 'X-Forwarded-For: <x-forwarded-for>' \
  --header 'X-Tenant-ID: <x-tenant-id>' \
  --data '
{
  "tenantId": "<string>",
  "firstName": "<string>",
  "lastName": "<string>",
  "email": "<string>",
  "phone": "<string>",
  "password": "<string>",
  "matchingPassword": "<string>",
  "roleIds": [
    {}
  ],
  "individualCustomer": {
    "tenantId": "<string>",
    "customerName": "<string>",
    "person": {
      "id": "<string>",
      "firstName": "<string>",
      "lastName": "<string>",
      "email": "<string>",
      "dateOfBirth": "<string>",
      "gender": "<string>",
      "nationality": "<string>",
      "placeOfBirth": "<string>",
      "fullName": "<string>",
      "addresses": [
        {
          "id": "<string>",
          "type": "<string>",
          "street": "<string>",
          "city": "<string>",
          "postalCode": "<string>",
          "country": "<string>",
          "state": "<string>",
          "isPrimary": true
        }
      ],
      "contacts": [
        {
          "id": "<string>",
          "type": "<string>",
          "value": "<string>",
          "isPrimary": true
        }
      ]
    },
    "user": {
      "id": "<string>",
      "tenantId": "<string>",
      "username": "<string>",
      "email": "<string>",
      "password": "<string>",
      "status": "<string>",
      "roles": [
        {}
      ],
      "isActive": true
    }
  }
}
'
{
  "code": 200,
  "message": "B2C individual account created successfully. Redirect to activate-account page",
  "redirectUrl": "/auth/activate-account",
  "data": {
    "organization": false,
    "individual": true,
    "id": "5887c98c-b5b1-4234-b819-a4987f54aa77",
    "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "customerType": "CT_PERSON",
    "customerStatus": "CS_REGISTRATION_COMPLETED",
    "categorization": {
      "active": true,
      "id": "B2CCustomerIndividual",
      "name": "B2C Individual",
      "description": "Customer categorization for B2C",
      "isActive": true,
      "categoryFeatureRelations": [],
      "parametrization": []
    },
    "person": {
      "lastName": "Jensen",
      "firstName": "Marcus",
      "id": "the2r6zaa6",
      "names": [
        {
          "type": "FIRST",
          "value": "Marcus"
        },
        {
          "type": "LAST",
          "value": "Jensen"
        }
      ],
      "dateOfBirth": "1990-05-15",
      "nationality": "LT",
      "email": "[email protected]",
      "contacts": [],
      "documents": [],
      "addresses": [
        {
          "type": "HOME",
          "street": "123 Medium Risk Street",
          "city": "Compliance City",
          "postalCode": "12345",
          "country": "LT",
          "isPrimary": true
        }
      ]
    },
    "user": {
      "id": "23cfc195-be4a-4e7c-88f2-ef789ae83d39",
      "email": "[email protected]",
      "roles": [],
      "permissions": [],
      "isActive": false,
      "requiresPasswordChange": false,
      "twoFactorEnabled": false
    },
    "notifications": [],
    "createdAt": "2026-01-12T19:21:59.019243Z",
    "updatedAt": "2026-01-12T19:21:59.019243Z",
    "consents": [],
    "organizationAssociations": []
  }
}

Individual Customer Registration

Register a new individual (B2C) customer with complete profile information, address history, and user account creation.
Endpoint: POST /api/v2.1/customer/individual/registration

Prerequisites

1

Get Categorization Hierarchy

Call GET /customer/individual/categorization/hierarchy/ to retrieve available categories and features.This returns the valid values you can use in registration.
2

Prepare Registration Data

Structure your request according to the required nested format with individualCustomer.person and individualCustomer.user.
3

Submit Registration

POST the registration request with all required fields.
The system automatically assigns the customer to the B2C Individual category. The response includes the categorization object showing the assigned category and its features.

Endpoint

POST /api/v2.1/customer/individual/registration

Headers

For complete details on authentication, compliance headers, and SDK implementation examples, refer to the Standard HTTP Headers reference documentation.
X-Tenant-ID
string
required
Tenant identifier for multi-tenant operationsExample: tenant_cloudvault
Authorization
string
required
Bearer token for authentication (admin privileges required for manual registration)Example: Bearer eyJ0eXAiOiJKV1QiLCJh...
Content-Type
string
required
Must be application/json
X-Forwarded-For
string
required
Required for Compliance & AuditClient’s originating IP address (critical for AML/KYC compliance)Format: IPv4 or IPv6 addressExamples:
  • 192.168.1.100
  • 2001:0db8:85a3:0000:0000:8a2e:0370:7334
This header is mandatory for all customer registration operations. It is captured and stored for regulatory compliance, fraud detection, and audit trails.
User-Agent
string
required
Required for Compliance & AuditClient application identifier (browser, mobile app, SDK version)Examples:
  • Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
  • Mobile: FinhubApp/2.1.0 (iOS 15.0; iPhone13,2)
  • SDK: finhub-sdk-js/1.5.0
This header is captured for security analysis, device fingerprinting, and compliance reporting.
Accept
string
Response format (default: application/json)

Request Body

The request body uses a nested structure. Do not send a flat object. All customer details must be inside the individualCustomer wrapper object.

Top-Level Fields

tenantId
string
required
Tenant identifier (must match X-Tenant-ID header)
firstName
string
required
Customer’s first name (also duplicated in individualCustomer.person.firstName)
lastName
string
required
Customer’s last name (also duplicated in individualCustomer.person.lastName)
email
string
required
Customer’s email address (also duplicated in individualCustomer.person.email)Must be unique within the tenant.
phone
string
required
Phone number with country codeFormat: E.164 (e.g., +37060012345)
password
string
required
Password for the customer’s user accountSecurity Requirements:
  • Minimum 8 characters
  • Must contain uppercase and lowercase letters
  • Must contain at least one number
  • Must contain at least one special character
matchingPassword
string
required
Password confirmation (must exactly match password)
roleIds
array
required
Array of role identifiers for the userStandard Roles:
  • ACCOUNT_OWNER: Primary account owner
  • USER: Standard user permissions
Example: ["ACCOUNT_OWNER", "USER"]

Individual Customer Object

individualCustomer
object
required
Nested object containing all customer details

Code Examples

curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/individual/registration" \
  -H "X-Tenant-ID: tenant_cloudvault" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-For: 192.168.1.100" \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
  -H "Accept: application/json" \
  -d '{
    "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "firstName": "Marcus",
    "lastName": "Jensen",
    "email": "[email protected]",
    "phone": "+37060012345",
    "password": "SecurePassword123!",
    "matchingPassword": "SecurePassword123!",
    "roleIds": ["ACCOUNT_OWNER", "USER"],
    "individualCustomer": {
      "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
      "customerName": "Marcus Jensen",
      "person": {
        "id": "the2r6zaa6",
        "firstName": "Marcus",
        "lastName": "Jensen",
        "email": "[email protected]",
        "dateOfBirth": "1990-05-15",
        "gender": "MALE",
        "nationality": "LT",
        "placeOfBirth": "Vilnius",
        "fullName": "Marcus Jensen",
        "addresses": [
          {
            "id": "6vsvy01jbzo",
            "type": "HOME",
            "street": "123 Medium Risk Street",
            "city": "Compliance City",
            "postalCode": "12345",
            "country": "LT",
            "isPrimary": true
          }
        ],
        "contacts": [
          {
            "id": "g4dh2ch831",
            "type": "EMAIL",
            "value": "[email protected]",
            "isPrimary": true
          }
        ]
      },
      "user": {
        "id": "uhqvq7sc80m",
        "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
        "username": "[email protected]",
        "email": "[email protected]",
        "password": "SecurePassword123!",
        "status": "PENDING_ACTIVATION",
        "roles": ["ACCOUNT_OWNER", "USER"],
        "isActive": false
      }
    }
  }'

Advanced: Registration with Categorization

When registering medium or high-risk customers, you can include categorization with feature parametrization to define risk assessment parameters upfront. This follows the pattern used in production for sophisticated risk management.

How It Works

  1. Get Categorization Hierarchy - Call GET /customer/individual/categorization/hierarchy/
  2. Select Category - Choose appropriate category based on risk level (e.g., “MEDIUM_RISK_INDIVIDUAL”, “VERIFIED_INDIVIDUAL”)
  3. Build Feature Relations - Map category features with smart value selection
  4. Include in Registration - Add categorization object to individualCustomer

Example: Medium-Risk Customer with Categorization

curl -X POST "https://sandbox.finhub.cloud/api/v2.1/customer/individual/registration" \
  -H "X-Tenant-ID: tenant_cloudvault" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-For: 192.168.1.100" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{
    "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "firstName": "Marcus",
    "lastName": "Jensen",
    "email": "[email protected]",
    "phone": "+37060012345",
    "password": "SecurePassword123!",
    "matchingPassword": "SecurePassword123!",
    "roleIds": ["ACCOUNT_OWNER", "USER"],
    "individualCustomer": {
      "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
      "customerName": "Marcus Jensen",
      "person": {
        "firstName": "Marcus",
        "lastName": "Jensen",
        "email": "[email protected]",
        "dateOfBirth": "1990-05-15",
        "gender": "MALE",
        "nationality": "LT",
        "addresses": [
          {
            "type": "HOME",
            "street": "123 Medium Risk Street",
            "city": "Vilnius",
            "postalCode": "12345",
            "country": "LT",
            "isPrimary": true
          }
        ],
        "contacts": [
          {
            "type": "EMAIL",
            "value": "[email protected]",
            "isPrimary": true
          }
        ]
      },
      "user": {
        "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
        "username": "[email protected]",
        "email": "[email protected]",
        "password": "SecurePassword123!",
        "status": "PENDING_ACTIVATION",
        "roles": ["ACCOUNT_OWNER", "USER"],
        "isActive": false
      },
      "categorization": {
        "id": "medium-risk-verified-5f8a9b",
        "name": "MEDIUM_RISK_VERIFIED_INDIVIDUAL",
        "description": "Medium risk verified individual customer",
        "isActive": true,
        "categoryFeatureRelations": [
          {
            "feature": {
              "id": "risk-assessment-3c4d",
              "code": "RISK_ASSESSMENT"
            },
            "enabled": true,
            "parametrization": [
              {
                "name": "RISK_LEVEL",
                "value": "MEDIUM"
              },
              {
                "name": "RISK_SCORE",
                "value": "55"
              },
              {
                "name": "PEP_STATUS",
                "value": "false"
              },
              {
                "name": "SANCTIONS_CHECK",
                "value": "STANDARD"
              },
              {
                "name": "MONITORING_FREQUENCY",
                "value": "WEEKLY"
              }
            ]
          },
          {
            "feature": {
              "id": "transaction-limits-7e2f",
              "code": "TRANSACTION_LIMITS"
            },
            "enabled": true,
            "parametrization": [
              {
                "name": "MONTHLY_LIMIT",
                "value": "20000"
              },
              {
                "name": "DAILY_LIMIT",
                "value": "5000"
              },
              {
                "name": "PER_TRANSACTION_LIMIT",
                "value": "2000"
              }
            ]
          },
          {
            "feature": {
              "id": "verification-requirements-9a1b",
              "code": "VERIFICATION_REQUIREMENTS"
            },
            "enabled": true,
            "parametrization": [
              {
                "name": "IDENTITY_VERIFICATION",
                "value": "REQUIRED"
              },
              {
                "name": "DOCUMENT_VERIFICATION",
                "value": "REQUIRED"
              },
              {
                "name": "ENHANCED_DUE_DILIGENCE",
                "value": "OPTIONAL"
              }
            ]
          }
        ]
      }
    }
  }'

Categorization Benefits

Why Use Categorization During Registration?
  1. Risk-Based Onboarding - Automatically apply appropriate risk controls
  2. Transaction Limits - Set limits based on customer risk profile
  3. Verification Requirements - Define required KYC/AML checks upfront
  4. Monitoring Frequency - Schedule appropriate transaction monitoring
  5. Compliance Automation - Ensure regulatory requirements are met

Smart Value Selection

The examples above demonstrate smart value selection patterns used in production:
ParameterSmart Selection LogicExample Values
RISK_LEVELMatch “MEDIUM”, “STANDARD”, or use middle valueMEDIUM, STANDARD, LOW
RISK_SCOREMatch 40-69 range for medium risk55, 50, 60
PEP_STATUSMatch “FALSE” or “NO”false, NO, NOT_APPLICABLE
SANCTIONS_CHECKMatch “STANDARD” or “PERIODIC”STANDARD, PERIODIC, DAILY
MONITORING_FREQUENCYMatch “WEEKLY” or “STANDARD”WEEKLY, STANDARD, DAILY
MONTHLY_LIMITMatch 15K-25K range for medium risk20000, 15000, 25000
Production Pattern: Always retrieve the categorization hierarchy first, then use smart value selection to build appropriate categoryFeatureRelations based on the customer’s risk profile.

Response

{
  "code": 200,
  "message": "B2C individual account created successfully. Redirect to activate-account page",
  "redirectUrl": "/auth/activate-account",
  "data": {
    "organization": false,
    "individual": true,
    "id": "5887c98c-b5b1-4234-b819-a4987f54aa77",
    "tenantId": "d1e2f3a4-b5c6-47d8-9e0f-1a2b3c4d5e6f",
    "customerType": "CT_PERSON",
    "customerStatus": "CS_REGISTRATION_COMPLETED",
    "categorization": {
      "active": true,
      "id": "B2CCustomerIndividual",
      "name": "B2C Individual",
      "description": "Customer categorization for B2C",
      "isActive": true,
      "categoryFeatureRelations": [],
      "parametrization": []
    },
    "person": {
      "lastName": "Jensen",
      "firstName": "Marcus",
      "id": "the2r6zaa6",
      "names": [
        {
          "type": "FIRST",
          "value": "Marcus"
        },
        {
          "type": "LAST",
          "value": "Jensen"
        }
      ],
      "dateOfBirth": "1990-05-15",
      "nationality": "LT",
      "email": "[email protected]",
      "contacts": [],
      "documents": [],
      "addresses": [
        {
          "type": "HOME",
          "street": "123 Medium Risk Street",
          "city": "Compliance City",
          "postalCode": "12345",
          "country": "LT",
          "isPrimary": true
        }
      ]
    },
    "user": {
      "id": "23cfc195-be4a-4e7c-88f2-ef789ae83d39",
      "email": "[email protected]",
      "roles": [],
      "permissions": [],
      "isActive": false,
      "requiresPasswordChange": false,
      "twoFactorEnabled": false
    },
    "notifications": [],
    "createdAt": "2026-01-12T19:21:59.019243Z",
    "updatedAt": "2026-01-12T19:21:59.019243Z",
    "consents": [],
    "organizationAssociations": []
  }
}

Response Fields

Success Response (data object)

FieldTypeDescription
idstringUnique customer identifier (UUID)
tenantIdstringTenant identifier
customerTypestringAlways "CT_PERSON" for individuals
customerStatusstringInitial status: "CS_REGISTRATION_COMPLETED"
individualbooleanAlways true for individual customers
organizationbooleanAlways false for individual customers
personobjectPerson details (simplified from request)
userobjectUser account details
categorizationobjectApplied customer category
redirectUrlstringNext step URL (activation page)
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last update timestamp

Next Steps After Registration

  1. User Receives Activation Email
    • System sends activation email to registered address
    • Email contains activation code and link
  2. User Completes Activation
  3. KYC Verification Required
  4. Account Becomes Fully Active
    • After KYC approval, customer can perform all operations
    • Wallet is created automatically upon activation

Common Validation Errors

Password Mismatch

Error:
{
  "code": 400,
  "message": "Password and matching password do not match"
}
Solution: Ensure password and matchingPassword are identical

Duplicate Email

Error:
{
  "code": 409,
  "message": "Customer with email '...' already exists"
}
Solution: Email addresses must be unique within the tenant. Use a different email or retrieve the existing customer.

Invalid Nested Structure

Error:
{
  "code": 400,
  "message": "individualCustomer is required"
}
Solution: Ensure you’re using the nested structure with individualCustomer.person.* hierarchy. Do not send a flat object.

Missing Required Fields

Error:
{
  "code": 400,
  "message": "firstName is required in person object"
}
Solution: All fields marked as “required” must be present in the request. Check the field is in the correct nested location.

Best Practices

Recommended Flow:
  1. Validate Input - Check all required fields before sending
  2. Hash Passwords - Never log or store passwords in plain text
  3. Handle Activation - Guide user through activation process
  4. Complete KYC - Ensure verification is completed before enabling financial operations
  5. Monitor Status - Track customer status through the workflow

Password Security

  • Use strong password requirements (enforced by API)
  • Never send passwords over unencrypted connections
  • Implement password strength indicator in UI
  • Consider implementing password hashing client-side

Data Validation

// Example validation before API call
const validateRegistrationData = (data) => {
  const errors = [];
  
  // Check password match
  if (data.password !== data.matchingPassword) {
    errors.push('Passwords do not match');
  }
  
  // Validate email format
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(data.email)) {
    errors.push('Invalid email format');
  }
  
  // Validate phone format (E.164)
  const phoneRegex = /^\+[1-9]\d{1,14}$/;
  if (!phoneRegex.test(data.phone)) {
    errors.push('Invalid phone format (use E.164: +1234567890)');
  }
  
  // Check nested structure exists
  if (!data.individualCustomer || !data.individualCustomer.person) {
    errors.push('Missing required nested structure');
  }
  
  return errors;
};

API Schema Reference

For the complete OpenAPI schema specification of this endpoint, including all request and response structures, see the API Schema Mapping document.

Changelog

VersionDateChanges
v2.12026-01-13Initial release