Create Subaccount (WebSocket)
Create a new trading subaccount under the authenticated wallet address through the WebSocket connection. Subaccounts allow for isolated trading strategies, separate margin management, and organized position tracking within a single master account.
Endpoint
ws.send() wss://api.synthetix.io/v1/ws/tradeRequest
Request Format
{
"id": "create-subaccount-1",
"method": "post",
"params": {
"action": "createSubaccount",
"name": "Trading Bot Strategy",
"nonce": 1735689600000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}
}Parameters
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Client-generated unique request identifier |
method | string | Yes | Must be "post" |
params | object | Yes | Contains all parameters for the request |
Params Object
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Must be "createSubaccount" |
name | string | No | Optional display name for the new subaccount (max 50 chars) |
nonce | integer | Yes | Unix milliseconds timestamp, monotonically increasing |
signature | object | Yes | EIP-712 signature for wallet authentication |
Important: This endpoint authenticates at the wallet level rather than requiring an existing subAccountId.
Naming Guidelines
- Optional Parameter: Name can be omitted for system-generated naming
- Character Limit: Maximum 50 characters when specified
- Default Behavior: If no name provided, system may generate a default identifier
Examples: "Main Trading", "DCA Strategy", "Arbitrage Bot", "Risk Management"
Response Format
Success Response (New Account)
When a subaccount is first created, only subAccountId and subAccountName are populated:
{
"id": "create-subaccount-1",
"status": 200,
"result": {
"subAccountId": "1867542890123456790",
"masterAccountId": null,
"subAccountName": "Trading Bot Strategy",
"collaterals": null,
"crossMarginSummary": {
"accountValue": "0",
"availableMargin": "0",
"totalUnrealizedPnl": "0",
"maintenanceMargin": "0",
"initialMargin": "0",
"withdrawable": "0",
"adjustedAccountValue": "0"
},
"positions": null,
"marketPreferences": {
"leverages": null
},
"feeRates": {
"makerFeeRate": "0",
"takerFeeRate": "0",
"tierName": ""
}
}
}Response Fields
| Field | Type | Description |
|---|---|---|
subAccountId | string | System-generated unique identifier for the new subaccount |
masterAccountId | string | null | Master account ID (returns null) |
subAccountName | string | Display name provided in request (or empty if not specified) |
collaterals | array | null | Collateral balances (returns null for new accounts) |
crossMarginSummary | object | Cross-margin account summary (returns zeros for new accounts) |
positions | array | null | Open positions (returns null for new accounts) |
marketPreferences | object | Market-specific preferences like leverage |
feeRates | object | Fee rate information |
Error Response
{
"id": "create-subaccount-1",
"status": 400,
"result": null,
"error": {
"code": 400,
"message": "Subaccount limit reached"
}
}Implementation Example
import { ethers } from 'ethers';
async function createSubaccount(ws, signer, name = "") {
const nonce = Date.now();
const domain = {
name: "Synthetix",
version: "1",
chainId: 1,
verifyingContract: "0x0000000000000000000000000000000000000000"
};
const types = {
CreateSubaccount: [
{ name: "name", type: "string" },
{ name: "nonce", type: "uint256" }
]
};
const message = {
name,
nonce: BigInt(nonce)
};
const sig = await signer.signTypedData(domain, types, message);
const signature = ethers.Signature.from(sig);
ws.send(JSON.stringify({
id: `create-subaccount-${Date.now()}`,
method: "post",
params: {
action: "createSubaccount",
name,
nonce,
signature: { v: signature.v, r: signature.r, s: signature.s }
}
}));
}
// Usage: Create a new trading subaccount
await createSubaccount(ws, signer, "Grid Trading Bot");Code Examples
Create Basic Subaccount
{
"id": "create-basic",
"method": "post",
"params": {
"action": "createSubaccount",
"name": "Main Trading",
"nonce": 1735689600000,
"signature": { "v": 28, "r": "0x...", "s": "0x..." }
}
}Create Strategy-Specific Subaccount
{
"id": "create-strategy",
"method": "post",
"params": {
"action": "createSubaccount",
"name": "Grid Trading Bot",
"nonce": 1735689600001,
"signature": { "v": 28, "r": "0x...", "s": "0x..." }
}
}Create Subaccount Without Name
{
"id": "create-unnamed",
"method": "post",
"params": {
"action": "createSubaccount",
"nonce": 1735689600002,
"signature": { "v": 28, "r": "0x...", "s": "0x..." }
}
}Implementation Notes
- Wallet-Level Auth: Authenticates at wallet level (no existing subAccountId needed)
- Immediate Availability: Subaccount is immediately available for trading after creation
- Account Limits: Platform may enforce maximum number of subaccounts per wallet
- Initial State: New subaccounts have zero balances and no positions
- Security Inheritance: Each subaccount inherits master wallet security settings
Common Errors
| Error Code | Message | Description |
|---|---|---|
| 400 | Subaccount limit reached | Maximum subaccounts for this wallet exceeded |
| 400 | Invalid subaccount name | Name exceeds 50 characters or contains invalid characters |
| 401 | Authentication failed | Invalid signature |
| Error | Description |
|---|---|
| Invalid signature | EIP-712 signature validation failed |
| Invalid market symbol | Market symbol not recognized |
| Nonce already used | Nonce must be greater than previous value |
| Rate limit exceeded | Too many requests in time window |
| Request expired | expiresAfter timestamp has passed |
Next Steps
- Get Subaccount - Retrieve account details
- Add Delegated Signer - Delegate trading access
- Place Orders - Start trading
- REST Alternative - REST API comparison