Skip to content

Get Delegated Signers

Retrieve a list of all delegated signers for a specific subaccount. This endpoint provides visibility into which wallet addresses have been granted permissions to act on behalf of the subaccount, along with their permission levels and delegation details.

Endpoint

POST https://papi.synthetix.io/v1/trade

Request

Request Format

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

Request Parameters

ParameterTypeRequiredDescription
paramsobjectYesAction object containing request details
params.actionstringYesMust be "getDelegatedSigners"
params.subAccountIdstringYesThe subaccount ID to retrieve delegated signers for
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": {
    "delegatedSigners": [
      {
        "subAccountId": "1867542890123456789",
        "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
        "permissions": ["trading"],
        "expiresAt": null
      },
      {
        "subAccountId": "1867542890123456789",
        "walletAddress": "0x8B3a9A6F8D1e2C4E5B7A9D0F1C3E5A7B9D1F3E5A",
        "permissions": ["trading"],
        "expiresAt": 1767225600000
      }
    ]
  },
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Response Fields

FieldTypeDescription
delegatedSignersarrayArray of delegated signer objects

Delegate Object

The delegate object represents a delegated signer in API responses. This differs from the EIP-712 signed structure which includes additional fields like subAccountId and nonce.

FieldTypeDescription
walletAddressstringEthereum wallet address of the delegated signer (42-character hex format)
permissionsstring[]Array of permission levels granted. Currently supports: ["trading"]
expiresAtinteger | nullUnix timestamp (milliseconds) when the delegation expires. null indicates no expiration

Example Delegate Object

{
  "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
  "permissions": ["trading"],
  "expiresAt": null
}

Example with Expiration

{
  "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
  "permissions": ["trading"],
  "expiresAt": 1767225600000
}

Empty Response

{
  "status": "ok",
  "response": {
    "delegatedSigners": []
  },
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Error Response

{
  "status": "error",
  "error": {
    "message": "Subaccount not found",
    "code": "NOT_FOUND"
  },
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Code Examples

Get All Delegated Signers

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

Response with Multiple Signers

{
  "status": "ok",
  "response": {
    "delegatedSigners": [
      {
        "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f89590",
        "permissions": ["trading"],
        "expiresAt": null
      },
      {
        "walletAddress": "0x8B3a9A6F8D1e2C4E5B7A9D0F1C3E5A7B9D1F3E5A",
        "permissions": ["trading"],
        "expiresAt": null
      },
      {
        "walletAddress": "0x9C4b8E7F0A2D3B6C5E8A1F3D5B7C9E1A3F5D7B9E",
        "permissions": ["trading"],
        "expiresAt": 1798761600000
      }
    ]
  },
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Implementation Notes

  • Access Control: Both master account owners and delegated signers can view the delegation list
  • Real-time Data: Returns current active delegations only
  • Expiration Handling: Expired delegations are automatically excluded from results
  • No Pagination: All delegated signers are returned in a single response

Use Cases

  • Team Management: View all team members with access to a trading account
  • Security Audit: Regular review of who has access to perform operations
  • Access Control UI: Build interfaces showing current permissions
  • Bot Management: Track which automated systems have trading access
  • Compliance: Maintain records of account access for regulatory purposes

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