Beneficiary
Overview
A Beneficiary is a person named on an existing account who inherits its assets under specified
circumstances — the traditional account-beneficiary concept. Their User record has to exist before they can be added to an account via the Account Beneficiaries endpoints (POST /accounts/{accountID}/beneficiaries, not covered by this guide).
This is the BENEFICIARY userType. See Creating a user if you're not sure this is the one you need.
Create the user
Standard identity documents — the same shape as an INDIVIDUAL_TRADER, just with userType: BENEFICIARY.
curl -X POST https://api.drivewealth.com/users \
-H "Authorization: Bearer $DW_BEARER_TOKEN" \
-H "dw-client-app-key: $DW_APP_KEY" \
-H "Content-Type: application/json" \
-d '{
"userType": "BENEFICIARY",
"username": "jordan.smith.beneficiary",
"password": "my#1Account",
"documents": [
{
"type": "BASIC_INFO",
"data": {
"firstName": "Jordan",
"lastName": "Smith",
"country": "USA",
"phone": "12025550149",
"emailAddress": "[email protected]"
}
},
{
"type": "IDENTIFICATION_INFO",
"data": {
"value": "402724321",
"type": "SSN",
"citizenship": "USA"
}
},
{
"type": "PERSONAL_INFO",
"data": {
"birthDay": 14,
"birthMonth": 6,
"birthYear": 1990,
"politicallyExposedNames": "NULL"
}
},
{
"type": "ADDRESS_INFO",
"data": {
"street1": "15 Exchange Place",
"street2": "Suite 1000",
"city": "Jersey City",
"province": "NJ",
"postalCode": "07302",
"country": "USA"
}
}
]
}'Response — 200
{
"id": "f25aeed1-1439-4dce-8b90-09221bc83167",
"username": "jordan.smith.beneficiary",
"userType": {
"name": "BENEFICIARY",
"description": "Beneficiary"
},
"status": {
"name": "APPROVED",
"description": "User approved."
},
"parentIB": {
"id": "80f9b672-120d-4b73-9cc9-42fb3262c4b9",
"name": "DriveWealth"
},
"documents": [
{
"type": "ADDRESS_INFO",
"data": {
"street1": "15 Exchange Place",
"street2": "Suite 1000",
"city": "Jersey City",
"province": "NJ",
"postalCode": "07302",
"country": "USA"
},
"description": "Physical address information"
},
{
"type": "BASIC_INFO",
"data": {
"firstName": "Jordan",
"lastName": "Smith",
"displayName": "JSmith",
"emailAddress": "[email protected]",
"phone": "12025550149",
"country": "USA",
"language": "en_US"
},
"description": "Name, email, phone, etc."
},
{
"type": "IDENTIFICATION_INFO",
"data": {
"value": "****4321",
"type": "SSN",
"citizenship": "USA",
"description": "Social Security Number"
},
"description": "ID Number and citizenship"
},
{
"type": "PERSONAL_INFO",
"data": {
"birthdate": "1990-06-14",
"politicallyExposedNames": "NULL"
},
"description": "Birth date, gender, marital status, etc."
},
{
"type": "TAX_INFO",
"data": {
"usTaxpayer": true,
"taxTreatyWithUS": false
},
"description": "Tax Information"
}
],
"wlpID": "DW",
"referralCode": "JZPSZO",
"createdWhen": "2026-09-02T20:51:45.991Z",
"updatedWhen": "2026-09-02T20:51:45.991Z"
}Document types used here
No document types unique to this flow — the same four base documents as
Creating a User (BASIC_INFO, IDENTIFICATION_INFO, PERSONAL_INFO, ADDRESS_INFO). Don't send a CUSTODIAN_INFO document here; that's specific to Custodial accounts.
Complete onboarding
PATCH /users/USERID — attach more documents, correct a field, or sign an attestation.
The body shape is identical to create: a documents array, any subset of types. There's no separate
endpoint for the tax attestation — it's a PATCH carrying a TAX_INFO document with a nested
attestation:
{
"documents": [
{
"type": "TAX_INFO",
"data": {
"attestation": {
"signedBy": "f25aeed1-1439-4dce-8b90-09221bc83167"
}
}
}
]
}And here's a corrected address, the same shape you'd use for any field-level fix:
{
"documents": [
{
"type": "ADDRESS_INFO",
"data": {
"street1": "480 Washington Blvd",
"city": "Jersey City",
"province": "NJ",
"postalCode": "07310"
}
}
]
}Check KYC status
Two status fields, two different resolutions — know which one you're gating on.
The User object itself (from create, retrieve, or update) only ever reports a coarse status.name:
PENDING or APPROVED. That's enough to gate account creation, but not enough to tell a user why
they're stuck. For that, call the dedicated status endpoint:
curl -X GET https://api.drivewealth.com/users/f25aeed1-1439-4dce-8b90-09221bc83167/kyc-status \
-H "Authorization: Bearer $DW_BEARER_TOKEN" \
-H "dw-client-app-key: $DW_APP_KEY"{
"userID": "f25aeed1-1439-4dce-8b90-09221bc83167",
"firstname": "Jordan",
"lastname": "Smith",
"identity": {
"number": "*******-4321",
"dob": "1990-06-14"
},
"accounts": [],
"kyc": {
"approved": {
"timestamp": "2026-09-02T20:51:46.035Z",
"approvedBy": "80f9b672-120d-4b73-9cc9-42fb3262c4b9"
},
"accepted": {
"acceptedBy": "SYSTEM PRINCIPAL APPROVER",
"timestamp": "2026-09-02T20:51:46.035Z"
}
},
"status": {
"name": "APPROVED",
"description": "User approved."
},
"partnerID": {
"id": "80f9b672-120d-4b73-9cc9-42fb3262c4b9",
"name": "Uttam_Investment"
},
"documents": []
}kyc.status.name only progresses through these intermediate states for do-KYC partners (DriveWealth
performs screening). For no-KYC/verify-KYC partners, the User is approved as soon as the required documents land, so you'll typically see KYC_APPROVED right away with no prior states to track.
When it does progress, kyc.status.name is the granular reason code you'll base your next step on:
| Status | Meaning | Next step |
|---|---|---|
KYC_NOT_READY | Required documents haven't been submitted yet | PATCH the missing documents, then wait for the update event |
KYC_READY | Documents complete, queued for processing | Wait for the update event, no action needed |
KYC_PROCESSING | Verification in progress | Wait for the update event, no action needed |
KYC_INFO_REQUIRED | PII didn't match — needs a corrected PATCH | Send the user back into your onboarding UI to fix the mismatched field(s), then PATCH |
KYC_DOC_REQUIRED | A supporting document is missing | Prompt for the specific missing document, then PATCH |
KYC_MANUAL_REVIEW | Escalated to a human reviewer | Show an "under review" state and wait — this can take longer than the automated states |
KYC_APPROVED | Terminal — cleared | Proceed to open an Account |
KYC_DENIED | Terminal — rejected | Surface the denial, don't retry the same payload |
For do-KYC partners, don't poll this endpoint as your primary signal — subscribe to the kyc.created / kyc.updated event on your SQS queue. Its payload.current.status already carries the new kyc.status.name value directly, so you don't need to re-fetch kyc-status just to learn what changed:
{
"id": "event_789ca9ba-312b-4480-9f36-3805ceb00f63",
"type": "kyc.updated",
"ibID": "80f9b672-120d-4b73-9cc9-42fb3262c4b9",
"object": "KYC_UPDATED",
"timestamp": "2026-07-23T07:08:14.121518146Z",
"payload": {
"current": {
"status": "KYC_APPROVED",
"statusMessage": "KYC Approved",
"details": ["POOR_PHOTO_QUALITY"]
},
"previous": {
"status": "KYC_APPROVED",
"statusMessage": "KYC Approved",
"details": ["POOR_PHOTO_QUALITY"]
},
"userID": "f25aeed1-1439-4dce-8b90-09221bc83167"
}
}Compare payload.current.status against payload.previous.status to confirm it actually changed, and use
payload.userID to look up the User in your own system. Reserve polling kyc-status for an occasional
reconciliation pass (catching a missed or delayed event), not the main driver of your UI.
Requirements vary by country
Everything above is the USA shape. Don't assume it generalizes:
- ID type:
IDENTIFICATION_INFO.typeaccepts more thanSSN—PASSPORT,ALIEN_ID,OTHER, etc., and non-SSNtypes requireissuingCountry. - "Doc countries": some countries require an actual scanned/photographed document (ID, proof of
address) to clear KYC, not just the structureddatafields above — that upload goes through the
separate Physical Documents API, notdocuments[]on this endpoint. - Which documents are required at all: KYC rules are configured per country/partner and aren't fully
exposed by the request schema — a payload that 200s isn't proof it satisfies every country's requirements.
If you're onboarding a non-US country / citizenship, confirm the required document types, fields, and
KYC rules for that specific region with DriveWealth and the relevant regulatory bodies first.
What's next
Once this User exists and clears KYC, name them on the relevant account through the Account Beneficiaries endpoints.
Updated about 5 hours ago