Create sub-account
Sub-Accounts & White-Label Retail KYC
/users
Create sub-account
createUsersCreates a new sub-account. Each sub-account has an isolated USD wallet, portfolio, and order book. The externalId is your own reference — it must be unique per partner and is used in all subsequent calls. Sub-accounts start with a walletBalance of $0 — fund them via POST /users/{userId}/deposit.
Parameters
This endpoint has no path or query parameters.
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Idempotency-KeystringheaderRequiredUnique string that makes write calls safe to retry on network failure. Required for money movement, trading, KYC, subscriptions, and webhook creation. Deduplicated for 24 hours -- duplicate keys return the cached response. HTTP 409 if a concurrent request with the same key is still in progress.
Example: dep_user42_1743152580
Request body
externalIdstringRequiredYour internal user identifier. Must be unique per partner.
Example: "usr_8821"
displayNamestringFull name shown in the MyStocks admin console.
Example: "Alice K."
emailstringEmail address for the sub-account user.
Example: "alice@yourapp.com"
phonestringCustomer phone number in international format when available.
Example: "+254712345678"
countrystringISO 3166-1 alpha-2 country code used for onboarding and compliance context.
Example: "KE"
Response fields
subAccountIdstringMyStocks internal ID. Use in /users/{userId}/... paths.
Example: "usr_abc123"
userIdstringCompatible alias of subAccountId. Use subAccountId as the canonical stored identifier.
externalIdstringYour own user identifier as set at creation.
Example: "usr_8821"
displayNamestring | nullExample: "Alice K."
emailstring | nullExample: "alice@yourapp.com"
kycStatusNONE | PENDING | VERIFIED | REJECTEDVERIFIED required for trading and asset subscriptions. REJECTED remains gated until re-asserted.
kycLevelNONE | BASIC | FULLBASIC = ID verified. FULL = enhanced due diligence.
kycRejectionCodestring | nullStable rejection code when kycStatus is REJECTED.
kycRejectionReasonstring | nullCustomer-safe remediation guidance when kycStatus is REJECTED.
kycReviewedAtstring | nullTimestamp of the rejection decision.
statusactive | frozen | closedwalletBalancenumberCurrent USD wallet balance.
Example: 1250
Response codes
201Sub-account created.409externalId already exists.