Remove Delegated Signer
Remove a delegated signer from a subaccount, revoking their ability to perform trading actions on behalf of the subaccount. This immediately terminates the trading permission previously granted to the specified wallet address.
Endpoint
POST https://papi.synthetix.io/v1/tradeRequest
Request Format
{
"params": {
"action": "removeDelegatedSigner",
"subAccountId": "1867542890123456789",
"walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590"
},
"nonce": 1735689600000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
params | object | Yes | Action object containing removal details |
params.action | string | Yes | Must be "removeDelegatedSigner" |
params.subAccountId | string | Yes | The subaccount ID to remove the delegated signer from |
params.walletAddress | string | Yes | Ethereum wallet address of the delegated signer to remove (42-character hex format) |
| Parameter | Type | Required | Description |
|---|---|---|---|
nonce | uint64 | Yes | Unix milliseconds timestamp (must be monotonically increasing) |
signature | object | Yes | EIP-712 signature object |
expiresAfter | uint64 | No | Unix milliseconds expiration timestamp (5x rate limit on stale cancels) |
EIP-712 Signature Structure
The request is signed using EIP-712 with the following type definition:
EIP-712 Type Definitions for Delegation
AddDelegatedSigner
const AddDelegatedSignerTypes = {
AddDelegatedSigner: [
{ name: "subAccountId", type: "uint256" },
{ name: "walletAddress", type: "address" },
{ name: "permissions", type: "string[]" },
{ name: "expiresAt", type: "uint256" },
{ name: "nonce", type: "uint256" }
]
}GetDelegatedSigners
const GetDelegatedSignersTypes = {
GetDelegatedSigners: [
{ name: "subAccountId", type: "uint256" },
{ name: "nonce", type: "uint256" }
]
}RemoveDelegatedSigner
const RemoveDelegatedSignerTypes = {
RemoveDelegatedSigner: [
{ name: "subAccountId", type: "uint256" },
{ name: "walletAddress", type: "address" },
{ name: "nonce", type: "uint256" }
]
}Example Typed Data for AddDelegatedSigner
{
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"AddDelegatedSigner": [
{ "name": "subAccountId", "type": "uint256" },
{ "name": "walletAddress", "type": "address" },
{ "name": "permissions", "type": "string[]" },
{ "name": "expiresAt", "type": "uint256" },
{ "name": "nonce", "type": "uint256" }
]
},
"primaryType": "AddDelegatedSigner",
"domain": {
"name": "Synthetix",
"version": "1",
"chainId": 1,
"verifyingContract": "0x0000000000000000000000000000000000000000"
},
"message": {
"subAccountId": "1867542890123456789",
"walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
"permissions": ["trading"],
"expiresAt": 0,
"nonce": 1735689600000
}
}Important Notes:
- When
expiresAtis not provided or should represent "no expiration", use0in the EIP-712 message (notnull) - The
noncefield is included in the EIP-712 message but comes from the top-level request field, not the action object - All delegation operations must be signed by the master account owner
Response
Success Response
{
"status": "ok",
"response": {
"subAccountId": "1867542890123456789",
"walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590"
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
subAccountId | string | The subaccount ID the signer was removed from |
walletAddress | string | The removed delegated signer's wallet address |
Error Response
{
"status": "error",
"error": {
"message": "Delegated signer not found",
"code": "NOT_FOUND"
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Common Error Cases
{
"status": "error",
"error": {
"message": "Only master account can remove delegated signers",
"code": "UNAUTHORIZED"
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}{
"status": "error",
"error": {
"message": "Subaccount not found",
"code": "NOT_FOUND"
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Code Examples
Remove Trading Bot Access
{
"params": {
"action": "removeDelegatedSigner",
"subAccountId": "1867542890123456789",
"walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590"
},
"nonce": 1735689600000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Revoke Team Member Access
{
"params": {
"action": "removeDelegatedSigner",
"subAccountId": "1867542890123456789",
"walletAddress": "0x9C4b8E7F0A2D3B6C5E8A1F3D5B7C9E1A3F5D7B9E"
},
"nonce": 1735689600001,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Implementation Notes
- Immediate Effect: Removal takes effect immediately upon successful execution
- Access Requirements: Only master account owners can remove delegated signers
- No Self-Removal: Delegated signers cannot remove themselves (must be done by master account)
- Idempotent: Attempting to remove a non-existent delegation returns an error
- Active Sessions: Any active sessions or connections for the removed signer should be terminated
- Pending Operations: Any pending operations initiated by the removed signer remain valid
- Audit Trail: All removal actions are logged for security and compliance
Security Considerations
- Master Account Only: System validates that only the master account can remove delegated signers
- Address Validation: Wallet addresses must be valid Ethereum addresses
- Signature Required: All removal operations require valid EIP-712 signatures
- No Cascade: Removing a delegated signer does not affect any other delegations
- Recovery: Removed signers can be re-added if needed through the
addDelegatedSignerendpoint
Effect on Active Operations
| Operation Type | Effect of Removal |
|---|---|
| Open Orders | Remain active (can be cancelled by master account) |
| Pending Withdrawals | Continue processing |
| Active Sessions | Should be terminated |
| API Keys | Should be invalidated |
| Subscriptions | Should be cancelled |
Use Cases
- Security Response: Immediately revoke access when a delegated signer is compromised
- Team Changes: Remove access when team members leave or change roles
- Bot Decommission: Remove trading bot access when no longer needed
- Access Rotation: Regular removal and re-addition of signers for security
- Emergency Lockdown: Quick removal of all delegated signers in security events
Signing
All trading methods are signed using EIP-712. Each successful trading request will contain:
- A piece of structured data that includes the sender address
- A signature of the hash of that structured data, signed by the sender
For detailed information on EIP-712 signing, see EIP-712 Signing.
Nonce Management
The nonce system prevents replay attacks and ensures order uniqueness:
- Use current timestamp in milliseconds as nonce
- Each nonce must be greater than the previous one
- Recommended: Use
Date.now()or equivalent - If nonce conflicts occur, increment by 1 and retry
Error Handling
| 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 |