Skip to content

Get Funding Payments (WebSocket)

Retrieve detailed funding payment history and statistics for the authenticated subaccount through the WebSocket connection. This endpoint provides user-specific funding data including payments received, paid, and net funding across all positions.

Endpoint

ws.send() wss://api.synthetix.io/v1/ws/trade

Request

Request Format

{
  "id": "funding-payments-1",
  "method": "post",
  "params": {
    "action": "getFundingPayments",
    "subAccountId": "1867542890123456789",
    "symbol": "BTC-USDT",
    "startTime": 1735603200000,
    "endTime": 1735689600000,
    "limit": 100,
    "expiresAfter": 1735689900,
    "signature": {
      "v": 28,
      "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
      "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
    }
  }
}

Parameters

Request Parameters

ParameterTypeRequiredDescription
idstringYesClient-generated unique request identifier
methodstringYesMust be "post"
paramsobjectYesContains all parameters for the request

Params Object

ParameterTypeRequiredDescription
actionstringYesMust be "getFundingPayments"
subAccountIdstringYesSubaccount identifier
symbolstringNoFilter by specific trading pair (e.g., "BTC-USDT")
startTimeintegerNoStart timestamp for filtering (milliseconds)
endTimeintegerNoEnd timestamp for filtering (milliseconds)
limitintegerNoMaximum number of records (default: 100)
expiresAfterintegerNoOptional expiration timestamp in seconds
signatureobjectYesEIP-712 signature using SubAccountAction type
Important Notes:
  • This endpoint uses SubAccountAction EIP-712 type (no nonce required)
  • For deposit/withdrawal history, use Get Balance Updates

EIP-712 Signature

const domain = {
  name: "Synthetix",
  version: "1",
  chainId: 1,
  verifyingContract: "0x0000000000000000000000000000000000000000"
};
 
const types = {
  SubAccountAction: [
    { name: "subAccountId", type: "uint256" },
    { name: "action", type: "string" },
    { name: "expiresAfter", type: "uint256" }
  ]
};
 
const message = {
  subAccountId: "1867542890123456789",
  action: "getFundingPayments",
  expiresAfter: 0
};
 
const signature = await signer._signTypedData(domain, types, message);

Response Format

Success Response

{
  "id": "funding-payments-1",
  "status": 200,
  "result": {
    "summary": {
      "totalFundingReceived": "125.75000000",
      "totalFundingPaid": "89.25000000",
      "netFunding": "36.50000000",
      "totalPayments": "247",
      "averagePaymentSize": "0.87044534"
    },
    "fundingHistory": [
      {
        "paymentId": "fp_1958787130134106112",
        "symbol": "BTC-USDT",
        "positionSize": "2.50000000",
        "fundingRate": "0.00001250",
        "payment": "-1.12500000",
        "timestamp": 1735689600000,
        "paymentTime": 1735689600000,
        "fundingTimestamp": 1735689600000,
        "fundingTime": 1735689600000
      },
      {
        "paymentId": "fp_1958787130134106111",
        "symbol": "ETH-USDT",
        "positionSize": "-5.00000000",
        "fundingRate": "-0.00002100",
        "payment": "3.15000000",
        "timestamp": 1735661200000,
        "paymentTime": 1735661200000,
        "fundingTimestamp": 1735661200000,
        "fundingTime": 1735661200000
      }
    ]
  }
}

Empty Result

{
  "id": "funding-payments-1",
  "status": 200,
  "result": {
    "summary": {
      "totalFundingReceived": "0",
      "totalFundingPaid": "0",
      "netFunding": "0",
      "totalPayments": "0",
      "averagePaymentSize": "0"
    },
    "fundingHistory": []
  }
}

Error Response

{
  "id": "funding-payments-1",
  "status": 400,
  "result": null,
  "error": {
    "code": 400,
    "message": "Invalid time range parameters"
  }
}

Response Fields

Summary Object

FieldTypeDescription
totalFundingReceivedstringTotal funding payments received
totalFundingPaidstringTotal funding payments paid
netFundingstringNet funding (received - paid)
totalPaymentsstringTotal number of funding payments
averagePaymentSizestringAverage payment size (absolute value)

Funding History Object

FieldTypeDescription
paymentIdstringUnique identifier for the funding payment
symbolstringTrading pair symbol
positionSizestringPosition size at funding time (signed)
fundingRatestringFunding rate applied (1-hour rate)
paymentstringFunding payment amount (negative = paid out)
timestampintegerDEPRECATED - Use paymentTime instead
paymentTimeintegerWhen payment was processed
fundingTimestampintegerDEPRECATED - Use fundingTime instead
fundingTimeintegerFunding period timestamp

Payment Calculation

Formula: Payment = Position Size × Funding Rate × Mark Price

  • Positive payment: Funding received
  • Negative payment: Funding paid
  • Long positions: Pay when funding rate is positive
  • Short positions: Receive when funding rate is positive

Code Examples

Get All Funding Payments

{
  "id": "all-funding",
  "method": "post",
  "params": {
    "action": "getFundingPayments",
    "subAccountId": "1867542890123456789",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Filter by Symbol

{
  "id": "btc-funding",
  "method": "post",
  "params": {
    "action": "getFundingPayments",
    "subAccountId": "1867542890123456789",
    "symbol": "BTC-USDT",
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Filter by Time Range

{
  "id": "time-range-funding",
  "method": "post",
  "params": {
    "action": "getFundingPayments",
    "subAccountId": "1867542890123456789",
    "startTime": 1735603200000,
    "endTime": 1735689600000,
    "expiresAfter": 0,
    "signature": { "v": 28, "r": "0x...", "s": "0x..." }
  }
}

Implementation Example

class FundingPaymentsQuery {
  constructor(ws, signer) {
    this.ws = ws;
    this.signer = signer;
    this.pendingRequests = new Map();
  }
 
  async getFundingPayments(options = {}) {
    const {
      subAccountId,
      symbol = null,
      startTime = null,
      endTime = null,
      limit = 100,
      expiresAfter = 0
    } = options;
 
    const signature = await this.signSubAccountAction(subAccountId, "getFundingPayments", expiresAfter);
 
    const request = {
      id: `funding-payments-${Date.now()}`,
      method: "post",
      params: {
        action: "getFundingPayments",
        subAccountId,
        limit,
        expiresAfter,
        signature
      }
    };
 
    if (symbol) request.params.symbol = symbol;
    if (startTime) request.params.startTime = startTime;
    if (endTime) request.params.endTime = endTime;
 
    return this.sendRequest(request);
  }
 
  async signSubAccountAction(subAccountId, action, expiresAfter = 0) {
    const domain = {
      name: "Synthetix",
      version: "1",
      chainId: 1,
      verifyingContract: "0x0000000000000000000000000000000000000000"
    };
 
    const types = {
      SubAccountAction: [
        { name: "subAccountId", type: "uint256" },
        { name: "action", type: "string" },
        { name: "expiresAfter", type: "uint256" }
      ]
    };
 
    const message = {
      subAccountId: BigInt(subAccountId),
      action,
      expiresAfter: BigInt(expiresAfter)
    };
 
    const sig = await this.signer.signTypedData(domain, types, message);
    const { v, r, s } = ethers.Signature.from(sig);
    return { v, r, s };
  }
 
  sendRequest(request) {
    return new Promise((resolve, reject) => {
      this.pendingRequests.set(request.id, { resolve, reject });
      this.ws.send(JSON.stringify(request));
 
      setTimeout(() => {
        if (this.pendingRequests.has(request.id)) {
          this.pendingRequests.delete(request.id);
          reject(new Error('Request timeout'));
        }
      }, 10000);
    });
  }
}
 
// Usage: Analyze funding performance
const query = new FundingPaymentsQuery(ws, signer);
const result = await query.getFundingPayments({
  subAccountId: "1867542890123456789",
  startTime: Date.now() - (30 * 24 * 60 * 60 * 1000) // Last 30 days
});
 
const netFunding = parseFloat(result.summary.netFunding);
console.log(`Net funding last 30 days: ${netFunding} USDT`);

Use Cases

Funding Performance Analysis

// Analyze funding performance over time
const fundingData = await query.getFundingPayments({
  subAccountId: "1867542890123456789",
  startTime: Date.now() - (30 * 24 * 60 * 60 * 1000) // Last 30 days
});
 
const netFunding = parseFloat(fundingData.summary.netFunding);
console.log(`Net funding last 30 days: ${netFunding} USDT`);

Position-Specific Funding

// Get funding for specific market
const btcFunding = await query.getFundingPayments({
  subAccountId: "1867542890123456789",
  symbol: "BTC-USDT"
});

Common Errors

Error CodeMessageDescription
400Invalid subaccountSubaccount not found or unauthorized
400Invalid symbolInvalid trading symbol filter
400Invalid time rangestartTime must be less than endTime
Error CodeDescriptionRetryable
UNAUTHORIZEDEIP-712 signature validation failedNo
VALIDATION_ERRORRequest validation failedNo
MISSING_REQUIRED_FIELDRequired field is missingNo
INVALID_FORMATField format is invalidNo
INVALID_VALUEInvalid parameter valueNo
RATE_LIMIT_EXCEEDEDToo many requests in time windowYes
INSUFFICIENT_MARGINNot enough margin for tradeNo
ORDER_NOT_FOUNDOrder does not existNo
OPERATION_TIMEOUTOperation timed outYes

Next Steps