Skip to content

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/trade

Request

Request Format

{
  "params": {
    "action": "removeDelegatedSigner",
    "subAccountId": "1867542890123456789",
    "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590"
  },
  "nonce": 1735689600000,
  "signature": {
    "v": 28,
    "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  }
}

Request Parameters

ParameterTypeRequiredDescription
paramsobjectYesAction object containing removal details
params.actionstringYesMust be "removeDelegatedSigner"
params.subAccountIdstringYesThe subaccount ID to remove the delegated signer from
params.walletAddressstringYesEthereum wallet address of the delegated signer to remove (42-character hex format)
ParameterTypeRequiredDescription
nonceuint64YesUnix milliseconds timestamp (must be monotonically increasing)
signatureobjectYesEIP-712 signature object
expiresAfteruint64NoUnix 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 expiresAt is not provided or should represent "no expiration", use 0 in the EIP-712 message (not null)
  • The nonce field 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

FieldTypeDescription
subAccountIdstringThe subaccount ID the signer was removed from
walletAddressstringThe 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 addDelegatedSigner endpoint

Effect on Active Operations

Operation TypeEffect of Removal
Open OrdersRemain active (can be cancelled by master account)
Pending WithdrawalsContinue processing
Active SessionsShould be terminated
API KeysShould be invalidated
SubscriptionsShould 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

ErrorDescription
Invalid signatureEIP-712 signature validation failed
Invalid market symbolMarket symbol not recognized
Nonce already usedNonce must be greater than previous value
Rate limit exceededToo many requests in time window
Request expiredexpiresAfter timestamp has passed