User API
Manage user profile and preferences.
Authentication. Profile and wallet read operations in this section accept either a session cookie or an organization API key (
kh_). Mutating operations require session authentication and reject API keys with401: profile mutation, password change, forgot-password, account deactivation, RPC preferences, and every wallet write operation (withdraw, share, refresh-share, export-key, active wallet switch, fee estimation). Address book entries are organization-scoped and accept either method. See Authentication for the full scope rules.
Get User Profile
GET /api/userResponse
{
"id": "user_123",
"name": "John Doe",
"email": "[email protected]",
"image": "https://...",
"isAnonymous": false,
"providerId": "google",
"walletAddress": "0x..."
}Update User Profile
PATCH /api/userNote: OAuth users cannot update email or name.
Request Body
{
"name": "New Name"
}Get Wallet
GET /api/user/walletReturns the Turnkey wallet for the authenticated user’s active organization. The wallet is organization-scoped, not per-user.
Response
{
"hasWallet": true,
"id": "wallet_...",
"canExportKey": true,
"isOwner": true,
"walletAddress": "0x...",
"walletId": "turnkey_wallet_...",
"email": "[email protected]",
"createdAt": "2026-01-01T00:00:00.000Z",
"organizationId": "org_...",
"isActive": true
}When the organization has no wallet yet, the response is { "hasWallet": false, "message": "No wallet found for this organization" }.
Balances are not included here. Fetch them from GET /api/user/wallet/balances.
RPC Preferences
Manage custom RPC endpoints per chain.
List RPC Preferences
GET /api/user/rpc-preferencesResponse
Returns two arrays. preferences lists the user’s saved overrides; resolved lists the effective RPC config for every chain after merging overrides with platform defaults. source is "user" when a preference is in effect, "default" otherwise.
{
"preferences": [
{
"id": "pref_abc123",
"chainId": 1,
"primaryRpcUrl": "https://custom-rpc.example.com",
"fallbackRpcUrl": "https://fallback.example.com",
"createdAt": "2026-05-01T12:00:00.000Z",
"updatedAt": "2026-05-01T12:00:00.000Z"
}
],
"resolved": [
{
"chainId": 1,
"chainName": "Ethereum Mainnet",
"primaryRpcUrl": "https://custom-rpc.example.com",
"fallbackRpcUrl": "https://fallback.example.com",
"primaryWssUrl": null,
"fallbackWssUrl": null,
"source": "user"
}
]
}Get Chain RPC Preference
GET /api/user/rpc-preferences/{chainId}Set or Update Chain RPC Preference
PUT /api/user/rpc-preferences/{chainId}Request Body
{
"primaryRpcUrl": "https://custom-rpc.example.com",
"fallbackRpcUrl": "https://fallback.example.com"
}fallbackRpcUrl is optional. To clear an existing preference, use the DELETE endpoint below instead of sending an empty body.
Delete Chain RPC Preference
DELETE /api/user/rpc-preferences/{chainId}Reverts to default RPC endpoints for the chain.
Change Password
POST /api/user/passwordChange the password for a credential-based account. Requires the current password and a new password (minimum 8 characters). Not available for OAuth-only accounts.
Request Body
{
"currentPassword": "old-password",
"newPassword": "new-password"
}Forgot Password
POST /api/user/forgot-passwordHandles password reset via OTP. Supports two actions controlled by the action field in the request body.
Request OTP (default when action is omitted or set to "request"):
{
"email": "[email protected]"
}Reset password (action: "reset"):
{
"action": "reset",
"email": "[email protected]",
"otp": "123456",
"newPassword": "new-password"
}The OTP expires after 5 minutes. OAuth-only accounts receive a notification email instead of a reset code.
Deactivate Account
POST /api/user/deleteSoft-deletes the authenticated user account. Requires a confirmation string in the request body. Invalidates all active sessions on success. Not available for anonymous users.
Request Body
{
"confirmation": "DEACTIVATE"
}Address Book
Manage saved Ethereum addresses scoped to the active organization. All address book endpoints require an active organization context.
List Address Book Entries
GET /api/address-bookReturns all address book entries for the active organization, ordered by creation date (newest first).
Create Address Book Entry
POST /api/address-bookRequest Body
{
"label": "Treasury Wallet",
"address": "0x..."
}The address must be a valid Ethereum address.
Update Address Book Entry
PATCH /api/address-book/{entryId}Update the label or address of an existing entry. Both fields are optional.
Delete Address Book Entry
DELETE /api/address-book/{entryId}Removes the entry from the organization address book.