Create users
Create platform users with automatic wallet and identity setup. Includes workflows for passive token holders and active users with API keys.
The "Create User" API allows you to directly create user accounts with automatic wallet and identity setup. Unlike invitations, this creates accounts immediately without sending emails.
When you want to send API requests as that user (minting, transferring, managing assets), you also need to create an API key and set up wallet verification for them using admin impersonation.
For the web interface approach, see the user guide.
Prerequisites
- Platform URL (e.g.,
https://your-platform.example.com) - API key from a user with the Identity Manager role (see Getting Started for API key setup)
- Wallet verification method enabled on your account (e.g., pincode or 2FA)
- For users needing API access: Platform admin role (along with Identity Manager)
When to use Create Users
Recommended scenarios
- Demo preparation - Setting up users quickly for demonstrations
- Testing environments - Creating test accounts with known credentials
- Passive token holders - Users who only receive tokens and don't perform on-chain actions
- Training scenarios - Preparing accounts for workshops or training
When to use invitations instead
- Production environments - Users should control their own credentials
- Security-sensitive setups - Users should generate their own wallets
No email notifications
Creating users through this method does not send automatic emails. The administrator manages all account details and can share credentials manually as needed.
User creation process
Prepare API request
Construct the API request with the user's name and email:
curl -X POST "https://your-platform.example.com/api/user/create" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "[email protected]",
"walletVerification": {
"secretVerificationCode": "123456"
}
}'Execute API call
When you execute the request, the platform:
- Validates your permissions - Confirms you have Identity Manager role
- Verifies your wallet - Uses your pincode/2FA to authorize the blockchain transaction
- Creates the user account - Generates a new account with a random password
- Deploys blockchain components - Creates wallet (EOA) and deploys identity contract
Blockchain transactions
Creating a user triggers on-chain transactions to generate the wallet and deploy the identity contract. This may take a few seconds to confirm.
Handle response
A successful response returns the created user with wallet and identity addresses:
{
"id": "usr_abc123",
"name": "John Doe",
"email": "[email protected]",
"wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"identity": "0x8e5F72f6E5b3B4D1234567890AbCdEf1234567890"
}Verify user creation
Confirm the user was created by querying the user list or fetching the user directly:
# Search for the user by email
curl -X GET "https://your-platform.example.com/api/user/[email protected]" \
-H "X-Api-Key: YOUR_API_KEY"Response:
[
{
"id": "usr_abc123",
"name": "John Doe",
"wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"role": "member"
}
]The user should appear with the wallet address from the creation response.
Create API key (optional)
If this user needs to send API requests (minting, transferring, managing assets), create an API key for them using admin impersonation.
Admin role required
Creating API keys for other users requires the platform admin role (along with Identity Manager). The first platform user automatically receives this role.
When creating an API key for a user, you must include the organization ID in the metadata. Users created via this method belong to your organization (the admin's organization), so use your organization ID.
Get your organization ID:
If you followed the First Administrator Setup guide, you saved your organization ID in Step 2. If you need to retrieve it, call:
curl -X GET "https://your-platform.example.com/api/auth/organization/list" \
-H "X-Api-Key: YOUR_ADMIN_API_KEY"Response:
[
{
"name": "Financial Institution S.A.",
"slug": "financial-institution-sa",
"logo": null,
"createdAt": "2025-12-23T14:38:07.082Z",
"metadata": null,
"id": "org_abc123"
}
]Use the id field (org_abc123 in this example) when creating the API key below.
Impersonate the user:
curl -i -c cookies.txt -X POST "https://your-platform.example.com/api/auth/admin/impersonate-user" \
-H "X-Api-Key: YOUR_ADMIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": "usr_abc123"
}'Use the id from the user creation response. The session cookie is saved to cookies.txt.
Create API key while impersonated:
curl -b cookies.txt -X POST "https://your-platform.example.com/api/auth/api-key/create" \
-H "Content-Type: application/json" \
-H "Origin: https://your-platform.example.com" \
-d '{
"name": "User Operations Key",
"expiresIn": 31536000,
"metadata": {
"organizationId": "org_abc123"
}
}'Response:
{
"name": "User Operations Key",
"start": "sm_atk",
"prefix": "sm_dalp_",
"key": "sm_dalp_xxxxxxxxxxxxxxxx",
"userId": "usr_abc123",
"enabled": true,
"rateLimitEnabled": true,
"rateLimitTimeWindow": 60000,
"rateLimitMax": 10000,
"requestCount": 0,
"expiresAt": "2026-01-15T10:00:00.000Z",
"createdAt": "2025-01-15T10:00:00.000Z",
"updatedAt": "2025-01-15T10:00:00.000Z",
"permissions": {
"organization": [],
"member": [],
"invitation": [],
"team": [],
"ac": ["read"],
"setting": ["read", "list"],
"system": ["read", "list"],
"exchangeRates": ["read", "list"]
},
"metadata": {
"organizationId": "org_abc123"
},
"id": "key_abc123"
}Store the API key securely
The full API key is shown only once. Store it securely—you'll need it for the next step if setting up wallet verification.
Organization context required
API keys need organization context to access system endpoints. The organizationId in the metadata ensures the API
key can authenticate properly when calling endpoints like identity read, user management, and asset operations.
Without this metadata, the API key will fail with 401 errors when calling system endpoints.
Stop impersonation:
curl -b cookies.txt -X POST "https://your-platform.example.com/api/auth/admin/stop-impersonating" \
-H "Origin: https://your-platform.example.com"Set up wallet verification (required for API access)
If this user needs to use their API key for blockchain transactions or system operations, set up wallet verification (PIN + secret codes). This requires an API key from the previous step.
Without wallet verification, the user's API key will fail with a NOT_ONBOARDED error when calling most system endpoints.
Enable PIN:
Using the user's API key, configure their PIN:
curl -X POST "https://your-platform.example.com/api/auth/wallet/pincode/enable" \
-H "Content-Type: application/json" \
-H "X-Api-Key: sm_dalp_user_xxxxxxxx" \
-d '{
"pincode": "123456"
}'Response:
{
"success": true
}Generate secret recovery codes:
Using the user's API key, generate backup recovery codes:
curl -X POST "https://your-platform.example.com/api/auth/wallet/secret-codes/generate" \
-H "Content-Type: application/json" \
-H "X-Api-Key: sm_dalp_user_xxxxxxxx" \
-d '{}'Response:
{
"secretCodes": ["ABCD-1234-EFGH", "IJKL-5678-MNOP", "QRST-9012-UVWX", "YZAB-3456-CDEF", "GHIJ-7890-KLMN"]
}Confirm secret codes were stored:
After securely storing the codes, confirm to the API that they've been saved:
curl -X POST "https://your-platform.example.com/api/auth/wallet/secret-codes/confirm" \
-H "Content-Type: application/json" \
-H "X-Api-Key: sm_dalp_user_xxxxxxxx" \
-d '{
"stored": true
}'Response:
{
"success": true
}Store credentials securely
Store the user's API key, PIN, and secret recovery codes in a secrets manager (HashiCorp Vault, AWS Secrets Manager, etc.). If handing off to users, use secure channels like encrypted messaging or password manager invites.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name (person or company) |
email | string | Yes | Email address for the account (must be unique) |
walletVerification | object | Yes | Verification code for your account (the caller) to authorize the blockchain transaction |
Wallet verification object
| Field | Type | Description |
|---|---|---|
secretVerificationCode | string | 6-digit pincode or TOTP code |
verificationType | string | "PINCODE" (default), "SECRET_CODES", or "OTP" |
Response fields
| Field | Type | Description |
|---|---|---|
id | string | User ID |
name | string | Display name |
email | string | Email address |
wallet | string | Created wallet address (0x...) |
identity | string | Created identity contract address (0x...) |
Post-creation steps
- Provide platform access - Share the platform URL with users so they can access via "Forgot password"
- Enroll in registries - Add users to relevant asset registries via Register User
- Assign administrative roles - Grant platform admin roles if needed via Add Administrators
- Verify identity - Complete KYC verification for compliance if required
Unknown passwords
User passwords are randomly generated and unknown to administrators. Users must use the "Forgot password" flow to set their own secure password.
What gets created automatically
Account setup
- User account with email as username
- Secure random password (must be reset)
Blockchain components
- Wallet address - New externally owned account (EOA)
- Private key storage - Securely encrypted
- On-chain identity - Smart contract deployed
- Identity registration - Registered as pending in identity registry
Limitations and considerations
- Password reset required - Extra step for user access
- No email notifications - No clean invitation emails for users
Comparison of user creation methods
| Aspect | Create User | Invite User |
|---|---|---|
| Speed | Immediate | Depends on user response |
| API access | Optional (via admin) | User creates own |
| Security | Admin-managed | User-controlled |
| Best for | Demos, test accounts | Production, external users |
| Admin role required | For API key: Yes | No |
| Organization | Your org only | Can create own orgs |
| Setup | Automatic | User-guided |
Troubleshooting
| Issue | Solution |
|---|---|
401 Unauthorized | API key is invalid, expired, or disabled |
403 USER_NOT_AUTHORIZED | Ensure your account has identityManager role (Identity Manager) |
400 Email already exists | User already exists; use user.search to find them |
400 Invalid wallet verification | Check your pincode/2FA code is correct |
500 Insufficient gas | Check blockchain node has sufficient funds for deployment |
403 YOU_ARE_NOT_ALLOWED_TO_IMPERSONATE_USERS | Requires platform admin role for API key creation |
| Impersonation session expired | Re-impersonate the user before creating the API key |
Related guides
- Register User - Register identity in jurisdiction
- First Administrator Setup - Initial platform setup with admin role
- Add Administrators - Grant admin roles to additional users
- Getting Started - API key setup basics