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). Cannot be more than 30 days in the past. When omitted, defaults to now − 30 days.
endTimeintegerNoEnd timestamp for filtering (milliseconds). If endTime is older than 30 days and startTime is not provided, the request is rejected.
limitintegerNoMaximum number of records to return. Default: 100. Maximum: 1000.
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

StatusError CodeMessageSolution
400VALIDATION_ERRORsubAccountId is requiredProvide a valid authenticated subaccount
400VALIDATION_ERRORinvalid symbolUse a valid symbol (e.g., BTC-USDT) from getMarkets
400VALIDATION_ERRORstartTime must be less than endTimeEnsure startTime is strictly less than endTime
400VALIDATION_ERRORstartTime must be a valid timestampUse a timestamp within the last year and not in the future
400VALIDATION_ERRORlimit must not exceed 1000Reduce the limit to 1000 or below
400INVALID_FORMATInvalid request bodyCheck request structure and field types
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