Customer Profile+ Callbacks (CP+)
StraitsX sends a cpVerificationStatusUpdated callback to your registered URL when a Customer Profile+ (CP+) verification status changes.
Both Regular CP and CP+ verification callbacks fire on the same
cpVerificationStatusUpdatedwebhook. The payload structure differs based on the profile's tier. This page covers CP+ (Tier 2) only. For Regular CP payloads, see Customer Profile Callbacks (Regular CP).
When this callback fires
| Scenario | Description |
|---|---|
| Verified | Customer Profile+ has been successfully verified. |
| Rejected | Customer Profile+ has been rejected. Check isRetryable and verificationRejectionSummary. |
Status values
| Status | Description |
|---|---|
pending | Customer profile submitted, verification in progress. |
verified | Customer profile successfully verified. |
rejected | Customer profile rejected. |
Payload structure
{
"data": {
"id": "customer_profile_e7f8a9b0-c1d2-3456-e7f8-a9b0c1d23456",
"type": "customer_profile",
"attributes": {
"customerName": "Jane Doe",
"registrationType": "personal",
"registrationId": "S1234567A",
"verificationStatus": "verified",
"dateOfBirth": "1990-01-15",
"gender": "FEMALE",
"nationality": "SG",
"email": "[email protected]",
"phoneNo": "6591234567",
"address": {
"street": "123 Orchard Road",
"city": "Singapore",
"state": "Singapore",
"country": "SG",
"postalCode": "238888"
},
"registrationIdCountry": "SG",
"registrationIdType": "identity_card",
"registrationIdExpiryDate": "2030-06-15",
"occupation": "SENIOR_ASSOCIATE_OR_SENIOR_EXECUTIVE",
"businessIndustry": "FINANCIAL_SERVICES",
"expectedAnnualTransactionAmount": "10001_TO_50000",
"expectedTransactionSize": "1001_TO_5000",
"expectedTransactionFrequency": "AT_LEAST_ONCE_EVERY_2_WEEKS",
"annualIncome": "100001_TO_200000",
"totalWealth": "500001_TO_1000000",
"countryOfResidence": "SG",
"customerFirstName": "Jane",
"customerLastName": "Doe",
"purposeOfAccount": "TRADING_OR_INVESTMENT",
"createdAt": "2026-01-10T09:00:00Z",
"updatedAt": "2026-01-10T09:05:30Z"
}
}
}{
"data": {
"id": "customer_profile_989407bb-1cc8-4e9b-a73b-864a4d1ba1c0",
"type": "customer_profile",
"attributes": {
"customerName": "ABC Pte Ltd",
"tradingName": "ABC Brand",
"registrationType": "business",
"registrationId": "20123232321",
"verificationStatus": "verified",
"address": {
"city": "Singapore",
"state": "Singapore",
"street": "Northside 18th",
"country": "SG",
"postalCode": "8809"
},
"operatingAddress": {
"city": "Singapore",
"state": "Singapore",
"street": "Northside 18th",
"country": "SG",
"postalCode": "8809"
},
"registrationIdCountry": "SG",
"placeOfBiz": "SG",
"placeOfBizCountry": "SG",
"countryOfIncorporation": "SG",
"dateOfIncorporation": "1999-09-09",
"registrationIdType": "business_reg_no",
"purposeOfAccount": "OTHERS",
"otherPurposeOfAccount": "TEST",
"entityLegalForm": "PUBLIC_COMPANY",
"businessContact": "+6565123456",
"intermediaries": true,
"natureOfBusiness": "PERSONAL_INVESTMENT_COMPANIES",
"usOwnership": true,
"monthlyTransactionVolume": "80001_TO_100000",
"sourceOfFunds": ["PERSONAL_SAVINGS", "OTHERS"],
"otherSourceOfFunds": "other source of funds",
"directors": [
{
"lastName": "Doe",
"firstName": "John",
"nationality": "SG",
"dateOfBirth": "1950-01-01",
"registrationId": "A12321321",
"countryOfResidence": "SG",
"registrationIdType": "passport",
"registrationIdCountry": "SG"
}
],
"beneficialOwners": [
{
"lastName": "Doe",
"firstName": "John",
"nationality": "SG",
"dateOfBirth": "1950-01-01",
"registrationId": "A12321321",
"countryOfResidence": "SG",
"registrationIdType": "passport",
"registrationIdCountry": "SG"
}
],
"trader": {
"lastName": "Doe",
"firstName": "John",
"nationality": "SG",
"dateOfBirth": "1950-01-01",
"livenessResult": true,
"registrationId": "A12321321",
"countryOfResidence": "SG",
"registrationIdType": "identity_card",
"registrationIdCountry": "SG"
},
"licensingStatus": "NOT_SUBJECTED_TO_LICENSING_REQUIREMENTS",
"createdAt": "2024-12-26T17:01:52Z",
"updatedAt": "2024-12-26T17:01:59Z"
}
}
}{
"data": {
"id": "customer_profile_08d5ffe5-8a02-4dc2-aabb-9057b8ab3c65",
"type": "customer_profile",
"attributes": {
"customerName": "TEST REJECT",
"isRetryable": true,
"verificationRejectionSummary": "Rejected due to StraitsX policy",
"registrationType": "personal",
"registrationId": "S9823457FY",
"verificationStatus": "rejected",
"dateOfBirth": "1998-03-14",
"gender": "MALE",
"nationality": "SG",
"email": "[email protected]",
"phoneNo": "6595109217",
"address": {
"city": "KUALA LUMPUR",
"country": "MALAYSIA",
"postalCode": "18000",
"state": "KUALA LUMPUR",
"street": "SOUTH 16TH"
},
"registrationIdCountry": "SG",
"registrationIdType": "passport",
"registrationIdExpiryDate": "2030-12-30",
"businessIndustry": "PAWN_BROKERAGE",
"occupation": "SENIOR_ASSOCIATE_OR_SENIOR_EXECUTIVE",
"expectedAnnualTransactionAmount": "0_TO_1000",
"expectedTransactionSize": "0_TO_1000",
"expectedTransactionFrequency": "AT_LEAST_ONCE_EVERY_2_WEEKS",
"annualIncome": "0_TO_30000",
"identityDocuments": {
"selfie": {
"rejectionReason": "",
"status": "verified"
},
"passport": {
"rejectionReason": "",
"status": "verified"
},
"proofOfAddress": {
"rejectionReason": "",
"status": "verified"
},
"livenessSnapshot": {
"rejectionReason": "",
"status": "verified"
},
"livenessResult": true
},
"ipAddresses": ["10.0.1.1", "10.0.1.6"],
"countryOfResidence": "SG",
"customerNativeName": "中国宝武钢铁集团",
"customerFirstName": "TEST",
"customerLastName": "REJECT",
"sourceOfWealth": {
"cashSavings": {
"rejectionReason": "",
"status": "verified"
},
"lotteryWinnings": {
"rejectionReason": "",
"status": "verified"
}
},
"createdAt": "2025-09-15T07:07:16Z",
"updatedAt": "2025-09-15T07:10:22Z",
"riskRating": {
"status": "rejected",
"rejection_reason": ["Rejected due to StraitsX policy"]
}
}
}
}Field reference - CP+ additional fields
CP+ callbacks include all Regular CP fields (see Regular CP field reference), plus the additional fields below.
| Field | Scope | Type | Description |
|---|---|---|---|
data.attributes.customerNativeName | Common fields | String | Customer name in native script. |
data.attributes.customerFirstName | Common fields | String | Customer first name. |
data.attributes.customerLastName | Common fields | String | Customer last name. |
data.attributes.purposeOfAccount | Common fields | String | Purpose of opening the account. |
data.attributes.otherPurposeOfAccount | Common fields | String | Free-text purpose. Only present when purposeOfAccount includes OTHERS. |
data.attributes.sourceOfWealth | Common fields | Object | Declared source(s) of wealth. See sourceOfWealth object below. |
data.attributes.registrationIdExpiryDate | Personal only | String | Expiry date of the registration ID (YYYY-MM-DD). |
data.attributes.occupation | Personal only | String | Customer's occupation. |
data.attributes.businessIndustry | Personal only | String | Industry the customer works in. |
data.attributes.expectedAnnualTransactionAmount | Personal only | String | Expected annual transaction volume. |
data.attributes.expectedTransactionSize | Personal only | String | Expected average transaction size. |
data.attributes.expectedTransactionFrequency | Personal only | String | Expected transaction frequency. |
data.attributes.annualIncome | Personal only | String | Customer's declared annual income. |
data.attributes.totalWealth | Personal only | String | Customer's declared total wealth. |
data.attributes.ipAddresses | Personal only | Array of strings | IP addresses used during onboarding. |
data.attributes.countryOfResidence | Personal only | String | Country of residence (ISO alpha-2). |
data.attributes.operatingAddress | Business only | Object | Operating address (same shape as address: street, city, state, country, postalCode). |
data.attributes.entityLegalForm | Business only | String | Legal entity type (e.g., PUBLIC_COMPANY, PRIVATE_LIMITED, SOLE_PROPRIETORSHIP). |
data.attributes.businessContact | Business only | String | Business contact number. |
data.attributes.website | Business only | String | Business website URL. |
data.attributes.intermediaries | Business only | Boolean | Whether the business uses intermediaries. |
data.attributes.natureOfBusiness | Business only | String | Description of the business's activities. |
data.attributes.otherNatureOfBusiness | Business only | String | Free-text nature of business. Only present when natureOfBusiness includes OTHERS. |
data.attributes.usOwnership | Business only | Boolean | Whether the business has US ownership. |
data.attributes.monthlyTransactionVolume | Business only | String | Expected monthly transaction volume. |
data.attributes.sourceOfFunds | Business only | Array of strings | Declared source(s) of business funds. |
data.attributes.otherSourceOfFunds | Business only | String | Free-text source of funds. Only present when sourceOfFunds includes OTHERS. |
data.attributes.directors | Business only | Array of objects | List of company directors. See directors/beneficialOwners object below. |
data.attributes.beneficialOwners | Business only | Array of objects | List of beneficial owners (≥25% ownership). Same structure as directors. |
data.attributes.trader | Business only | Object | Person operating the account on behalf of the business. Same structure as a director entry, plus livenessResult (boolean). |
data.attributes.licensingStatus | Business only | String | Business licensing status. |
The following fields are not present in verified callbacks and only appear in rejection callbacks when
isRetryableis true:
identityDocumentssourceOfWealthintermediariesDocumentsdocumentsSee the Rejection-specific fields section below for details.
directors[] / beneficialOwners[] items
directors[] / beneficialOwners[] items| Field | Type | Description |
|---|---|---|
firstName | String | First name. |
lastName | String | Last name. |
nationality | String | ISO alpha-2 country code. |
dateOfBirth | String | Date of birth (YYYY-MM-DD). |
registrationId | String | Identity number. |
registrationIdType | String | Type of ID (e.g., passport, identity_card). |
registrationIdCountry | String | Country that issued the ID (ISO alpha-2). |
countryOfResidence | String | Country of residence (ISO alpha-2). |
trader object
trader objectSame fields as directors[] items above, plus:
| Field | Type | Description |
|---|---|---|
livenessResult | Boolean | Whether liveness verification passed. |
Field reference - Rejection-specific fields
These fields are only present when verificationStatus is rejected. They apply on top of all the fields above.
| Field | Type | Description |
|---|---|---|
data.attributes.isRetryable | Boolean | Whether the profile can be resubmitted with corrections. If true, prompt the customer to fix and resubmit. If false, the profile is permanently rejected. |
data.attributes.verificationRejectionSummary | String | Human-readable summary of why the profile was rejected. |
data.attributes.riskRating | Object | Risk rating details. See riskRating object below. |
riskRating object
riskRating object| Field | Type | Description |
|---|---|---|
status | String | Always "rejected" in rejection callbacks. |
rejection_reason | Array of strings | List of rejection reasons. Note: uses snake_case (not camelCase). |
rejections | Array of objects | (Optional) Detailed rejection entries. May not always be present. |
rejections[] items
rejections[] items| Field | Type | Description |
|---|---|---|
code | String | Rejection code. |
reason | String | Short rejection reason label. |
message | String | Human-readable explanation. |
Document fields behavior in rejection context
| Field | Condition | Type | Description |
|---|---|---|---|
data.attributes.identityDocuments | isRetryable: true | Object | Each document entry includes status and rejectionReason. URLs are not included. |
data.attributes.sourceOfWealth | isRetryable: true | Object | Each source entry includes status and rejectionReason. |
data.attributes.intermediariesDocuments | isRetryable: true, Business only | Array of objects | Intermediary documents included as-is with document URLs. |
data.attributes.documents | isRetryable: true, Business only | Object | Business documents included as-is with document URLs. |
Note:
When
isRetryableis false, bothidentityDocuments,sourceOfWealth,intermediariesDocuments, anddocumentsare removed entirely from the payload.
identityDocuments entries
identityDocuments entriesEach document entry (e.g., selfie, passport, idFront, idBack, proofOfAddress, livenessSnapshot):
| Field | Type | Description |
|---|---|---|
status | String | "verified" or "rejected". |
rejectionReason | String | Reason the document was rejected. Empty string if passed. |
Additionally, livenessResult (boolean) indicates whether liveness verification passed.
"identityDocuments": {
"livenessSnapshot": {
"rejectionReason": "",
"status": "verified"
},
"livenessResult": true // <-- this one
}sourceOfWealth entries
sourceOfWealth entriesEach source entry (e.g., cashSavings, lotteryWinnings, inheritance):
| Field | Type | Description |
|---|---|---|
status | String | "verified" or "rejected". |
rejectionReason | String | Reason the source was rejected. Empty string if passed. |
Updated 2 months ago

