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 cpVerificationStatusUpdated webhook. 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

ScenarioDescription
VerifiedCustomer Profile+ has been successfully verified.
RejectedCustomer Profile+ has been rejected. Check isRetryable and verificationRejectionSummary.

Status values

StatusDescription
pendingCustomer profile submitted, verification in progress.
verifiedCustomer profile successfully verified.
rejectedCustomer 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.

FieldScopeTypeDescription
data.attributes.customerNativeNameCommon fieldsStringCustomer name in native script.
data.attributes.customerFirstNameCommon fieldsStringCustomer first name.
data.attributes.customerLastNameCommon fieldsStringCustomer last name.
data.attributes.purposeOfAccountCommon fieldsStringPurpose of opening the account.
data.attributes.otherPurposeOfAccountCommon fieldsStringFree-text purpose. Only present when purposeOfAccount includes OTHERS.
data.attributes.sourceOfWealthCommon fieldsObjectDeclared source(s) of wealth. See sourceOfWealth object below.
data.attributes.registrationIdExpiryDatePersonal onlyStringExpiry date of the registration ID (YYYY-MM-DD).
data.attributes.occupationPersonal onlyStringCustomer's occupation.
data.attributes.businessIndustryPersonal onlyStringIndustry the customer works in.
data.attributes.expectedAnnualTransactionAmountPersonal onlyStringExpected annual transaction volume.
data.attributes.expectedTransactionSizePersonal onlyStringExpected average transaction size.
data.attributes.expectedTransactionFrequencyPersonal onlyStringExpected transaction frequency.
data.attributes.annualIncomePersonal onlyStringCustomer's declared annual income.
data.attributes.totalWealthPersonal onlyStringCustomer's declared total wealth.
data.attributes.ipAddressesPersonal onlyArray of stringsIP addresses used during onboarding.
data.attributes.countryOfResidencePersonal onlyStringCountry of residence (ISO alpha-2).
data.attributes.operatingAddressBusiness onlyObjectOperating address (same shape as address: street, city, state, country, postalCode).
data.attributes.entityLegalFormBusiness onlyStringLegal entity type (e.g., PUBLIC_COMPANY, PRIVATE_LIMITED, SOLE_PROPRIETORSHIP).
data.attributes.businessContactBusiness onlyStringBusiness contact number.
data.attributes.websiteBusiness onlyStringBusiness website URL.
data.attributes.intermediariesBusiness onlyBooleanWhether the business uses intermediaries.
data.attributes.natureOfBusinessBusiness onlyStringDescription of the business's activities.
data.attributes.otherNatureOfBusinessBusiness onlyStringFree-text nature of business. Only present when natureOfBusiness includes OTHERS.
data.attributes.usOwnershipBusiness onlyBooleanWhether the business has US ownership.
data.attributes.monthlyTransactionVolumeBusiness onlyStringExpected monthly transaction volume.
data.attributes.sourceOfFundsBusiness onlyArray of stringsDeclared source(s) of business funds.
data.attributes.otherSourceOfFundsBusiness onlyStringFree-text source of funds. Only present when sourceOfFunds includes OTHERS.
data.attributes.directorsBusiness onlyArray of objectsList of company directors. See directors/beneficialOwners object below.
data.attributes.beneficialOwnersBusiness onlyArray of objectsList of beneficial owners (≥25% ownership). Same structure as directors.
data.attributes.traderBusiness onlyObjectPerson operating the account on behalf of the business. Same structure as a director entry, plus livenessResult (boolean).
data.attributes.licensingStatusBusiness onlyStringBusiness licensing status.
📘

The following fields are not present in verified callbacks and only appear in rejection callbacks when isRetryable is true:

  • identityDocuments
  • sourceOfWealth
  • intermediariesDocuments
  • documents

See the Rejection-specific fields section below for details.

directors[] / beneficialOwners[] items

FieldTypeDescription
firstNameStringFirst name.
lastNameStringLast name.
nationalityStringISO alpha-2 country code.
dateOfBirthStringDate of birth (YYYY-MM-DD).
registrationIdStringIdentity number.
registrationIdTypeStringType of ID (e.g., passport, identity_card).
registrationIdCountryStringCountry that issued the ID (ISO alpha-2).
countryOfResidenceStringCountry of residence (ISO alpha-2).

trader object

Same fields as directors[] items above, plus:

FieldTypeDescription
livenessResultBooleanWhether 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.

FieldTypeDescription
data.attributes.isRetryableBooleanWhether 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.verificationRejectionSummaryStringHuman-readable summary of why the profile was rejected.
data.attributes.riskRatingObjectRisk rating details. See riskRating object below.

riskRating object

FieldTypeDescription
statusStringAlways "rejected" in rejection callbacks.
rejection_reasonArray of stringsList of rejection reasons.
Note: uses snake_case (not camelCase).
rejectionsArray of objects(Optional) Detailed rejection entries. May not always be present.

rejections[] items

FieldTypeDescription
codeStringRejection code.
reasonStringShort rejection reason label.
messageStringHuman-readable explanation.

Document fields behavior in rejection context

FieldConditionTypeDescription
data.attributes.identityDocumentsisRetryable: trueObjectEach document entry includes status and rejectionReason. URLs are not included.
data.attributes.sourceOfWealthisRetryable: trueObjectEach source entry includes status and rejectionReason.
data.attributes.intermediariesDocumentsisRetryable: true, Business onlyArray of objectsIntermediary documents included as-is with document URLs.
data.attributes.documentsisRetryable: true, Business onlyObjectBusiness documents included as-is with document URLs.
📘

Note:

When isRetryable is false, both identityDocuments, sourceOfWealth, intermediariesDocuments, and documents are removed entirely from the payload.

identityDocuments entries

Each document entry (e.g., selfie, passport, idFront, idBack, proofOfAddress, livenessSnapshot):

FieldTypeDescription
statusString"verified" or "rejected".
rejectionReasonStringReason 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

Each source entry (e.g., cashSavings, lotteryWinnings, inheritance):

FieldTypeDescription
statusString"verified" or "rejected".
rejectionReasonStringReason the source was rejected. Empty string if passed.


Did this page help you?