docs.dydx.exchange Open in urlscan Pro
2606:4700:4400::6812:24fb  Public Scan

URL: https://docs.dydx.exchange/
Submission: On October 21 via api from GR — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

NAV

Python TypeScript HTTP

 * Terms of Service and Privacy Policy
 * General
   * Layer 2: ZK-Rollups
   * Data Centers
   * Number Formats
   * Base URLs
   * Testnet
   * Rate-Limits
     * Rate Limit - API
     * Rate Limit - Websocket
     * Cancel-Order Rate Limits
     * Place-Order Rate-Limits
     * Active-Order Rate-Limits
   * Other Limits
 * Perpetual Contracts
   * Margin
     * Risk Parameters and Related Fields
     * Portfolio Margining
     * Margin Calculation
   * Liquidations
     * Close Price for Liquidations
   * Funding
     * Funding Rate Units
     * Funding Payment Calculation
     * Funding Rate Calculation
   * Contract Loss Mechanisms
   * Oracle Prices
     * Calculation
     * Node Providers
   * Index Prices
     * Calculation
     * Exchange Sources
 * Clients
   * Python Client
     * Installation
     * Usage
   * TypeScript Client
     * Installation
     * Usage
   * Client Initialization
     * C++ Methods for Faster STARK Signing
 * Private HTTP API
   * Authentication
     * Ethereum Key Authentication
     * STARK Key Authentication
     * API Key Authentication
     * STARK Key Cryptography
   * Creating and Signing Requests
     * Onboarding Endpoint: POST v3/onboarding
     * Ethereum Key Private Endpoints
     * API Key Private Endpoints
   * Onboarding
     * Overview
     * HTTP Request
     * Request
     * Response
   * Derive StarkKey
     * Request
     * Response
     * KeyPairWithYCoordinate
   * Recover Default API Credentials
     * Request
     * Response
     * ApiKeyCredentials
   * Recover StarkKey, QuoteBalance and Open Positions
     * HTTP Request
     * Response
   * Get Registration
     * HTTP Request
     * Response
   * Register API Key
     * HTTP Request
     * Response
   * Get API Keys
     * HTTP Request
     * Response
   * Delete API Key
     * HTTP Request
     * Request
     * Response
   * Get User
     * HTTP Request
     * Response
   * Update User
     * HTTP Request
     * Response
   * Get User Active Links
     * HTTP Request
     * Response
   * Send User Link Request
     * HTTP Request
     * Request
     * Response
     * Link Actions
   * Get User Pending Link Requests
     * HTTP Request
     * Response
   * Create An Account
     * HTTP Request
     * Request
     * Response
   * Get Account
     * HTTP Request
     * Request
     * Response
   * Get Account Leaderboard PNLs
     * HTTP Request
     * Request
     * Response
   * Get Account Historical Leaderboard PNLs
     * HTTP Request
     * Request
     * Response
     * LeaderboardPnl
   * Get Accounts
     * HTTP Request
     * Response
   * Get Positions
     * HTTP Request
     * Request
     * Response
   * Get Transfers
     * HTTP Request
     * Request
     * Response
   * Create Transfer
     * HTTP Request
     * Request
     * Response
   * Fast vs. Slow Withdrawal
   * Create Withdrawal
     * HTTP Request
     * Request
     * Response
   * Create Fast Withdrawal
     * HTTP Request
     * Request
     * Response
   * Order Types
   * Create A New Order
     * HTTP Request
     * Request
     * Response
   * Order LimitFee
   * Tick Size and Minimum Size
     * Tick Size
     * Minimum Size
   * Order Deletion
   * Reduce Only
   * Cancel An Order
     * HTTP Request
     * Request
     * Response
   * Cancel Orders
     * HTTP Request
     * Request
     * Response
   * Cancel Active Orders
     * HTTP Request
     * Request
     * Response
   * Get Orders
     * HTTP Request
     * Request
     * Response
     * Order
     * Order Statuses
     * Cancel Reasons
   * Get Active Orders
     * HTTP Request
     * Request
     * Response
     * ActiveOrder
   * Get Order By Id
     * HTTP Request
     * Request
     * Response
   * Get Order by ClientId
     * HTTP Request
     * Request
     * Response
   * Get Fills
     * HTTP Request
     * Request
     * Response
     * Fill
   * Get Funding Payments
     * HTTP Request
     * Request
     * Response
   * Get Historical PNL Ticks
     * HTTP Request
     * Request
     * Response
     * HistoricalAggregatedPnl
   * Get Trading Rewards
     * HTTP Request
     * Request
     * Response
     * Weight
     * Fees
     * OpenInterest
     * StakedDYDX
   * Get Liquidity Provider Rewards
     * HTTP Request
     * Request
     * Response
     * LiquidityRewards
     * StakedDYDX
     * PerAddressRewards
   * Get Liquidity Rewards (Deprecated)
     * HTTP Request
     * Request
     * Response
     * LiquidityRewards
     * StakedDYDX
   * Get Retroactive Mining Rewards
     * HTTP Request
     * Response
     * RetroactiveMiningRewards
   * Send Verification Email
     * HTTP Request
     * Response
     * Setting Notification Status
   * Request Testnet Tokens
     * HTTP Request
     * Response
   * Get Private Profile
     * HTTP Request
     * Response
     * AffiliateLinkData
     * TradingLeagues
     * TradingPnls
     * TradingRewards
     * AffiliateStatistics
     * CurrentEpochAffiliateStatistics
     * PreviousEpochsAffiliateStatistics
 * Public HTTP API
   * Get Markets
     * HTTP Request
     * Request
     * Response
     * Market
   * Get Orderbook
     * HTTP Request
     * Request
     * Response
     * Orderbook Order
   * Get Trades
     * HTTP Request
     * Request
     * Response
     * Trade
   * Get Fast Withdrawal Liquidity
     * HTTP Request
     * Request
     * Response
     * Liquidity Provider
     * Liquidity Provider Quote
   * Get Market Stats
     * HTTP Request
     * Request
     * Response
     * MarketStats
   * Get Historical Funding
     * HTTP Request
     * Request
     * Response
     * Historical Funding
   * Get Candles for Market
     * HTTP Request
     * Request
     * Response
   * Get Global Configuration Variables
     * HTTP Request
     * Response
     * cancelOrderRateLimiting
     * placeOrderRateLimiting
   * Check If User Exists
     * HTTP Request
     * Request
     * Response
   * Check If Username Exists
     * HTTP Request
     * Request
     * Response
   * Get API Server Time
     * HTTP Request
     * Response
   * Get Public Leaderboard PNLs
     * HTTP Request
     * Request
     * Response
   * Get Public Retroactive Mining Rewards
     * HTTP Request
     * Request
     * Response
   * Verify an Email Address
     * HTTP Request
     * Request
     * Response
   * Get Currently Revealed Hedgies
     * HTTP Request
     * Response
     * NftPeriodInformation
   * Get Historically Revealed Hedgies
     * HTTP Request
     * Request
     * Response
   * Get Insurance Fund Balance
     * HTTP Request
     * Response
   * Get Public Profile
     * HTTP Request
     * Response
     * Request
     * Response
     * TradingLeagues
     * TradingPnls
     * TradingRewards
 * V3 Websocket API
   * Accounts channel
     * Initial Response:
     * Channel Data
   * Orderbook
     * Initial Response:
     * Channel Data
   * Trades
     * Initial Response:
     * Channel Data
   * Markets
     * Initial Response:
     * Channel Data
 * Security
   * Independent Audits
   * Vulnerability Disclosure Policy


TERMS OF SERVICE AND PRIVACY POLICY

By using any API provided by dYdX Trading Inc., you agree to its Terms of Use
and Privacy Policy. If you do not agree to the foregoing, then do not use any
such API.


GENERAL

These docs describe the v3 API for the dYdX decentralized perpetual contracts
exchange. The exchange runs on an L2 (layer-2) blockchain system, and operates
independently of previous dYdX protocols and systems, including the v1 and v2
APIs.

Like the previous iteration of dYdX perpetuals, the exchange uses a centralized
order book, but remains non-custodial, and settles trades and liquidations in a
trustless manner.

These docs describe the dYdX layer-2 perpetuals exchange.


LAYER 2: ZK-ROLLUPS

Trades are settled in an L2 (layer-2) system, which publishes ZK
(zero-knowledge) proofs periodically to an Ethereum smart contract in order to
prove that state transitions within L2 are valid. Funds must be deposited to the
Ethereum smart contract before they can be used to trade on dYdX.

By settling trades on L2, the exchange is able to offer much higher trade
throughput and lower minimum order sizes, compared with systems settling trades
directly on Ethereum (i.e. L1). This is achieved while maintaining
decentralization, and the exchange is fully non-custodial.

The L2 system was developed with, and is operated jointly with, Starkware. More
information about the L2 design can be found in Starkware's documentation.
(Note: Some of the details described there may be specific to Starkware's
previous StarkEx system and may not apply to the dYdX system.)


DATA CENTERS

Our data centers are located in the AWS AP-NORTHEAST-1 region (Tokyo).

It is strictly against our Terms of Use to use United States based IPs to trade
on dYdX.


NUMBER FORMATS

All amounts and prices in the clients and API are represented in “human
readable,” natural units. For example, an amount of 1.25 ETH is represented as
1.25, and a price of $31,000.50 per BTC is represented as 31000.5.


BASE URLS

Base URLs for API endpoints are as follows:

 * Production (Mainnet): https://api.dydx.exchange
 * Staging (Goerli): https://api.stage.dydx.exchange


TESTNET

We have one testnet which is on Goerli. To use the testnet, use the above
Staging URL for your endpoint. Also use a networkId of 5 (Goerli) instead of 1
(Mainnet).

The user interface for testnet can be found here.

The dYdX Goerli USDC token address is
0xF7a2fa2c2025fFe64427dd40Dc190d47ecC8B36e. Users can deposit via the Testnet
website.


RATE-LIMITS

All rate-limits are subject to change.

Please make use of the WebSockets API if you need real-time data.


RATE LIMIT - API

Limits are enforced by IP Address for public endpoints, and by both IP Address
and Account for private endpoints.

Each request consumes 1 point towards the rate limit. POST v3/orders consumes
variable points based on the order. Points refresh at the end of each time
window. Please take note of the RateLimit-Remaining header to track points
usage.

RESPONSE HEADERS

Field Description RateLimit-Remaining Points remaining in the time window.
RateLimit-Reset Timestamp that the time window ends, in Epoch milliseconds.
Retry-After Milliseconds until the next time window. Header included only when
the limit has been reached. RateLimit-Limit The maximum amount of points allowed
per time window.

Request Limit GET v3/* 175 requests per 10 seconds. PUT
v3/emails/send-verification-email 2 requests for 10 minutes. DELETE v3/orders
See Cancel-Order Rate Limits POST v3/orders See Place-Order Rate-Limits POST
v3/testnet/tokens 5 requests per 24 hours. GET v3/active-orders See Active-Order
Rate-Limits DELETE v3/active-orders See Active-Order Rate-Limits All other
requests 10 requests per minute.


RATE LIMIT - WEBSOCKET

Limits are enforced per connectionId.

If your connection exceeds the request limit, we will terminate the connection,
and you will need to reconnect to the websocket. Additionally, sending too many
invalid messages will also result in your websocket being disconnected.

Request Limit subscribe v3_accounts, v3_markets 2 requests per 1 second.
subscribe v3_orderbook, v3_trades 2 requests for 1 second per market. ping 5
requests per 1 second.


CANCEL-ORDER RATE LIMITS

Canceling orders is limited per asset-pair and is intended to be higher than the
limit on placing orders.

DELETE v3/orders requests are limited to 3 requests per 10 seconds per
asset-pair.

DELETE v3/orders/:id requests are limited to 250 requests per 10 seconds per
asset-pair.


PLACE-ORDER RATE-LIMITS

Order rate limits are limited to maxPoints spent (per asset-pair) in a fixed
window of windowSec seconds.

We want to give priority to those who are making the largest orders and who are
contributing the most liquidity to the exchange. Therefore, placing larger
orders is subject to higher limits (i.e. larger orders carry a lower point
cost). The point cost is based on the orderNotional which is equal to the size *
price of the order.

Limit-order point consumption is equal to:

orderConsumption = clamp(
  ceil(targetNotional / orderNotional),
  minOrderConsumption,
  maxOrderConsumption
)


The minOrderConsumption is different for each order type, and can be one of
minLimitConsumption, minMarketConsumption, or minTriggerableConsumption. Limit
orders that are Fill-or-Kill or Immediate-or-Cancel are considered to be market
orders for the purposes of rate limiting.

The values of the above variables as of March 15th, 2022 are listed below, but
the most up-to-date values can be found in the v3/config endpoint.

Variable Value maxPoints 1,750 windowSec 10 targetNotional 40,000
minLimitConsumption 4 minMarketConsumption 20 minTriggerableConsumption 100
maxOrderConsumption 100


ACTIVE-ORDER RATE-LIMITS

Querying active orders is limited per endpoint and per asset and is intended to
be higher than the respective DELETE and GET endpoints these new endpoints
replace.

DELETE ACTIVE-ORDERS RATE LIMITS

DELETE v3/active-orders/*

 * 425 points allotted per 10 seconds per market.
 * 1 point consumed if order id included.
 * 25 points consumed if order side included.
 * 50 points consumed otherwise.

GET ACTIVE-ORDERS RATE LIMITS

GET v3/active-orders/*

 * 175 points allotted per 10 seconds per market.
 * 1 point consumed if order id included.
 * 3 points consumed if order side included.
 * 5 points consumed otherwise.


OTHER LIMITS

Accounts may only have up to 20 open orders for a given market/side pair at any
one time. (For example up to 20 open BTC-USD bids).


PERPETUAL CONTRACTS

The dYdX Perpetual is a non-custodial, decentralized margin product that offers
synthetic exposure to a variety of assets.


MARGIN

Collateral is held as USDC, and the quote asset for all perpetual markets is
USDC. Cross-margining is used by default, meaning an account can open multiple
positions that share the same collateral. Isolated margin can be achieved by
creating separate accounts (sub-accounts) under the same user.

Each market has three risk parameters, the initialMarginFraction,
maintenanceMarginFraction and incrementalInitialMarginFraction, which determine
the max leverage available within that market. These are used to calculate the
value that must be held by an account in order to open or increase positions (in
the case of initial margin) or avoid liquidation (in the case of maintenance
margin).


RISK PARAMETERS AND RELATED FIELDS

Risk Description initialMarginFraction The margin fraction needed to open a
position. maintenanceMarginFraction The margin fraction required to prevent
liquidation. incrementalInitialMarginFraction The increase of
initialMarginFraction for each incrementalPositionSize above the
baselinePositionSize the position is. baselinePositionSize The max position size
(in base token) before increasing the initial-margin-fraction.
incrementalPositionSize The step size (in base token) for increasing the
initialMarginFraction by (incrementalInitialMarginFraction per step).


PORTFOLIO MARGINING

There is no distinction between realized and unrealized PnL for the purposes of
margin calculations. Gains from one position will offset losses from another
position within the same account, regardless of whether the profitable position
is closed.


MARGIN CALCULATION

The margin requirement for a single position is calculated as follows:

Initial Margin Requirement = abs(S × P × I)
Maintenance Margin Requirement = abs(S × P × M)


Where:

 * S is the size of the position (positive if long, negative if short)
 * P is the oracle price for the market
 * I is the initial margin fraction for the market
 * M is the maintenance margin fraction for the market

The margin requirement for the account as a whole is the sum of the margin
requirement over each market i in which the account holds a position:

Total Initial Margin Requirement = Σ abs(Si × Pi × Ii)
Total Maintenance Margin Requirement = Σ abs(Si × Pi × Mi)


The total margin requirement is compared against the total value of the account,
which incorporates the quote asset (USDC) balance of the account as well as the
value of the positions held by the account:

Total Account Value = Q + Σ (Si × Pi)


The Total Account Value is also referred to as equity.

Where:

 * Q is the account's USDC balance (note that Q may be negative). In the API,
   this is called quoteBalance. Every time a transfer, deposit or withdrawal
   occurs for an account, the balance changes. Also, when a position is modified
   for an account, the quoteBalance changes. Also funding payments and
   liquidations will change an account's quoteBalance.
 * S and P are as defined above (note that S may be negative)

An account cannot open new positions or increase the size of existing positions
if it would lead the total account value of the account to drop below the total
initial margin requirement. If the total account value ever falls below the
total maintenance margin requirement, the account may be liquidated.

Free collateral is calculated as:

Free collateral = Total Account Value - Total Initial Margin Requirement


Equity and free collateral can be tracked over time using the latest oracle
price (obtained from the markets websocket).


LIQUIDATIONS

Accounts whose total value falls below the maintenance margin requirement
(described above) may have their positions automatically closed by the
liquidation engine. Positions are closed at the close price described below.
Profits or losses from liquidations are taken on by the insurance fund.


CLOSE PRICE FOR LIQUIDATIONS

The close price for a position being liquidated is calculated as follows,
depending whether it is a short or long position:

Close Price (Short) = P × (1 + (M × V / W))
Close Price (Long) = P × (1 − (M × V / W))


Where:

 * P is the oracle price for the market
 * M is the maintenance margin fraction for the market
 * V is the total account value, as defined above
 * W is the total maintentance margin requirement, as defined above

This formula is chosen such that the ratio V / W is unchanged as individual
positions are liquidated.


FUNDING

Funding payments are exchanged between long and short traders to encourage the
price of a perpetual contract to trade close to the price of the underlying. If
the perpetual trades at a premium relative to the index, long traders will
typically make payments to short traders, whereas if the perpetual trades at a
discount relative to the index, short traders will typically make payments to
long traders.

The payments are credited or debited at the start of each hour, and are included
in the realized PnL for the position.

Funding payments can be found by calling Get /v3/funding and the predicted
funding rate can be found by calling Get v3/markets.


FUNDING RATE UNITS

Since funding payments are exchanged every hour, the dYdX funding rate is
usually represented as a 1-hour rate, which represents the return a position may
expect to earn or pay every hour.

When calculating the funding rate, the premium is scaled to have a realization
period of 8 hours. That means, for example, that if a certain perpetual market
trades consistently at a 0.1% premium relative to the underlying, long traders
may expect to pay ~0.1% every 8 hours, and short traders may expect to earn a
~0.1% return every 8 hours (not accounting for the interest rate component).


FUNDING PAYMENT CALCULATION

At the start of each hour, an account receives USDC (if F is positive) or pays
USDC (if F is negative) in an amount equal to:

F = (-1) × S × P × R


Where:

 * S is the size of the position (positive if long, negative if short)
 * P is the oracle price for the market
 * R is the funding rate (as a 1-hour rate)


FUNDING RATE CALCULATION

The main component of the funding rate is a premium that takes into account
market activity for the perpetual. It is calculated for each market, every
minute (at a random point within the minute) using the formula:

Premium = (Max(0, Impact Bid Price - Index Price) - Max(0, Index Price - Impact Ask Price)) / Index Price


Where the impact bid and impact ask prices are defined as:

Impact Bid Price = Average execution price for a market sell of the impact notional value
Impact Ask Price = Average execution price for a market buy of the impact notional value


And the impact notional amount for a market is:

Impact Notional Amount = 500 USDC / Initial Margin Fraction


For example, for a market with a 10% initial margin fraction, the impact
notional value is 5,000 USDC.

At the end of each hour, the premium component is calculated as the simple
average (i.e. TWAP) of the 60 premiums calculated over the course of the last
hour. In addition to the premium component, each market has a fixed interest
rate component that aims to account for the difference in interest rates of the
base and quote currencies. The funding rate is then:

Funding Rate = (Premium Component / 8) + Interest Rate Component


Currently, the interest rate component for all dYdX markets is 0.00125%
(equivalent to 0.01% per 8 hours).


CONTRACT LOSS MECHANISMS

During periods of high volatility in the markets underlying the perpetual
contracts, the value of some accounts may drop below zero before they can be
liquidated.

The insurance fund is the first backstop to maintain the solvency of the system
when an account has a negative balance. The account will be liquidated, and the
insurance fund will take on the loss.

In the event that the insurance fund is depleted, positions with the most profit
and leverage may be used to offset negative-balance accounts, in order to
maintain the stability of the system.


ORACLE PRICES

The Oracle Price for each trading pair is used for the following:

 * Ensuring that each account is well-collateralized after each trade
 * Determining when an account should be liquidated


CALCULATION

Oracle prices are equal to the median of the reported prices of 15 independent
Chainlink nodes.


NODE PROVIDERS

 * Chainlayer
 * Inotel
 * LinkForest
 * SimplyVC
 * DexTrac
 * Fiews
 * dMakers
 * linkPool
 * SDL
 * Ztake
 * stakFacils
 * infStones
 * 01node
 * Syncnode
 * Vulcan


INDEX PRICES

The Index Price for each trading pair is used for the following:

 * Calculating the funding rate
 * Triggering "triggerable" order types such as Stop-Limit and Take-Profit
   orders


CALCULATION

Index prices are equal to the median of several exchanges' spot prices.

Each exchange's spot price is calculated as the median of the best-ask,
best-bid, and last-traded prices of its spot pair.

If the exchange's quote-asset is a non-USD asset (including USDT), the price is
adjusted by our index price for that asset.


EXCHANGE SOURCES

USDT-USD

 * Binance: BTC-USD Index Price / BTC-USDT
 * Bitfinex: USDT-USD
 * FTX: ETH-USD Index Price / ETH-USDT
 * Huobi: ETH-USD Index Price / ETH-USDT
 * Kraken: USDT-USD
 * OKEx: BTC-USD Index Price / BTC-USDT

ETH-USD

 * Binance: ETH-USDT
 * Bitstamp: ETH-USD
 * CoinbasePro: ETH-USD
 * FTX: ETH-USD
 * Gemini: ETH-USD
 * Kraken: ETH-USD

BTC-USD

 * Bitstamp: BTC-USD
 * Bittrex: BTC-USD
 * CoinbasePro: BTC-USD
 * FTX: BTC-USD
 * Gemini: BTC-USD
 * Kraken: BTC-USD

LINK-USD

 * Binance: LINK-USDT
 * CoinbasePro: LINK-USD
 * Huobi: LINK-USDT
 * Kraken: LINK-USD
 * KuCoin: LINK-USDT
 * OKEx: LINK-USDT

AAVE-USD

 * Binance: AAVE-USDT
 * CoinbasePro: AAVE-USD
 * FTX: AAVE-USD
 * Gemini: AAVE-USD
 * Huobi: AAVE-USDT
 * Kraken: AAVE-USD
 * OKEx: AAVE-USDT

UNI-USD

 * Binance: UNI-USDT
 * CoinbasePro: UNI-USD
 * FTX: UNI-USD
 * Gemini: UNI-USD
 * Huobi: UNI-USDT
 * Kraken: UNI-USD
 * OKEx: UNI-USDT

SUSHI-USD

 * Binance: SUSHI-USDT
 * Bitfinex: SUSHI-USD
 * CoinbasePro: SUSHI-USD
 * FTX: SUSHI-USD
 * Gate: SUSHI-USDT
 * Huobi: SUSHI-USDT
 * OKEx: SUSHI-USDT

SOL-USD

 * Binance: SOL-USDT
 * Bitfinex: SOL-USD
 * FTX: SOL-USD
 * Huobi: SOL-USDT
 * KuCoin: SOL-USDT
 * OKEx: SOL-USDT

YFI-USD

 * Binance: YFI-USDT
 * Bitfinex: YFI-USD
 * CoinbasePro: YFI-USD
 * FTX: YFI-USD
 * Gemini: YFI-USD
 * Huobi: YFI-USDT
 * Kraken: YFI-USD
 * OKEx: YFI-USDT

1INCH-USD

 * Binance: 1INCH-USDT
 * CoinbasePro: 1INCH-USD
 * FTX: 1INCH-USD
 * Gate: 1INCH-USDT
 * Gemini: 1INCH-USD
 * Huobi: 1INCH-USDT
 * OKEx: 1INCH-USDT

AVAX-USD

 * Binance: AVAX-USDT
 * Bitfinex: AVAX-USD
 * Gate: AVAX-USDT
 * FTX: AVAX-USD
 * Huobi: AVAX-USDT
 * KuCoin: AVAX-USDT
 * OKEx: AVAX-USDT

SNX-USD

 * Binance: SNX-USDT
 * CoinbasePro: SNX-USD
 * FTX: SNX-USD
 * Gemini: SNX-USD
 * Huobi: SNX-USDT
 * Kraken: SNX-USD
 * OKEx: SNX-USDT

CRV-USD

 * Binance: CRV-USDT
 * CoinbasePro: CRV-USD
 * FTX: CRV-USD
 * Gate: CRV-USDT
 * Gemini: CRV-USD
 * Huobi: CRV-USDT
 * Kraken: CRV-USD
 * OKEx: CRV-USDT

UMA-USD

 * Binance: UMA-USDT
 * CoinbasePro: UMA-USD
 * Gate: UMA-USDT
 * Gemini: UMA-USD
 * Huobi: UMA-USDT
 * OKEx: UMA-USDT

DOT-USD

 * Binance: DOT-USDT
 * Bitfinex: DOT-USD
 * Gate: DOT-USDT
 * Huobi: DOT-USDT
 * Kraken: DOT-USD
 * KuCoin: DOT-USDT
 * OKEx: DOT-USDT

DOGE-USD

 * Binance: DOGE-USDT
 * FTX: DOGE-USD
 * Gate: DOGE-USDT
 * Huobi: DOGE-USDT
 * Kraken: DOGE-USD
 * KuCoin: DOGE-USDT
 * OKEx: DOGE-USDT

MATIC-USD

 * Binance: MATIC-USDT
 * CoinbasePro: MATIC-USD
 * FTX: MATIC-USD
 * Gate: MATIC-USDT
 * Huobi: MATIC-USDT
 * KuCoin: MATIC-USDT
 * OKEx: MATIC-USDT

MKR-USD

 * Binance: MKR-USDT
 * CoinbasePro: MKR-USD
 * FTX: MKR-USD
 * Gate: MKR-USDT
 * Gemini: MKR-USD
 * Huobi: MKR-USDT
 * OKEx: MKR-USDT

FIL-USD

 * Binance: FIL-USDT
 * CoinbasePro: FIL-USD
 * Gemini: FIL-USD
 * Huobi: FIL-USDT
 * Kraken: FIL-USD
 * OKEx: FIL-USDT

ADA-USD

 * Binance: ADA-USDT
 * Bitfinex: ADA-USD
 * CoinbasePro: ADA-USD
 * Gate: ADA-USDT
 * Huobi: ADA-USDT
 * Kraken: ADA-USD
 * KuCoin: ADA-USDT

ATOM-USD

 * Binance: ATOM-USDT
 * CoinbasePro: ATOM-USD
 * Huobi: ATOM-USDT
 * Kraken: ATOM-USD
 * KuCoin: ATOM-USDT
 * OKEx: ATOM-USDT

COMP-USD

 * Binance: COMP-USDT
 * CoinbasePro: COMP-USD
 * FTX: COMP-USD
 * Huobi: COMP-USDT
 * Kraken: COMP-USD
 * OKEx: COMP-USDT

BCH-USD

 * Binance: BCH-USDT
 * CoinbasePro: BCH-USD
 * FTX: BCH-USD
 * Gemini: BCH-USD
 * Huobi: BCH-USDT
 * Kraken: BCH-USD
 * OKEx: BCH-USDT

LTC-USD

 * Binance: LTC-USDT
 * CoinbasePro: LTC-USD
 * FTX: LTC-USD
 * Huobi: LTC-USDT
 * Kraken: LTC-USD
 * OKEx: LTC-USDT

EOS-USD

 * Binance: EOS-USDT
 * Bitfinex: EOS-USD
 * CoinbasePro: EOS-USD
 * Huobi: EOS-USDT
 * Kraken: EOS-USD
 * OKEx: EOS-USDT

ALGO-USD

 * Binance: ALGO-USDT
 * CoinbasePro: ALGO-USD
 * Huobi: ALGO-USDT
 * Kraken: ALGO-USD
 * KuCoin: ALGO-USDT
 * OKEx: ALGO-USDT

ZRX-USD

 * Binance: ZRX-USDT
 * Bitfinex: ZRX-USD
 * CoinbasePro: ZRX-USD
 * Gemini: ZRX-USD
 * Huobi: ZRX-USDT
 * OKEx: ZRX-USDT

XMR-USD

 * Binance: XMR-USDT
 * Bitfinex: XMR-USD
 * Gate: XMR-USDT
 * Kraken: XMR-USD
 * KuCoin: XMR-USDT
 * OKEx: XMR-USDT

ZEC-USD

 * Binance: ZEC-USDT
 * Bitfinex: ZEC-USD
 * CoinbasePro: ZEC-USD
 * Gemini: ZEC-USD
 * Kraken: ZEC-USD
 * KuCoin: ZEC-USDT
 * OKEx: ZEC-USDT

ENJ-USD

 * Binance: ENJ-USDT
 * CoinbasePro: ENJ-USD
 * FTX: ENJ-USD
 * Gate: ENJ-USDT
 * Huobi: ENJ-USDT
 * KuCoin: ENJ-USDT
 * OKEx: ENJ-USDT

ETC-USD

 * Binance: ETC-USDT
 * CoinbasePro: ETC-USD
 * Gate: ETC-USDT
 * Huobi: ETC-USDT
 * Kraken: ETC-USD
 * OKEx: ETC-USDT

XLM-USD

 * Binance: XLM-USDT
 * Bitfinex: XLM-USD
 * CoinbasePro: XLM-USD
 * Gate: XLM-USDT
 * Kraken: XLM-USD
 * KuCoin: XLM-USDT
 * OKEx: XLM-USDT

TRX-USD

 * Binance: TRX-USDT
 * Bitfinex: TRX-USD
 * FTX: TRX-USD
 * Gate: TRX-USDT
 * Huobi: TRX-USDT
 * OKEx: TRX-USDT

XTZ-USD

 * Binance: XTZ-USDT
 * Bitfinex: XTZ-USD
 * CoinbasePro: XTZ-USD
 * Gate: XTZ-USDT
 * Huobi: XTZ-USDT
 * Kraken: XTZ-USD
 * OKEx: XTZ-USDT

HNT-USD

 * Binance: HNT-USDT
 * BinanceUS: HNT-USDT
 * Crypto.com: HNT-USDT
 * FTX: HNT-USD
 * Gate: HNT-USDT
 * KuCoin: HNT-USDT

ICP-USD

 * Binance: ICP-USDT
 * CoinbasePro: ICP-USD
 * Gate: ICP-USDT
 * Huobi: ICP-USDT
 * KuCoin: ICP-USDT
 * OKEx: ICP-USDT

RUNE-USD

 * Binance: RUNE-USDT
 * Bybit: RUNE-USDT
 * Crypto.com: RUNE-USDT
 * Gate: RUNE-USDT
 * KuCoin: RUNE-USDT

LUNA-USD

 * Binance: LUNA-USDT
 * Bitfinex: LUNA-USD
 * FTX: LUNA-USD
 * Huobi: LUNA-USDT
 * Kraken: LUNA-USD
 * KuCoin: LUNA-USDT
 * OKEx: LUNA-USDT

NEAR-USD

 * Binance: NEAR-USDT
 * Gate: NEAR-USDT
 * Huobi: NEAR-USDT
 * KuCoin: NEAR-USDT
 * OKEx: NEAR-USDT

AR-USD

 * Binance: AR-USDT
 * Gate: AR-USDT
 * Huobi: AR-USDT
 * KuCoin: AR-USDT
 * OKEx: AR-USDT

FLOW-USD

 * Binance: FLOW-USDT
 * Crypto.com: FLOW-USDT
 * Gate: FLOW-USDT
 * Huobi: FLOW-USDT
 * Kraken: FLOW-USD
 * KuCoin: FLOW-USDT
 * OKEx: FLOW-USDT

PERP-USD

 * Binance: PERP-USDT
 * CoinbasePro: PERP-USD
 * FTX: PERP-USD
 * Gate: PERP-USDT
 * Kraken: PERP-USD
 * OKEx: PERP-USDT

REN-USD

 * Binance: REN-USDT
 * CoinbasePro: REN-USD
 * Crypto.com: REN-USDT
 * FTX: REN-USD
 * Gate: REN-USDT
 * KuCoin: REN-USDT
 * OKEx: REN-USDT

CELO-USD

 * Binance: CELO-USDT
 * CoinbasePro: CELO-USD
 * Gate: CELO-USDT
 * KuCoin: CELO-USDT
 * OKEx: CELO-USDT

KSM-USD

 * Binance: KSM-USDT
 * Gate: KSM-USDT
 * Huobi: KSM-USDT
 * Kraken: KSM-USD
 * KuCoin: KSM-USDT
 * OKEx: KSM-USDT

BAL-USD

 * Binance: BAL-USDT
 * CoinbasePro: BAL-USD
 * Gate: BAL-USDT
 * Huobi: BAL-USDT
 * Kraken: BAL-USD
 * OKEx: BAL-USDT

BNT-USD

 * Binance: BNT-USDT
 * CoinbasePro: BNT-USD
 * Crypto.com: BNT-USDT
 * FTX: BNT-USD
 * OKEx: BNT-USDT

MIR-USD

 * Binance: MIR-USDT
 * CoinbasePro: MIR-USD
 * Gate: MIR-USDT
 * Huobi: MIR-USDT
 * KuCoin: MIR-USDT
 * OKEx: MIR-USDT

SRM-USD

 * Binance: SRM-USDT
 * FTX: SRM-USD
 * Gate: SRM-USDT
 * Huobi: SRM-USDT
 * OKEx: SRM-USDT

LON-USD

 * Gate: LON-USDT
 * KuCoin: LON-USDT
 * OKEx: LON-USDT

DODO-USD

 * Binance: DODO-USDT
 * FTX: DODO-USD
 * Gate: DODO-USDT
 * KuCoin: DODO-USDT

ALPHA-USD

 * Binance: ALPHA-USDT
 * FTX: ALPHA-USD
 * Gate: ALPHA-USDT
 * KuCoin: ALPHA-USDT
 * OKEx: ALPHA-USDT

WNXM-USD

 * Binance: WNXM-USDT
 * Gate: WNXM-USDT
 * Huobi: WNXM-USDT
 * KuCoin: WNXM-USDT
 * OKEx: WNXM-USDT

XCH-USD

 * Gate: XCH-USDT
 * Huobi: XCH-USDT
 * KuCoin: XCH-USDT
 * OKEx: XCH-USDT


CLIENTS

Python and TypeScript clients are available, allowing programmatic usage of
dYdX.


PYTHON CLIENT


INSTALLATION

Install dydx-v3-python from PyPI using pip:

pip install dydx-v3-python



USAGE

See dydxprotocol/dydx-v3-python.

See the examples folder for simple python examples.


TYPESCRIPT CLIENT


INSTALLATION

Install @dydxprotocol/v3-client from NPM:

npm i -s @dydxprotocol/v3-client



USAGE

See dydxprotocol/v3-client.

See the examples folder for simple typescript examples.


CLIENT INITIALIZATION

> Initialize

Copy to Clipboardclient = Client(
    host='https://api.dydx.exchange',
    web3=Web3('...'),
    stark_private_key='01234abcd...',
)


Copy to Clipboardconst client: DydxClient = new Client(
    'host',
    {
        apiTimeout: 3000,
        starkPrivateKey: '01234abcd...',
    },
);


The client is organized into modules, based on the type of authentication needed
for different requests. The configuration options passed into the client
determine which modules are available. See Authentication for more information.

Multiple methods of authorization are available, so users never need to provide
private keys directly to the client, if so desired. Ethereum signatures are
needed only for onboarding and managing API keys, not trading, and may be
provided via a web3 provider. STARK key signatures are required for trading, and
the STARK key can be held either in the client or elsewhere.

Module Description public Public API endpoints. Does not require authentication.
onboarding Endpoint to create a new user, authenticated via Ethereum key.
api_keys Endpoints for managing API keys, authenticated via Ethereum key.
private All other private endpoints, authenticated via API key. eth Calling and
querying L1 Ethereum smart contracts.

The following configuration options are available:

Parameter Description host The HTTP API host. api_timeout Timeout for HTTP
requests, in milliseconds. default_ethereum_address (Optional) The default
account for Ethereum key auth and sending Ethereum transactions. eth_private_key
(Optional) May be used for Ethereum key auth. eth_send_options (Optional)
Options for Ethereum transactions, see sendTransaction. network_id (Optional)
Chain ID for Ethereum key auth and smart contract addresses. Defaults to
web3.net.version if available, or 1 (mainnet). stark_private_key (Optional)
STARK private key, used to sign orders and withdrawals. web3 (Optional) Web3
object used for Ethereum key auth and/or smart contract interactions.
web3_account (Optional) May be used for Ethereum key auth. web3_provider
(Optional) Web3 provider object, same usage as web3. api_key_credentials
(Optional) Dictionary containing the key, secret and passphrase required for the
private module to sign requests. crypto_c_exports_path (Optional) For python
only, will use faster C++ code to run hashing, signing and verifying. It's
expected to be compiled from the crypto_c_exports target from Starkware's
repository. See section on this below for more information.


C++ METHODS FOR FASTER STARK SIGNING

This optimization is only available for the Python client currently.

The C++ wrapper methods in the client expect an absolute path to a Shared
Object. This has to be compiled from Starkware's crypto C++ library.


PRIVATE HTTP API


AUTHENTICATION

There are three levels of authentication to be considered when using dYdX. All
signing can be handled directly by the client libraries.


ETHEREUM KEY AUTHENTICATION

The highest level of authentication is via an account's Ethereum private key.
The Ethereum key remains in control of an account's funds while they are within
the L2 system. This includes the ability to forcibly close an account's
positions and exit the system, in the event that the L2 operators (dYdX and
Starkware) were to unexpectedly go offline or otherwise censor requests.

Ethereum key authentication is required for the following operations:

 * Register a new user or STARK key
 * Create or revoke API keys
 * Request a forced withdrawal or forced trade


STARK KEY AUTHENTICATION

Within the L2 system, authentication is handled by a separate key pair, known as
the account's STARK key pair.

STARK key authentication is required for the following operations:

 * Place an order
 * Withdraw funds


API KEY AUTHENTICATION

The third level of authentication consists of the API key, secret and passphrase
which are used solely to authenticate API requests made to dYdX. This includes
operations such as canceling orders or retrieving an account's fills, which do
not affect the L2 system.

When a user onboards via POST v3/onboarding, the server will use the signature
as a seed to determinstically generate default API key credentials. An API key
includes three fields:

 * key: UUID identifying the credentials.
 * secret: Secret string used to generate HMACs, not sent with requests.
 * passphrase: Secret string sent with each request, used to encrypt/decrypt the
   secret in our DB, and never stored in our DB.

API keys can be added and managed via the /v3/api-keys endpoints.

All requests which are not signed by an Ethereum key and which are made to
private endpoints require an API key signature.


STARK KEY CRYPTOGRAPHY

The STARK and API keys are ECDSA key pairs on the STARK curve. More info on the
cryptography used on L2 is available in Starkware's documentation.


CREATING AND SIGNING REQUESTS

Note that the Python and TypeScript clients can generate all required
signatures.

Within the private HTTP API, there are three groups of endpoints which each
require different headers and authentication.

(Separately, and in addition to the above, STARK signatures are required for
orders and withdrawals. For details, please refer to the Python and TypeScript
reference implementations.)


ONBOARDING ENDPOINT: POST V3/ONBOARDING

Request Headers

Header Required? Description DYDX-SIGNATURE yes Ethereum key authentication
DYDX-ETHEREUM-ADDRESS yes Ethereum address of the user

Signing

The header DYDX-SIGNATURE is an EIP-712 Ethereum signature on a static message
containing the fields:

 * action: The string DYDX-ONBOARDING.
 * onlySignOn: The string https://trade.dydx.exchange.

See reference implementations: [Python] [TypeScript]


ETHEREUM KEY PRIVATE ENDPOINTS

This group includes the POST and DELETE v3/api-keys endpoints for managing API
keys. Like the onboarding endpoint, requests to these endpoints require
signatures by the user's Ethereum key.

Request Headers

Header Required? Description DYDX-SIGNATURE yes Ethereum key authentication
DYDX-ETHEREUM-ADDRESS yes Ethereum address of the user DYDX-TIMESTAMP yes ISO
timestamp of when the request was signed. Must be within 30 seconds of the
server time.

Signing

The header DYDX-SIGNATURE is an EIP-712-compliant Ethereum signature on a
message containing the fields:

 * method: The name of the HTTP method used, uppercase (e.g. GET).
 * requestPath: The API endpoint path, beginning with /v3/.
 * body: The HTTP request body (normally empty for GET and DELETE).
 * timestamp: Equal to the header DYDX-TIMESTAMP.

See reference implementations: [Python] [TypeScript]


API KEY PRIVATE ENDPOINTS

All private endpoints not listed above fall in this category, and must be
authenticated via an API key.

Request Headers

Header Required? Description DYDX-SIGNATURE yes HMAC of the request.
DYDX-API-KEY yes Api key for the account. DYDX-TIMESTAMP yes ISO timestamp of
when the request was signed. Must be within 30 seconds of the server time.
DYDX-PASSPHRASE yes The passphrase field of the API key. DYDX-ACCOUNT-NUMBER no
Account number used to scope the request. Defaults to zero.

Signing

The DYDX-SIGNATURE is a SHA-256 HMAC produced as described below, and encoded as
a Base64 string.

A SHA-256 HMAC is created using the API key secret and the message timestamp +
method + requestPath + body defined as follows:

 * timestamp: The DYDX-TIMESTAMP header, which must be within 30 seconds of the
   server time.
 * method: The name of the HTTP method used, uppercase (e.g. GET).
 * requestPath: The API endpoint path, beginning with /v3/.
 * body: The HTTP request body (normally empty for GET and DELETE).

The HMAC should be encoded as a Base64 string and sent as the DYDX-SIGNATURE
header.

See reference implementations: [Python] [TypeScript]


ONBOARDING


OVERVIEW

A few steps are required of all accounts before they can begin trading:

 1. Create a user, providing a STARK public key to be associated with the main
    account.
 2. Request registration signature from dYdX.
 3. Send registration request to the L1 smart contract.
 4. Approve collateral token allowance on the L1 smart contract.
 5. Deposit collateral token to the L1 smart contract.

All of these steps are supported by the Python and TypeScript clients. See the
Python integration tests for an example of onboarding and usage of various
endpoints.

> Create User

Copy to Clipboardonboarding_information = client.onboarding.create_user(
  # Optional if stark_private_key was provided.
  stark_public_key='012340bcd...',
  stark_public_key_y_coordinate='01234abcd...',
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='ethereumAddress',
  country='SG',
)


Copy to Clipboardconst onboardingInformation: {
  apiKey: ApiKeyCredentials,
  user: UserResponseObject,
  account: AccountResponseObject,
}  = await client.onboarding.createUser(
  {
    starkKey: '71234abcd...',
    starkKeyYCoordinate: '01234abcd...',
    country: 'SG',
  },
  ethereumAddress: 'ethereumAddress',
);


Copy to Clipboard{
  "apiKey": {
    "key": "290decd9-548b-62a8-d603-45a988386fc8",
    "passphrase": "S6a8lUhACPY2L5MWDvPl",
    "secret": "KQ3s2VSLYqjWA0WpiDhvyEumvJVIQAj2Ni-TFg7z"
  },
  "user": {
    "ethereumAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "isRegistered": true,
    "email": "email@dydx.exchange",
    "username": "supersam15o",
    "referredByAffiliateLink": null,
    "makerFeeRate": "0.01",
    "takerFeeRate": "0.01",
    "makerVolume30D": "1000.00",
    "takerVolume30D": "1000.00",
    "fees30D": "00.50",
    "userData": {},
    "dydxTokenBalance": "0",
    "stakedDydxTokenBalance": "0",
    "isEmailVerified": false,
    "isSharingUsername": null,
    "isSharingAddress": true,
    "country": "SG",
  },
  "account": {
    "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
    "positionId": "1812",
    "equity": "10000",
    "freeCollateral": "10000",
    "quoteBalance": "10000",
    "pendingDeposits": "0",
    "pendingWithdrawals": "0",
    "createdAt": "2021-04-09T21:08:34.984Z",
    "openPositions": {
      "BTC-USD": {
        "market": "BTC-USD",
        "status": "OPEN",
        "side": "LONG",
        "size": "1000",
        "maxSize": "1050",
        "entryPrice": "100",
        "exitPrice": null,
        "unrealizedPnl": "50",
        "realizedPnl": "100",
        "createdAt": "2021-01-04T23:44:59.690Z",
        "closedAt": null,
        "netFunding": "500",
        "sumOpen": "1050",
        "sumClose": "50"
      }
    },
    "accountNumber": "5",
    "id": "id"
  }
}



HTTP REQUEST

POST v3/onboarding

Programmatic users of the API must take care to store private STARK and API keys
securely. dYdX does not store any private keys. Using the default key generation
methods (such as `derive_stark_key`) ensures keys can be easily recovered by
Ethereum key holder. If you generate your STARK key through other means, you
must be careful not to lose it, or your funds may be inaccessible for a period
of time.

Description: Onboard a user so they can begin using dYdX V3 API. This will
generate a user, account and derive a key, passphrase and secret from the
signature.


REQUEST

Parameter Description starkKey Public starkKey associated with the key-pair you
created. starkKeyYCoordinate Public starkKey Y-Coordinate associated with the
key-pair you created. ethereumAddress Ethereum address associated with the user
being created. referredByAffiliateLink (Optional) Link to affiliate the user was
referred by. country (Optional) Country of the user's residence. Must be ISO
3166-1 Alpha-2 compliant.


RESPONSE

Parameter Description apiKey See ApiKeyCredentials. user See User. account See
Account.


DERIVE STARKKEY

> Derive StarkKey

Copy to Clipboardkey_pair_with_y_coordinate = client.onboarding.derive_stark_key(
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='ethereumAddress',
)


Copy to Clipboardconst keyPairWithYCoordinate: KeyPairWithYCoordinate = await client.onboarding.deriveStarkKey(
  'ethereumAddress',
);


This method does not access the dYdX API. This is used by the frontend app to
derive the STARK key pair in a way that is recoverable. Programmatic traders may
optionally derive their STARK key pair in the same way.


REQUEST

Parameter Description ethereumAddress Ethereum address associated with the user
being created.


RESPONSE

Parameter Description keyPairWithYCoordinate KeyPairWithYCoordinate.


KEYPAIRWITHYCOORDINATE

field type description publicKey string The x-coordinate of the publicKey.
publicKeyYCoordinate string The y-coordinate of the publicKey. privateKey string
The privateKey for the key pair.


RECOVER DEFAULT API CREDENTIALS

> Recover Default API Credentials

Copy to Clipboardapi_credentials = client.onboarding.recover_default_api_key_credentials(
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='ethereumAddress',
)


Copy to Clipboardconst apiCredentials: ApiKeyCredentials = await client.onboarding.recoverDefaultApiCredentials(
  'ethereumAddress',
);


This method does not access the dYdX API. This can be used to recover the
default API key credentials, which are the same set of credentials used in the
dYdX frontend.


REQUEST

Parameter Description ethereumAddress Ethereum address associated with the user
being created.


RESPONSE

Parameter Description apiCredentials ApiKeyCredentials.


APIKEYCREDENTIALS

field type description key string UUID identifying the credentials. secret
string Secret string used to generate HMACs. passphrase string Secret string
sent with each request.


RECOVER STARKKEY, QUOTEBALANCE AND OPEN POSITIONS

> Recovery

Copy to Clipboardrecovery = client.eth_private.recovery(
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='ethereumAddress',
)


Copy to Clipboardconst recovery: {
  starkKey: string,
  positionId: string,
  quoteBalance: string,
  positions: PositionResponseObject[],
} = client.ethPrivate.recovery(
  'ethereumAddress',
);


Copy to Clipboard{
  "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
  "positionId": "1812",
  "equity": "10000",
  "freeCollateral": "10000",
  "quoteBalance": "10000",
  "positions": [
    {
      "market": "BTC-USD",
      "status": "OPEN",
      "side": "LONG",
      "size": "1000",
      "maxSize": "1050",
      "entryPrice": "100",
      "exitPrice": null,
      "unrealizedPnl": "50",
      "realizedPnl": "100",
      "createdAt": "2021-01-04T23:44:59.690Z",
      "closedAt": null,
      "netFunding": "500",
      "sumOpen": "1050",
      "sumClose": "50"
    }
  ]
}



HTTP REQUEST

GET v3/recovery

Description: This is for if you can't recover your starkKey or apiKey and need
an additional way to get your starkKey and balance on our exchange, both of
which are needed to call the L1 solidity function needed to recover your funds.


RESPONSE

Parameter Description starkKey Public starkKey associated with the key-pair you
created. positionId Starkware-specific positionId. equity The amount of equity
(value) in the account. Uses balances and oracle-prices to calculate.
freeCollateral The amount of collateral that is withdrawable from the account.
quoteBalance Human readable quote token balance. Can be negative. positions See
Positions. Note, only open position are returned.


GET REGISTRATION

> Get Registration

Copy to Clipboardsignature = client.private.get_registration()


Copy to Clipboardconst signature: { signature: string } = await client.private.getRegistration();


Copy to Clipboard{
  "signature": "foo"
}



HTTP REQUEST

GET v3/registration

Description: Gets the dYdX provided Ethereum signature required to send a
registration transaction to the Starkware smart contract.


RESPONSE

Parameter Description signature Ethereum signature authorizing the user's
Ethereum address to register for the corresponding position id.


REGISTER API KEY

> Register API Key

Copy to Clipboardapi_key_response = client.eth_private.create_api_key(
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='0x0123...',
)


Copy to Clipboardconst apiKey: { apiKey: ApiKeyCredentials } = await client.ethPrivate.createApiKey(
  '0x0123...',
);


Copy to Clipboard{
  "apiKey": {
    "key": "290decd9-548b-62a8-d603-45a988386fc8",
    "passphrase": "S6a8lUhACPY2L5MWDvPl",
    "secret": "KQ3s2VSLYqjWA0WpiDhvyEumvJVIQAj2Ni-TFg7z"
  }
}



HTTP REQUEST

POST v3/api-keys

Description: Create new API key credentials for a user.


RESPONSE

Parameter Description apiKey ApiKeyCredentials.


GET API KEYS

> Get API Keys

Copy to Clipboardapi_keys = client.private.get_api_keys()


Copy to Clipboardconst apiKeys: { keys: string[] } = await client.private.getApiKeys();


Copy to Clipboard{
  "apiKeys": [
    "290decd9-548b-62a8-d603-45a988386fc8",
    "390decd9-548b-62a8-d603-45a988386fc8",
    ...
  ]
}



HTTP REQUEST

GET v3/api-keys

Description: Get all api keys associated with an Ethereum address.

Note that this endpoint is in the private module, unlike the methods to create
or revoke API keys.


RESPONSE

Parameter Description apiKeys Array of apiKey strings corresponding to the
ethereumAddress in the request.


DELETE API KEY

> Delete API Key

Copy to Clipboardclient.eth_private.delete_api_key(
  api_key='290decd9-548b-...',
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='0x0123...',
)


Copy to Clipboardawait client.ethPrivate.delete_api_key(
  '290decd9-548b-...', // API key
  '0x0123...', // Ethereum address
);


Copy to Clipboard{
  "apiKey": "foo"
}



HTTP REQUEST

DELETE v3/api-keys

Description: Delete an api key by key and Ethereum address.

Deleting your API keys may cause you to be locked out of your account. dYdX will
only prevent deleting your last API Key. Proceed with caution when using this
endpoint.


REQUEST

Parameter Description apiKey Public api key being deleted. ethereumAdddress
Ethereum address the api key is associated with.


RESPONSE

Returns a 200 on success.


GET USER

> Get User

Copy to Clipboarduser = client.private.get_user()


Copy to Clipboardconst user: { user: UserResponseObject } = await client.private.getUser();


Copy to Clipboard{
  "user": {
    "ethereumAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "isRegistered": true,
    "email": "email@dydx.exchange",
    "username": "supersam15o",
    "referredByAffiliateLink": null,
    "makerFeeRate": "0.01",
    "takerFeeRate": "0.01",
    "makerVolume30D": "1000.00",
    "takerVolume30D": "1000.00",
    "fees30D": "00.50",
    "userData": {},
    "dydxTokenBalance": "0",
    "stakedDydxTokenBalance": "0",
    "isEmailVerified": false,
    "hedgiesHeld": [1, 2, 3000],
    "country": "CN",
    "languageCode": "zh-CN"
  }
}



HTTP REQUEST

GET v3/users

Description: return the user and user information.


RESPONSE

Parameter Description ethereumAddress The 20-byte Ethereum address. isRegistered
True if the user is registered on the starkware smart contract. This is false
otherwise. email Email address. username User defined username.
referredByAffiliateLink The affiliate link that referred this user, or null if
the user was not referred. makerFeeRate The fee rate the user would be willing
to take as the maker. Fee rates are rounded to a 100th of a basis point, or
0.0001%. Note, 1% would be represented as 0.01. takerFeeRate The fee rate the
user would be willing to take as the taker. Fee rates are rounded to a 100th of
a basis point, or 0.0001%. Note, 1% would be represented as 0.01. makerVolume30D
The user's trailing-thirty-day maker volume in USD. takerVolume30D The user's
trailing-thirty-day taker volume in USD. fees30D The user's trailing-thirty-day
fees in USD. userData The user's unstructured user data. dydxTokenBalance The
user's DYDX token holdings. stakedDydxTokenBalance The user's staked DYDX token
holdings isEmailVerified If the user's email address is verified to receive
emails from dYdX. hedgiesHeld Indices of all Hedgies held by the user. country
Country of the user's residence. Must be ISO 3166-1 Alpha-2 compliant.
languageCode The user's preferred language. Must be ISO 639-1 compliant,
including 'zh-CN'.


UPDATE USER

> Update user

Copy to Clipboarduser = client.private.update_user(
  user_data={},
  email='user@example.com',
  username='username',
  is_sharing_email=False,
  is_sharing_address=True,
  country='SG',
  language_code='en',
)


Copy to Clipboardconst user: { user: UserResponseObject } = await client.private.updateUser({
  email: 'user@example.com',
  username: 'username',
  isSharingEmail: false,
  isSharingAddress: false,
  userData: {},
  country: 'SG',
  languageCode: 'en',
});


Copy to Clipboard{
  "user": {
    "ethereumAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "isRegistered": true,
    "email": "email@dydx.exchange",
    "username": "supersam15o",
    "referredByAffiliateLink": null,
    "makerFeeRate": "0.01",
    "takerFeeRate": "0.01",
    "makerVolume30D": "1000.00",
    "takerVolume30D": "1000.00",
    "fees30D": "00.50",
    "userData": {},
    "dydxTokenBalance": "0",
    "stakedDydxTokenBalance": "0",
    "isEmailVerified": false,
    "country": "SG",
    "languageCode": "en"
  }
}



HTTP REQUEST

PUT v3/users

Description: Update user information and return the updated user.

Parameter Description userData User metadata in a JSON blob. email (Optional)
Email to be used with the user. username (Optional) Username to be used for the
user. isSharingUsername (Optional) Share username publically on leaderboard
rankings. isSharingAddress (Optional) Share ETH address publically on
leaderboard rankings. country (Optional) Country of the user's residence. Must
be ISO 3166-1 Alpha-2 compliant. languageCode (Optional) The user's preferred
language. Must be ISO 639-1 compliant, including 'zh-CN'.


RESPONSE

Parameter Description user See User.


GET USER ACTIVE LINKS

> Get User Active Links

Copy to Clipboardlinks = client.private.get_user_links()


Copy to Clipboardconst userLinks: UserLinksResponseObject = await client.private.getUserLinks();


Copy to Clipboard{
  "userType": "SECONDARY",
  "primaryAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
  "secondaryAddresses": null
}



HTTP REQUEST

GET v3/users/links

Description: return active user links.


RESPONSE

Parameter Description userType PRIMARY, SECONDARY, or null if no active links.
primaryAddress Address of the PRIMARY user if userType = SECONDARY. null
otherwise. linkedAddresses Addresses of the SECONDARY users if userType =
PRIMARY. null otherwise.


SEND USER LINK REQUEST

> Send User Link Request

Copy to Clipboardpending_links = client.private.send_link_request('CREATE_SECONDARY_REQUEST', '0x0913017c740260fea4b2c62828a4008ca8b0d6e4')


Copy to Clipboardconst res: {} = await client.private.sendLinkRequest({
  action: LinkAction.REMOVE,
  address: "0x0913017c740260fea4b2c62828a4008ca8b0d6e4"
});


Copy to Clipboard{}



HTTP REQUEST

POST v3/users/links

Description: Send a new request to link users, respond to a pending request, or
remove a link.

All DYDX rewards will be calculated and distributed to the primary address
following the current rewards formulas.

For trading rewards, all formula terms will be summed and aggregated across
linked addresses, including fees paid, open interest, and stkDYDX. For liquidity
provider rewards, all formula terms will be summed and aggregated across linked
addresses, including depth/score score, stkDYDX, and maker volume. For each
market, the max uptime across linked addresses will be used.


REQUEST

Parameter Description action CREATE_SECONDARY_REQUEST, DELETE_SECONDARY_REQUEST,
ACCEPT_PRIMARY_REQUEST, REJECT_PRIMARY_REQUEST, or REMOVE. address Address that
the link is with (should not be your own).


RESPONSE

Parameter Description {} Empty object upon success.


LINK ACTIONS

Action Description CREATE_SECONDARY_REQUEST Create a pending link request for
the address to become SECONDARY, and your address to become PRIMARY. Request
will be rejected if either address is already linked. DELETE_SECONDARY_REQUEST
Delete an outgoing link request from your address. ACCEPT_PRIMARY_REQUEST Accept
a pending link request for your address to become SECONDARY and their address to
become PRIMARY. REJECT_PRIMARY_REQUEST Reject an incoming pending link request.
REMOVE Remove an active link between your address and the other's.


GET USER PENDING LINK REQUESTS

> Get User Pending Link Requests

Copy to Clipboardpending_links = client.private.get_user_pending_link_requests()


Copy to Clipboardconst userPendingLinks: UserLinkRequestsResponseObject = await client.private.getUserPendingLinkRequests();


Copy to Clipboard{
  "userType": null,
  "outgoingRequests": [],
  "incomingRequests": [
    {
      "primaryAddress": "0x99b0599952a4fd2d1a1561fa4c010827ead30354",
      "secondaryAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4"
    }
  ]
}



HTTP REQUEST

GET v3/users/links/requests

Description: return pending user links.


RESPONSE

Parameter Description userType PRIMARY, SECONDARY, or null if no active links.
outgoingRequests Outgoing requests for another user to be linked as SECONDARY to
this user. null if userType = SECONDARY. incomingRequests Incoming requests for
this user to be linked as SECONDARY to another user. null if userType != null.


CREATE AN ACCOUNT

> Create Account

Copy to Clipboardclient.private.create_account(
  stark_public_key='701234abcd...',
  stark_public_key_y_coordinate='1234abcd...',
)


Copy to Clipboardconst account: { account: AccountResponseObject } = await client.private.createAccount(
  '701234abcd...', // starkKey
  '1234abcd...', // starkKeyYCoordinate
);


Copy to Clipboard{
  "account": {
    "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
    "positionId": "1812",
    "equity": "10000",
    "freeCollateral": "10000",
    "quoteBalance": "10000",
    "pendingDeposits": "0",
    "pendingWithdrawals": "0",
    "createdAt": "2021-04-09T21:08:34.984Z",
    "openPositions": {
      "BTC-USD": {
        "market": "BTC-USD",
        "status": "OPEN",
        "side": "LONG",
        "size": "1000",
        "maxSize": "1050",
        "entryPrice": "100",
        "exitPrice": null,
        "unrealizedPnl": "50",
        "realizedPnl": "100",
        "createdAt": "2021-01-04T23:44:59.690Z",
        "closedAt": null,
        "netFunding": "500",
        "sumOpen": "1050",
        "sumClose": "50"
      }
    },
    "accountNumber": "5",
    "id": "id"
  }
}


An account will be created automatically during onboarding so this call is not
necessary to get started.


HTTP REQUEST

POST v3/accounts

Description: Create an account with a given starkKey.


REQUEST

Parameter Description starkKey Public starkKey associated with the key-pair you
created. starkKeyYCoordinate Public starkKey Y-Coordinate associated with the
key-pair you created.


RESPONSE

Parameter Description account See Account.


GET ACCOUNT

> Get Account

Copy to Clipboardaccount = client.private.get_account(
  # Optional if eth_private_key or web3.eth.defaultAccount was provided.
  ethereum_address='0x0123...',
)


Copy to Clipboardconst account: { account: AccountResponseObject } = await client.private.getAccount(
  '0x0123...',
);


Copy to Clipboard{
  "account": {
    "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
    "positionId": "1812",
    "equity": "10000",
    "freeCollateral": "10000",
    "quoteBalance": "10000",
    "pendingDeposits": "0",
    "pendingWithdrawals": "0",
    "createdAt": "2021-04-09T21:08:34.984Z",
    "openPositions": {
      "BTC-USD": {
        "market": "BTC-USD",
        "status": "OPEN",
        "side": "LONG",
        "size": "1000",
        "maxSize": "1050",
        "entryPrice": "100",
        "exitPrice": null,
        "unrealizedPnl": "50",
        "realizedPnl": "100",
        "createdAt": "2021-01-04T23:44:59.690Z",
        "closedAt": null,
        "netFunding": "500",
        "sumOpen": "1050",
        "sumClose": "50"
      }
    },
    "accountNumber": "5",
    "id": "id"
  }
}



HTTP REQUEST

GET v3/accounts/:id

Description: Get an account for a user by id. Using the client, the id will be
generated with client information and an Ethereum address.


REQUEST

Parameter Description ethereumAddress Ethereum address associated with an
account.


RESPONSE

Parameter Description starkKey Public StarkKey associated with an account.
positionId Starkware-specific positionId. equity The amount of equity (value) in
the account. Uses balances and oracle-prices to calculate. freeCollateral The
amount of collateral that is withdrawable from the account. quoteBalance Human
readable quote token balance. Can be negative. pendingDeposits The sum amount of
all pending deposits. pendingWithdrawals The sum amount of all pending
withdrawal requests. createdAt When the account was first created in UTC.
openPositions See Positions. Note, markets where the user has no position are
not returned in the map. accountNumber Unique accountNumber for the account. id
Unique id of the account hashed from the userId and the accountNumber.


GET ACCOUNT LEADERBOARD PNLS

> Get Account Leaderboard PNLs

Copy to Clipboardconst account: { accountPnls: AccountLeaderboardPnlResponseObject } = await client.private.getAccountLeaderboardPnl(
  period=LeaderboardPnlPeriod.DAILY,
);


Copy to Clipboard{
  "absolutePnl": "100.000000",
  "percentPnl": "100.000000",
  "absoluteRank": 10,
  "percentRank": 10,
  "startedAt": "2021-08-01T00:00:00.000Z",
  "endsAt": "2021-08-10T00:00:00.000Z",
  "updatedAt": "2021-08-02T22:53:45.659Z",
  "accountId": "afoo",
  "period": "BRONZE",
  "seasonExpectedOutcome": "PROMOTION",
  "seasonNumber": 16,
  "hedgieWon": null,
  "prizeWon": "100000"
}



HTTP REQUEST

GET v3/accounts/leaderboard-pnl/:period

Description: Get an account's personal leaderboard pnls.


REQUEST

Parameter Description period "DAILY", "WEEKLY", "MONTHLY", "ALLTIME",
"COMPETITION", "DAILY_COMPETITION", or "LEAGUES". startingBeforeOrAt (Optional)
Latest the leaderboard starts at.


RESPONSE

Parameter Description absolutePnl The account's latest updated absolute PNL.
percentPnl The account's latest updated percent PNL. absoluteRank User's
absolute PNL rank. null if not ranked. percentRank User's percent PNL rank. null
if not ranked. startedAt Starting time for this pnl. Note: will only be set if
being used for a competition or leagues. Otherwise, this value will always be
null. endsAt Ending time for this pnl. Note: will only be set if being used for
a competition or leagues. Otherwise, this value will always be null. (Can be a
future time.) updatedAt When these leaderboard PNLs were last updated. accountId
The account the PNLs are for. period "DAILY", "WEEKLY", "MONTHLY", "ALLTIME",
"COMPETITION", "BRONZE", "SILVER", "GOLD", "PLATINUM", "DIAMOND".
seasonExpectedOutcome User's expected outcome of latest season. "PROMOTION",
"DEMOTION", or "SAME_LEAGUE". null if not "LEAGUES". seasonNumber Leagues season
number. Starts at 1. null if not "LEAGUES". hedgieWon Index of hedgie won. null
if no hedgie won. prizeWon Amount of cash prize won in dollars. null if no prize
won.


GET ACCOUNT HISTORICAL LEADERBOARD PNLS

> Get Account Historical Leaderboard PNLs

Copy to Clipboardhistorical_leaderboard_pnls = client.private.get_historical_leaderboard_pnls("LEAGUES")


Copy to Clipboardconst historicalLeaderboardPnls: HistoricalLeaderboardPnlsResponseObject = await client.private.getAccountHistoricalLeaderboardPnl(
  period=AccountLeaderboardPnlPeriod.DAILY,
);


Copy to Clipboard{
  "leaderboardPnls" : [
    {
      "absolutePnl": "100.000000",
      "percentPnl": "100.000000",
      "absoluteRank": 10,
      "percentRank": 10,
      "startedAt": "2021-08-01T00:00:00.000Z",
      "endsAt": "2021-08-10T00:00:00.000Z",
      "updatedAt": "2021-08-02T22:53:45.659Z",
      "accountId": "afoo",
      "period": "BRONZE",
      "seasonOutcome": "PROMOTION",
      "seasonNumber": 16,
      "hedgieWon": null,
      "prizeWon": "100000"
    },
    ...
  ],
}



HTTP REQUEST

GET v3/accounts/historical-leaderboard-pnls/:period

Description: Get an account's historical leaderboard pnls.


REQUEST

Parameter Description period Leaderboard period. "LEAGUES", "DAILY", or
"DAILY_COMPETITION". limit Integer between 1 to 10, which indicates the number
of most recent leaderboard pnls to be returned. By default this value will be
10.


RESPONSE

Parameter Description leaderboardPnls Array of "LeaderboardPnl" from oldest to
most recent. See "LeaderboardPnl" below.


LEADERBOARDPNL

Parameter Description absolutePnl The account's latest updated absolute PNL.
percentPnl The account's latest updated percent PNL. absoluteRank User's
absolute PNL rank. null if not ranked. percentRank User's percent PNL rank. null
if not ranked. startedAt Starting time for this pnl. Note: will only be set if
being used for a competition or leagues. Otherwise, this value will always be
null. endsAt Ending time for this pnl. Note: will only be set if being used for
a competition or leagues. Otherwise, this value will always be null. (Can be a
future time.) updatedAt When these leaderboard PNLs were last updated. accountId
The account the PNLs are for. period Leaderboard period. "LEAGUES", "DAILY", or
"DAILY_COMPETITION". seasonExpectedOutcome User's expected outcome of latest
season. "PROMOTION", "DEMOTION", or "SAME_LEAGUE". null if not "LEAGUES".
seasonNumber Leagues season number. Starts at 1. null if not "LEAGUES".
hedgieWon Index of hedgie won. null if no hedgie won. prizeWon Amount of cash
prize won in dollars. null if no prize won.


GET ACCOUNTS

> Get Account

Copy to Clipboardaccounts = client.private.get_accounts()


Copy to Clipboardconst accounts: { accounts: AccountResponseObject[] } = await client.private.getAccounts();


Copy to Clipboard{ "accounts": [{
    "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
    "positionId": "1812",
    "equity": "10000",
    "freeCollateral": "10000",
    "quoteBalance": "10000",
    "pendingDeposits": "0",
    "pendingWithdrawals": "0",
    "createdAt": "2021-04-09T21:08:34.984Z",
    "openPositions": {
      "BTC-USD": {
        "market": "BTC-USD",
        "status": "OPEN",
        "side": "LONG",
        "size": "1000",
        "maxSize": "1050",
        "entryPrice": "100",
        "exitPrice": null,
        "unrealizedPnl": "50",
        "realizedPnl": "100",
        "createdAt": "2021-01-04T23:44:59.690Z",
        "closedAt": null,
        "netFunding": "500",
        "sumOpen": "1050",
        "sumClose": "50"
      }
    },
    "accountNumber": "5",
    "id": "id"
  }]
}



HTTP REQUEST

GET v3/accounts

Description: Get all accounts for a user.


RESPONSE

Parameter Description accounts See Account. Returns an array of Accounts.


GET POSITIONS

> Get Positions

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD
from dydx3.constants import POSITION_STATUS_OPEN

all_positions = client.private.get_positions(
  market=MARKET_BTC_USD,
  status=POSITION_STATUS_OPEN,
)


Copy to Clipboardconst positions: { positions: PositionResponseObject[] } = await client.private.getPositions(
  {
    market: Market.BTC_USD,
    status: PositionStatus.OPEN,
  },
);


Copy to Clipboard{
  "market": "BTC-USD",
  "status": "OPEN",
  "side": "LONG",
  "size": "1000",
  "maxSize": "1050",
  "entryPrice": "100",
  "exitPrice": null,
  "unrealizedPnl": "50",
  "realizedPnl": "100",
  "createdAt": "2021-01-04T23:44:59.690Z",
  "closedAt": null,
  "netFunding": "500",
  "sumOpen": "1050",
  "sumClose": "50"
}



HTTP REQUEST

GET v3/positions

Description: Get all current positions for a user by specified query parameters.

For each market, a position is created with status=OPEN. A position is set to
status=CLOSED when it goes to market-neutral (i.e. size=0). On a per-market
basis, there should be at most one status=OPEN position at any given time.


REQUEST

Parameter Description market (Optional) Market of the position. status
(Optional) Status of the position. Can be OPEN, CLOSED or LIQUIDATED. limit
(Optional) The maximum number of positions that can be fetched via this request.
Note, this cannot be greater than 100. createdBeforeOrAt (Optional) Set a date
by which the positions had to be created.


RESPONSE

Parameter Description market The market of the position. status The status of
the position. side The side of the position. LONG or SHORT. size The current
size of the position. Positive if long, negative if short, 0 if closed. maxSize
The maximum (absolute value) size of the position. Positive if long, negative if
short. entryPrice Average price paid to enter the position. exitPrice Average
price paid to exit the position. unrealizedPnl The unrealized pnl of the
position in quote currency using the market's index-price for the position to
calculate. realizedPnl The realized pnl of the position in quote currency.
createdAt Timestamp of when the position was opened. closedAt Timestamp of when
the position was closed. netFunding Sum of all funding payments for this
position. sumOpen Sum of all trades sizes that increased the size of this
position. sumClose Sum of all trades sizes that decreased the size of this
position.


GET TRANSFERS

> Get Transfers

Copy to Clipboardfrom dydx3.constants import ACCOUNT_ACTION_DEPOSIT

transfers = client.private.get_transfers(
  transfer_type=ACCOUNT_ACTION_DEPOSIT,
  limit=50,
)


Copy to Clipboardconst transfers: { transfers: TransferResponseObject[] } = await client.private.getTransfers(
  {
    type: AccountAction.DEPOSIT,
    limit: 50,
  },
);


Copy to Clipboard{
  "transfers": [{
    "id": "foo",
    "type": "DEPOSIT",
    "debitAsset": "USDC",
    "creditAsset": "USDT",
    "debitAmount": "3000",
    "creditAmount": "2800",
    "transactionHash": "hash",
    "status": "PENDING",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "confirmedAt": null,
    "clientId": "foo",
    "fromAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "toAddress": null
  }]
}



HTTP REQUEST

GET v3/transfers

Description: Get transfers for a user, limited by query parameters.


REQUEST

Parameter Description transferType (Optional) Type of the transfer. Can be
DEPOSIT, WITHDRAWAL or FAST_WITHDRAWAL. limit (Optional) The maximum number of
transfers that can be fetched via this request. Note, this cannot be greater
than 100. createdBeforeOrAt Latest that the transfers could have been created.


RESPONSE

Parameter Description id Unique id assigned by dYdX. type Type of the transfer.
Will be DEPOSIT, WITHDRAWAL or FAST_WITHDRAWAL. debitAsset Asset that was
debited (USDC, USDT, USD, etc). creditAsset Asset that was credited (USDC, USDT,
USD, etc). debitAmount Amount that was sent in for the deposit in debitAsset.
creditAmount Amount that was credited to the account in creditAsset.
transactionHash Ethereum transaction hash of the transfer. status Status of the
transfer. Will be PENDING or CONFIRMED. createdAt Timestamp when created.
confirmedAt Timestamp when confirmed. clientId ClientId of transfer. fromAddress
The Ethereum address the transfer is from. toAddress The Ethereum address the
transfer is for.


CREATE TRANSFER

> Create Transfer

Copy to Clipboardconst transfers: { transfers: TransferResponseObject[] } = await client.private.createTransfer(
  {
    amount: '50',
    positionId: '12345',
    expiration: '2025-12-28T22:49:31.588Z',
    receiverAccountId: 'id',
    receiverPublicKey: '180913017c740260fea4b2c62828a4008ca8b0d6e4',
    receiverPositionId: '1812',
    clientId: 'clientId0', // Optional
    signature: '0abc12...',  // Optional if stark_private_key was provided to client.
  },
);


Copy to Clipboardtransfer = client.private.create_transfer(
    amount='50',
    position_id='12345',
    expiration='2025-12-28T22:49:31.588Z',
    receiver_account_id='id',
    receiver_public_key='180913017c740260fea4b2c62828a4008ca8b0d6e4',
    receiver_position_id='1812',
    client_id='clientId0', # Optional
    signature='0abc12...',  # Optional if stark_private_key was provided to client.
)


Copy to Clipboard{
  "transfer": {
    "id": "foo",
    "type": "TRANSFER_OUT",
    "debitAsset": "USDC",
    "creditAsset": "USDC",
    "debitAmount": "3000",
    "creditAmount": "0",
    "transactionHash": "hash",
    "status": "PENDING",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "confirmedAt": null,
    "clientId": "foo",
    "fromAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "toAddress": null
  }
}



HTTP REQUEST

POST v3/transfers

Description: Sends a StarkEx L2 transfer.


REQUEST

Parameter Description amount Amount to transfer. clientId Unique id of the
client associated with the transfer. Must be <= 40 characters. When using the
client, if not included, will be randomly generated by the client. expiration
Datetime at which the transfer expires if it has not been completed. Expiration
must be at least seven days in the future. receiverAccountId Account id of the
receiver. signature The signature for the transfer, signed with the account's
STARK private key. Required when using the HTTP API. If not included When using
the client, will be derived from the receiverPublicKey and receiverPositionId.
For more information see above. receiverPublicKey STARK Public key of the
receiver. Ignored when using the HTTP API. receiverPositionId Position id of the
receiver. Ignored when using the HTTP API.


RESPONSE

Parameter Description id Unique id assigned by dYdX. type Type of the transfer.
Will always be TRANSFER_OUT. debitAsset Asset that was debited (currently always
USDC). creditAsset Asset that was credited (currently always USDC). debitAmount
Amount that was sent in the transfer in debitAsset. creditAmount Amount that was
credited to your account in the transfer. Will always be 0. transactionHash
Ethereum transaction hash of the transfer. status Status of the transfer. Will
be PENDING or CONFIRMED. createdAt Timestamp when created. confirmedAt Timestamp
when confirmed. clientId ClientId of transfer. fromAddress The Ethereum address
the transfer is from. toAddress The Ethereum address the transfer is for.


FAST VS. SLOW WITHDRAWAL

The normal process for withdrawing from L2 to L1 requires waiting for a block of
L2 transactions to be collected, and the zero-knowledge proof for the block to
be constructed and verified on-chain.

Using the fast withdrawal process, users can get their funds on L1 much faster
by essentially trading their L2 funds to an “LP” account operated by dYdX, in
order to receive immediate liquidity on L1. Since the LP must then recycle these
funds from L2 to L1 via the regular withdrawal process, dYdX is only able to
process a certain volume of fast withdrawals within a given period of time.


CREATE WITHDRAWAL

> Create Withdrawal

Copy to Clipboardfrom dydx3.constants import ASSET_USDC

withdrawal = client.private.create_withdrawal(
  position_id=1, # required for creating the withdrawal signature
  amount='100',
  asset=ASSET_USDC,
  expiration_epoch_seconds=1613988637,
)


Copy to Clipboardconst withdrawal: { withdrawal: TransferResponseObject } = await client.private.createWithdrawal(
  {
    amount: '100',
    asset: Asset.USDC,
    expiration: '2020-12-28T22:49:31.588Z',
  },
  '1', // positionId required for creating the withdrawal signature
);


Copy to Clipboard{
  "withdrawal": {
    "id": "foo",
    "type": "WITHDRAWAL",
    "debitAsset": "USDC",
    "creditAsset": "USDC",
    "debitAmount": "3000",
    "creditAmount": "2800",
    "transactionHash": "hash",
    "status": "PENDING",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "confirmedAt": null,
    "clientId": "foo",
    "fromAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "toAddress": null
  }
}



HTTP REQUEST

POST v3/withdrawals

Description: Create a withdrawal from an account.

If not withdrawing the entirety of your balance, there is a minimum withdrawal
amount. Currently that amount is 100 USDC.

An additional L1 transaction has to be sent to the Starkware contract to
retrieve funds after a slow withdrawal. This cannot be done until the
zero-knowledge proof for the block has been constructed and verified on-chain.
For the L1 transaction, the Ethereum address that the starkKey is registered to
must call either the withdraw or withdrawTo smart-contract functions. The
contract ABI is not tied to a particular client but can be accessed via a
client. All withdrawable funds are withdrawn at once.

Both Layer 1 withdrawal methods can be accessed from starkex-eth.


REQUEST

Parameter Description amount Amount to be withdrawn. asset Asset being
withdrawn. Can currently only be USDC. expiration Datetime at which the
withdrawal expires if it has not been completed. Expiration must be at least
seven days in the future. clientId Unique id of the client associated with the
withdrawal. Must be <= 40 characters. When using the client, if not included,
will be randomly generated by the client. signature The signature for the
withdrawal, signed with the account's STARK private key. When using the client,
if not included, will be done by the client. For more information see above.


RESPONSE

Parameter Description withdrawal See Transfers.


CREATE FAST WITHDRAWAL

> Create Fast Withdrawal

Copy to Clipboardfrom dydx3.constants import ASSET_USDC

fast_withdrawal = client.private.create_fast_withdrawal(
  position_id='1', # required for creating the fast-withdrawal signature
  credit_asset=ASSET_USDC,
  credit_amount='100',
  debit_amount='110',
  to_address='0x98ab...',
  lp_position_id='2',
  expiration_epoch_seconds=1613988637,
  signature='0abc12...',  # Optional if stark_private_key was provided to client.
)


Copy to Clipboardconst fastWithdrawal: { withdrawal: TransferResponseObject } = await client.private.createFastWithdrawal(
  {
    creditAsset: Asset.USDC,
    creditAmount: '100',
    debitAmount: '110',
    toAddress: '0x98ab...',
    lpPositionId: '2',
    clientId: 'client',
    signature: '0abc12...', // Optional if starkPrivateKey was provided to client.
  },
  '1', // positionId required for creating the fast-withdrawal signature
);


Copy to Clipboard{
  "withdrawal": {
    "id": "foo",
    "type": "FAST_WITHDRAWAL",
    "debitAsset": "USDC",
    "creditAsset": "USDC",
    "debitAmount": "3000",
    "creditAmount": "2800",
    "transactionHash": "hash",
    "status": "PENDING",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "confirmedAt": null,
    "clientId": "foo",
    "fromAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "toAddress": null
  }
}



HTTP REQUEST

POST v3/fast-withdrawals

Description: Create a fast-withdrawal. dYdX article on how fast withdrawals
work.


REQUEST

Parameter Description creditAsset Asset being withdrawn. Can currently only be
USDC. creditAmount Amount that is expected. debitAmount Amount offered in USDC
for the credit amount. slippageTolerance (Optional) Percentage tolerance for
slippage between expectedCredit and creditAmount. Allowed values in the range of
[0, 1]. Defaults to 0.25, ie. up to 25% slippage. toAddress Address to be
credited. lpPositionId LP Position Id of the debit account. expiration Datetime
at which the withdrawal expires if it has not been completed. Expiration must be
at least seven days in the future. signature Signature for the fast-withdrawal,
signed with the account's STARK private key. When using the client, if not
included, will be done by the client. For more information see above. clientId
Unique id of the client associated with the fast-withdrawal. Must be <= 40
characters. When using the client, if not included, will be randomly generated
by the client.

expectedCredit is the result of computing debitAmount - min(gas_fee,
withdrawal_fee), then swapping to creditAsset using 0x.


RESPONSE

Parameter Description withdrawal See Transfers.

Returns 400 unless expectedCredit <= creditAmount <= expectedCredit *
(1-slippageTolerance).


ORDER TYPES

Type Description MARKET Market order (must be FOK or IOC). LIMIT Limit order.
STOP Stop limit order. TRAILING_STOP Trailing stop limit order. TAKE_PROFIT
Trailing stop limit order. LIQUIDATED Indicates the account was liquidated
(fills only). LIQUIDATION Indicates the account took over a liquidated account
(fills only).


CREATE A NEW ORDER

> Create Order

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD
from dydx3.constants import ORDER_SIDE_SELL
from dydx3.constants import ORDER_TYPE_LIMIT
from dydx3.constants import TIME_IN_FORCE_GTT

placed_order = client.private.create_order(
  position_id=1, # required for creating the order signature
  market=MARKET_BTC_USD,
  side=ORDER_SIDE_SELL,
  order_type=ORDER_TYPE_LIMIT,
  post_only=False,
  size='100',
  price='18000',
  limit_fee='0.015',
  expiration_epoch_seconds=1613988637,
  time_in_force=TIME_IN_FORCE_GTT,
)


Copy to Clipboardconst order: { order: OrderResponseObject } = await client.private.createOrder(
  {
    side: OrderSide.SELL,
    type: OrderType.LIMIT,
    timeInForce: TimeInForce.GTT,
    postOnly: false,
    size: '100',
    price: '18000',
    limitFee: '0.015',
    expiration: '2022-12-21T21:30:20.200Z',
  },
  '1', // required for creating the order signature
);


Copy to Clipboard{
  "order": {
    "id": "foo",
    "clientId": "foo",
    "accountId": "afoo",
    "market": "BTC-USD",
    "side": "SELL",
    "price": "18000",
    "triggerPrice": null,
    "trailingPercent": null,
    "size": "100",
    "remainingSize": "100",
    "type": "LIMIT",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "unfillableAt": null,
    "expiresAt": "2022-12-21T21:30:20.200Z",
    "status": "PENDING",
    "timeInForce": "GTT",
    "postOnly": false,
    "reduceOnly": false,
    "cancelReason": null
  }
}



HTTP REQUEST

POST v3/orders

Description: Create a new order.


REQUEST

Parameter Description market Market of the order. side Either BUY or SELL. type
The type of order. This can be MARKET, LIMIT, STOP_LIMIT, TRAILING_STOP or
TAKE_PROFIT. postOnly Whether the order should be canceled if it would fill
immediately on reaching the matching-engine. size Size of the order, in base
currency (i.e. an ETH-USD position of size 1 represents 1 ETH). price Worst
accepted price of the base asset in USD. limitFee Is the highest accepted fee
for the trade. See below for more information. expiration Time at which the
order will expire if not filled. This is the Good-Til-Time and is accurate to a
granularity of about 15 seconds. timeInForce (Optional) One of GTT (Good til
time), FOK(Fill or kill) or IOC (Immediate or cancel). This will default to GTT.
cancelId (Optional) The id of the order that is being replaced by this one.
triggerPrice (Optional) The triggerPrice at which this order will go to the
matching-engine. trailingPercent (Optional) The percent that the triggerPrice
trails the index price of the market. reduceOnly (Optional) Whether the order
should be reduce-only. Only supported on FOK(Fill or kill) or IOC (Immediate or
cancel) orders. clientId Unique id of the client associated with the order. Must
be <= 40 characters. When using the client, if not included, will be randomly
generated by the client. signature Signature for the order, signed with the
account's STARK private key. When using the client, if not included, will be
done by the client. For more information see above.

Specifying cancelId will cause the order matching cancelId to be canceled
**atomically** (and immediately before) with the new order being placed. This
can be used to always have available liquidity on the book when market making.
The new order will still be placed even if the old order was already filled.


RESPONSE

Parameter Description order See order.


ORDER LIMITFEE

The limitFee is the highest fee a user would be willing to accept on an order.
This should be in decimal form (i.e. 0.1 is 10%). To see current fees, call GET
/v3/users and the maker/taker fee rates show what fees will be. If the order is
postOnly dYdX will validate against makerFeeRate only. The opposite is true if
the order is FOK or IOC - dYdX will only validate against takerFeeRate.
Otherwise, dYdX assesses against the maximum of maker and taker fee rate.


TICK SIZE AND MINIMUM SIZE


TICK SIZE

Each market has a specified tickSize. Order price must be a multiple of the
tickSize. The same applies to triggerPrice and trailingPercent if either of
these are not null.


MINIMUM SIZE

Each market has a specified minOrderSize. Order size must be not be less than
the minOrderSize.


ORDER DELETION

Canceled orders older than one month are deleted from the dYdX database.


REDUCE ONLY

A reduce-only order can only reduce an existing position.

 * When user holds no open position, a reduce-only order will always be
   rejected.
 * When user holds an open position, a reduce-only order can only be placed on
   the other side of the book, with size smaller or equal to the existing
   position size.

The reduce-only option can be combined with any order type (Limit, Market, Stop
Loss, Take Profit, Trailing Stop), but is only available for taker orders
(Immediate-or-Cancel and Fill-or-Kill).

UNTRIGGERED reduce-only orders are either resized or canceled (with cancel
reason REDUCE_ONLY_RESIZED) if the underlying position shrinks or no longer
exists. When there are multiple UNTRIGGERED reduce-only orders and the total
order size exceeds the existing position, they will be resized/canceled starting
from the order that will be filled last.


CANCEL AN ORDER

> Cancel an order

Copy to Clipboardclient.private.cancel_order(order_id='0x0000')


Copy to Clipboardawait client.private.cancelOrder('0x0000');


Copy to Clipboard{}



HTTP REQUEST

DELETE v3/orders/:id

Description: Cancel an order by its unique id.


REQUEST

Parameter Description orderId Unique id of the order to be canceled.


RESPONSE

The endpoint returns with status code 200 once the order has been queued for
cancelation. The order's status will be updated after the cancelation has been
processed by the matching engine.

Parameter Description cancelOrder See order.


CANCEL ORDERS

> Cancel Orders

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

client.private.cancel_all_orders(market=MARKET_BTC_USD)


Copy to Clipboardawait client.private.cancelAllOrders(Market.BTC_USD);


Copy to Clipboard{}



HTTP REQUEST

DELETE v3/orders

Description: Either bulk cancel all orders or just all orders for a specific
market.


REQUEST

Parameter Description market (Optional) Market of the orders being canceled.


RESPONSE

The endpoint returns with status code 200 once the orders have been queued for
cancelation. The orders' statuses will be updated after the cancelations have
been processed by the matching engine.

Parameter Description cancelOrders Returns an array of orders to be canceled.
See order.


CANCEL ACTIVE ORDERS

> Cancel Active Orders

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD
from dydx3.constants import ORDER_SIDE_SELL

market_side_orders = client.private.cancel_active_orders(
  market=MARKET_BTC_USD,
  side=ORDER_SIDE_SELL,
)


Copy to Clipboardconst marketSideOrders: {
  cancelOrders: ActiveOrderResponseObject[],
} = await client.private.cancelActiveOrders(
  {
    market: Market.BTC_USD,
    side: OrderSide.SELL,
  },
);


Copy to Clipboard{
  "cancelOrders": [
    {
      "id": "id",
      "accountId": "afoo",
      "market": "BTC-USD",
      "side": "SELL",
      "price": "29000",
      "remainingSize": "0.500",
    },
    ...
  ]
}



HTTP REQUEST

DELETE v3/active-orders

Description: Cancel active orders that match request parameters.

Note that rate-limiting is more generous for this endpoint than DELETE
v3/orders. When including side, the rate-limiting becomes even more permissive
and when id is included as well as side, the rate-limiting is its most
permissive.


REQUEST

Parameter Description market Market of the order. side (Optional) Either BUY or
SELL. This parameter is required if id is included. id (Optional) The unique id
assigned by dYdX. Note, if id is not found, will return a 400.


RESPONSE

The endpoint returns with status code 200 once the orders have been queued for
cancelation. The orders' statuses will be updated after the cancelations have
been processed by the matching engine.

Parameter Description cancelOrders Returns an array of active orders to be
canceled. See activeOrder.


GET ORDERS

> Get Orders

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD
from dydx3.constants import ORDER_SIDE_SELL
from dydx3.constants import ORDER_TYPE_LIMIT
from dydx3.constants import ORDER_STATUS_OPEN

all_orders = client.private.get_orders(
  market=MARKET_BTC_USD,
  status=ORDER_STATUS_OPEN,
  side=ORDER_SIDE_SELL,
  type=ORDER_TYPE_LIMIT,
  limit=50,
)


Copy to Clipboardconst allOrders: { orders: OrderResponseObject[] } = await client.private.getOrders(
  {
    market: Market.BTC_USD,
    status: OrderStatus.OPEN,
    side: OrderSide.SELL,
    type: OrderType.LIMIT,
    limit: 50,
  },
);


Copy to Clipboard{
  "orders": [
    {
      "id": "id",
      "clientId": "foo",
      "accountId": "afoo",
      "market": "BTC-USD",
      "side": "SELL",
      "price": "29000",
      "triggerPrice": null,
      "trailingPercent": null,
      "size": "0.500",
      "remainingSize": "0.500",
      "type": "LIMIT",
      "createdAt": "2021-01-04T23:44:59.690Z",
      "unfillableAt": null,
      "expiresAt": "2021-02-04T23:44:59.690Z",
      "status": "OPEN",
      "timeInForce": "GTT",
      "postOnly": false,
      "cancelReason": null
    },
    ...
  ]
}



HTTP REQUEST

GET v3/orders

Description: Get active (not filled or canceled) orders for a user by specified
parameters.


REQUEST

Parameter Description market (Optional) Market of the order. status (Optional) A
list of statuses to filter by. Must be in the subset PENDING side (Optional)
Either BUY or SELL. type (Optional) The expected type of the order. This can be
LIMIT, STOP, TRAILING_STOP or TAKE_PROFIT. limit (Optional) The maximum number
of orders that can be fetched via this request. Note, this cannot be greater
than 100. createdBeforeOrAt (Optional) Set a date by which the orders had to be
created. returnLatestOrders (Optional) Returns the most recently created orders
instead of the oldest and the order is from most recent to least recent (up to
limit).


RESPONSE

Parameter Description orders An array of orders. See order below.


ORDER

Parameter Description id The unique id assigned by dYdX. clientId The unique id
assigned by the client. accountId The id of the account. market Market of the
fill. side Either BUY or SELL. price The price of the order. Must adhere to the
market's tick size. triggerPrice The trigger price of the order. Must adhere to
the market's tick size. trailingPercent Used for trailing stops. Percent drop
from maximum price that will trigger the order. size Total size (base currency)
of the order remainingSize Size of order not yet filled. type The type of the
fill. createdAt Timestamp when the fill was created. unfillableAt Time order was
either filled or canceled. expiresAt Time order will expire. status See order
statuses below. timeInForce One of GTT (Good til time), FOK(Fill or kill) or IOC
(Immediate or cancel). This will default to GTT. postOnly If the order will
cancel if it would take the position of TAKER. cancelReason See cancel reasons
below.


ORDER STATUSES

Status Description PENDING Order has yet to be processed by the matching engine.
OPEN Order is active and on the orderbook. Could be partially filled. FILLED
Fully filled. CANCELED Canceled, for one of the cancel reasons. Could be
partially filled. UNTRIGGERED Triggerable order that has not yet been triggered.


CANCEL REASONS

Reason Description UNDERCOLLATERALIZED Order would have led to an
undercollateralized state for the user. EXPIRED Order expired. USER_CANCELED
Order was canceled by the user. SELF_TRADE Order would have resulted in a self
trade for the user. FAILED An internal issue caused the order to be canceled.
COULD_NOT_FILL A FOK or IOC order could not be fully filled.
POST_ONLY_WOULD_CROSS A post-only order would cross the orderbook.


GET ACTIVE ORDERS

> Get Active Orders

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD
from dydx3.constants import ORDER_SIDE_SELL

market_side_orders = client.private.get_active_orders(
  market=MARKET_BTC_USD,
  side=ORDER_SIDE_SELL,
)


Copy to Clipboardconst marketSideOrders: {
  orders: ActiveOrderResponseObject[],
} = await client.private.getActiveOrders(
  {
    market: Market.BTC_USD,
    side: OrderSide.SELL,
  },
);


Copy to Clipboard{
  "orders": [
    {
      "id": "id",
      "accountId": "afoo",
      "market": "BTC-USD",
      "side": "SELL",
      "price": "29000",
      "remainingSize": "0.500",
    },
    ...
  ]
}



HTTP REQUEST

GET v3/active-orders

Description: Get active (not filled or canceled) orders for a user by specified
parameters.

Note that rate-limiting is more generous for this endpoint than GET v3/orders.
When including side, the rate-limiting becomes even more permissive and when id
is included as well as side, the rate-limiting is its most permissive.


REQUEST

Parameter Description market Market of the order. side (Optional) Either BUY or
SELL. This parameter is required if id is included. id (Optional) The unique id
assigned by dYdX. Note, if id is not found, will return a 400.


RESPONSE

Parameter Description orders An array of activeOrders. See activeOrder below.


ACTIVEORDER

Parameter Description id The unique id assigned by dYdX. accountId The id of the
account. market Market of the fill. side Either BUY or SELL. price The price of
the order. Must adhere to the market's tick size. remainingSize Size of order
not yet filled.


GET ORDER BY ID

> Get Order By Id

Copy to Clipboardorder = client.private.get_order_by_id('foo')


Copy to Clipboardconst orderResponse: { order: OrderResponseObject } = await client.private.getOrderById('foo');


Copy to Clipboard{
  "order": {
    "id": "foo",
    "clientId": "foo",
    "accountId": "afoo",
    "market": "BTC-USD",
    "side": "SELL",
    "price": "29000",
    "triggerPrice": null,
    "trailingPercent": null,
    "size": "0.500",
    "remainingSize": "0.500",
    "type": "LIMIT",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "unfillableAt": null,
    "expiresAt": "2021-02-04T23:44:59.690Z",
    "status": "OPEN",
    "timeInForce": "GTT",
    "postOnly": false,
    "cancelReason": null
  }
}



HTTP REQUEST

GET v3/orders/:id

Description: Get an order by id from the active orderbook and order history.


REQUEST

Parameter Description id Unique id of the order


RESPONSE

Parameter Description order See order.


GET ORDER BY CLIENTID

> Get Order By ClientId

Copy to Clipboardorder = client.private.get_order_by_client_id('clientId')


Copy to Clipboardconst allOrders: { order: OrderResponseObject } = await client.private.getOrderByClientId('clientId');


Copy to Clipboard{
  "order": {
    "id": "foo",
    "clientId": "foo",
    "accountId": "afoo",
    "market": "BTC-USD",
    "side": "SELL",
    "price": "29000",
    "triggerPrice": null,
    "trailingPercent": null,
    "size": "0.500",
    "remainingSize": "0.500",
    "type": "LIMIT",
    "createdAt": "2021-01-04T23:44:59.690Z",
    "unfillableAt": null,
    "expiresAt": "2021-02-04T23:44:59.690Z",
    "status": "OPEN",
    "timeInForce": "GTT",
    "postOnly": false,
    "cancelReason": null
  }
}



HTTP REQUEST

GET v3/orders/client/:id

Description: Get an order by clientId from the active orderbook and order
history. Only the latest 1 hour of orders can be fetched from this endpoint.


REQUEST

Parameter Description id Unique clientId of the order


RESPONSE

Parameter Description order See order.


GET FILLS

> Get Fills

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

all_fills = client.private.get_fills(
  market=MARKET_BTC_USD,
)


Copy to Clipboardconst allFills: { fills: FillResponseObject[] } = await client.private.getFills(
  {
    market: Market.BTC_USD,
  },
);


Copy to Clipboard{
  "fills": [
    {
      "id": "foo",
      "side": "BUY",
      "liquidity": "TAKER",
      "type": "LIMIT",
      "market": "BTC-USD",
      "orderId": "id",
      "price": "29000",
      "size": "0.001",
      "fee": "100",
      "createdAt": "2021-01-05T16:33:43.163Z"
    },
    ...
  ]
}



HTTP REQUEST

GET v3/fills

Description: Get Fills for a user by specified parameters.


REQUEST

Parameter Description market (Optional) Market of the fills. orderId (Optional)
Unique order id. Will only fetch a single order. limit (Optional) The maximum
number of fills that can be fetched via this request. Note, this cannot be
greater than 100. createdBeforeOrAt (Optional) Set a date by which the fills had
to be created.


RESPONSE

Parameter Description fills Array of fills. See below for an individual example.


FILL

Parameter Description id The unique id assigned by dYdX. side Either BUY or
SELL. liquidity Either MAKER or TAKER. type The type of the fill. market Market
of the fill. orderId Id of the order which caused this fill. null if type is
LIQUIDATED or LIQUIDATION`. price The price the fill occurred at (in quote /
base currency). size Size that was filled (in base currency). fee Fee that was
charged (in quote currency). createdAt Timestamp when the fill was created.


GET FUNDING PAYMENTS

> Get Funding Payments

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

funding_payments = client.private.get_funding_payments(
  market=MARKET_BTC_USD,
  limit=75,
)


Copy to Clipboardconst fundingPayments: { fundingPayments: FundingResponseObject } = await client.private.getFundingPayments(
  {
    market: Market.BTC_USD,
    limit: 75,
  },
);


Copy to Clipboard{
  "fundingPayments": [{
    "market": "BTC-USD",
    "payment": "10000",
    "rate": "0.0000125000",
    "positionSize": "500",
    "price": "90",
    "effectiveAt": "2021-01-04T23:44:59.690Z"
  }]
}



HTTP REQUEST

GET v3/funding

Description: Get Funding Payments made to an account.


REQUEST

Parameter Description market (Optional) Market of the funding payments. limit
(Optional) The maximum number of funding payments that can be fetched via this
request. Note, this cannot be greater than 100. effectiveBeforeOrAt (Optional)
Set a date by which the funding payments had to be created.


RESPONSE

Parameter Description market Market corresponding to the funding payment.
payment Change in the quoteBalance of the account. Positive if the user received
funding and negative if the user paid funding. rate Funding rate at the time of
this payment (as a 1-hour rate). positionSize User's position size at the time
of this funding payment. positive if long, negative if short. price Oracle price
used to calculate this funding payment. effectiveAt Time of this funding
payment.


GET HISTORICAL PNL TICKS

> Get Historical PNL Ticks

Copy to Clipboardhistorical_pnl = client.private.get_historical_pnl(
  created_before_or_at='2021-04-09T22:02:46+0000',
)


Copy to Clipboardconst historicalPnlTicks: {
  historicalPnl: HistoricalPnlResponseObject[],
} = await client.private.getHistoricalPnl(
  {
    createdBeforeOrAt: '2021-04-09T22:02:46+0000',
  },
);


Copy to Clipboard{
  "historicalPnl": [{
    "equity": "0.0000",
    "totalPnl": "0.0000",
    "createdAt": "2021-04-09T21:08:34.984Z",
    "netTransfers": "0.0000",
    "accountId": "49979004..."
  }]
}



HTTP REQUEST

GET v3/historical-pnl

Description: Get Historical PNL for an account during an interval.

The max interval of ticks is 1 month. If a single time value is provided, the
other value will default to one month away from said value (i.e. set
createdBeforeOrAt and createdOnOrAfter will be a month before). If neither value
is set, the interval will be the current past roughly 30 days.


REQUEST

Parameter Description effectiveBeforeOrAt (Optional) Used for setting a ending
bounds on the ticks. effectiveAtOrAfter (Optional) Used for setting a starting
bounds on the ticks.


RESPONSE

Parameter Description historicalPnl Array of HistoricalAggregatedPnl. See
"HistoricalAggregatedPnl" below.


HISTORICALAGGREGATEDPNL

Parameter Description equity The total account equity. totalPnl The total PNL
for the account since inception. createdAt When the tick was recorded.
netTransfers The value into or out of the account of transfers since the last
interval. accountId Account the tick is for.


GET TRADING REWARDS

> Get Trading Rewards

Copy to Clipboardrewards = client.private.get_trading_rewards(
  epoch=0,
)


Copy to Clipboardconst rewards: {
  tradingRewards: TradingRewardsResponseObject,
} = await client.private.getTradingRewards(
  {
    epoch: 5,
  },
);


Copy to Clipboard{
  "epoch": 5,
  "epochStart": "2021-12-21T15:00:00.000Z",
  "epochEnd": "2022-01-18T15:00:00.000Z",
  "fees": {
    "feesPaid": "0.1",
    "totalFeesPaid": "1"
  },
  "openInterest": {
    "averageOpenInterest": "10",
    "totalAverageOpenInterest": "100"
  },
  "stakedDYDX": {
    "primaryStakedDYDX": "0",
    "averageStakedDYDX": "200",
    "averageStakedDYDXWithFloor": "200",
    "totalAverageStakedDYDX": "2000"
  },
  "weight": {
    "weight": "0.1",
    "totalWeight": "1"
  },
  "totalRewards": "383561.6",
  "estimatedRewards": "3835616"
}



HTTP REQUEST

GET v3/rewards/weight

Description: Get the rewards weight of a given epoch.


REQUEST

Parameter Description epoch (Optional) Epoch number to request rewards data for.
Defaults to current epoch. secondaryAddress (Optional) Get rewards for a linked,
SECONDARY address.


RESPONSE

Parameter Description epoch ID of the epoch. epochStart Time when the epoch
starts. epochEnd Time when the epoch ends. fees See "Fees" below. openInterest
See "OpenInterest" below. weight See "Weight" below. stakedDYDX See "StakedDYDX"
below. totalRewards The total number of tokens that will be given out at the end
of the epoch. estimatedRewards The user's estimated number of dYdX tokens as
rewards.


WEIGHT

Parameter Description weight The user's current weight score for this epoch.
totalWeight The sum of the weight score of all users for this epoch.


FEES

Parameter Description feesPaid The USD amount of fees paid by the user in the
epoch. totalFeesPaid The total USD amount of fees paid by all users in the
epoch.


OPENINTEREST

Parameter Description averageOpenInterest The average open interest for the
user. totalAverageOpenInterest The total average open interest for all users.


STAKEDDYDX

Parameter Description primaryStakedDYDX The average staked DYDX of the primary
user if own user linkType = SECONDARY or secondaryAddress is included. '0' for
epochs 0-4 (old rewards formula). null otherwise. averageStakedDYDX The average
staked DYDX for the user. This value is '0' for epochs 0-4 (old rewards formula
does not take into account stakedDYDX). averageStakedDYDXWithFloor The average
staked DYDX for the user, taking into account both primaryStakedDYDX and the
rewards formula's floor stakedDYDX value. This value is '0' for epochs 0-4 (old
rewards formula does not take into account stakedDYDX). totalAverageStakedDYDX
The total average staked DYDX for all users. This value is '0' for epochs 0-4
(old rewards formula does not take into account stakedDYDX).


GET LIQUIDITY PROVIDER REWARDS

> Get Liquidity Provider Rewards

This API is only supported for epochs 13+. For previous epochs, please use the
`Get Liquidity Rewards` endpoint.
Copy to Clipboardrewards = client.private.get_liquidity_provider_rewards_v2(
  epoch=13,
)


Copy to Clipboardconst rewards: {
  liquidityRewards: LiquidityProviderRewardsV2ResponseObject,
} = await client.private.getLiquidityProviderRewardsV2(
  {
    epoch: 13,
  },
);


Copy to Clipboard{
  "epoch": 13,
  "epochStart": "2021-8-02T15:00:00.000Z",
  "epochEnd": "2022-08-30T15:00:00.000Z",
  "markets": {
    "BTC-USD": {
      "market": "BTC-USD",
      "depthSpreadScore": "0.5",
      "uptime": "500",
      "linkedUptime": "7500",
      "maxUptime": "10000",
      "score": "0.00098821176880261854125",
      "totalScore": "1",
      "makerVolume": "10000",
      "totalMakerVolume": "100000",
      "totalRewards": "230137",
      "estimatedRewards": "227.42409183692822322765125",
      "secondaryAllocation": "0"
    }
    ...
  },
  "stakedDYDX": {
    "averageStakedDYDX": "1000",
    "totalAverageStakedDYDX": "10000"
  },
  "linkedAddressRewards": {
    "0x0913017c740260fea4b2c62828a4008ca8b0d6e4": {
      "markets": {
        "BTC-USD": {
          "market": "BTC-USD",
          "depthSpreadScore": "0.5",
          "uptime": "500",
          "linkedUptime": "7500",
          "maxUptime": "10000",
          "score": "0.00098821176880261854125",
          "totalScore": "1",
          "makerVolume": "10000",
          "totalMakerVolume": "100000",
          "totalRewards": "230137",
          "estimatedRewards": "227.42409183692822322765125",
          "secondaryAllocation": "0.5"
        }
        ...
      },
      "averageStakedDYDX": "750"
    }
  }
}



HTTP REQUEST

GET v3/rewards/liquidity-provider

Description: Get the liquidity provider rewards of a given epoch (epochs 13+).


REQUEST

Parameter Description epoch (Optional) Epoch number to request rewards data for.
Defaults to current epoch.


RESPONSE

Parameter Description epoch ID of the epoch. epochStart Time when the epoch
starts. epochEnd Time when the epoch ends. markets Map of market name to
liquidity rewards for that market. See "LiquidityRewards" below. stakedDYDX See
"StakedDYDX" below. linkedAddressRewards For a PRIMARY address, map of linked
address to rewards data for that address. Includes the PRIMARY address. See
"PerAddressRewards" below.


LIQUIDITYREWARDS

Parameter Description market The market for which the rewards are for.
depthSpreadScore The user's depth and spread score for this market. uptime The
ratio of uptime (non-zero scores) that the user has for this market.
linkedUptime For a SECONDARY address, the max uptime of linked addresses, which
will be used in rewards calculation. 0 otherwise. maxUptime The number of
samples taken for this market. score The user's total score for this market.
totalScore The total score of all liquidity providers who are eligible for
liquidity rewards. makerVolume The maker volume for the user. totalMakerVolume
The total maker volume for all liquidity providers. estimatedRewards The user's
estimated number of dYdX tokens as rewards for this market. For a SECONDARY
address, this field is the amount of rewards contributed to the PRIMARY address
(SECONDARY addresses do not receive rewards). totalRewards The total number of
tokens that will be given out at the end of the epoch for this market.
secondaryAllocation For a SECONDARY address, the proportion (0 to 1) of the
PRIMARY address rewards that are based on this address contribution. 0
otherwise.


STAKEDDYDX

Parameter Description averageStakedDYDX The average staked DYDX for the user.
For a PRIMARY address, this is the aggregate averageStakedDYDX across all linked
addresses. totalAverageStakedDYDX The total average staked DYDX for all eligible
users.


PERADDRESSREWARDS

Parameter Description markets Map of market name to liquidity rewards for that
market for the respective address. See "LiquidityRewards" above.
averageStakedDYDX The average staked DYDX for the respective address.


GET LIQUIDITY REWARDS (DEPRECATED)

> Get Liquidity Rewards

This API is now deprecated. Please use it to fetch rewards for only epoch 0-12.
For future epochs, please use the `Get Liquidity Provider Rewards` endpoint.
Copy to Clipboardrewards = client.private.get_liquidity_provider_rewards(
  epoch=0,
)


Copy to Clipboardconst rewards: {
  liquidityRewards: LiquidityProviderRewardsResponseObject,
} = await client.private.getLiquidityProviderRewards(
  {
    epoch: 5,
  },
);


Copy to Clipboard{
  "epoch": 5,
  "epochStart": "2021-12-21T15:00:00.000Z",
  "epochEnd": "2022-01-18T15:00:00.000Z",
  "markets": {
    "BTC-USD": {
      "market": "BTC-USD",
      "uptime": "0.5",
      "score": "0.00098821176880261854125",
      "totalScore": "1",
      "totalRewards": "230137",
      "estimatedRewards": "227.42409183692822322765125",
    }
    ...
  },
  "stakedDYDX": {
    "primaryStakedDYDX": "0",
    "averageStakedDYDX": "1000",
    "totalAverageStakedDYDX": "10000"
  }
}



HTTP REQUEST

GET v3/rewards/liquidity

Description: Get the liquidity rewards of a given epoch.


REQUEST

Parameter Description epoch (Optional) Epoch number to request rewards data for.
Defaults to current epoch. secondaryAddress (Optional) Get rewards for a linked,
SECONDARY address.


RESPONSE

Parameter Description epoch ID of the epoch. epochStart Time when the epoch
starts. epochEnd Time when the epoch ends. markets Map of market name to rewards
for that market. See "LiquidityRewards" below. stakedDYDX See "StakedDYDX"
below.


LIQUIDITYREWARDS

Parameter Description market The market for which the rewards are for.
depthSpreadScore The user's depth and spread score for this market. uptime The
ratio of uptime (non-zero scores) that the user has for this market. maxUptime
The number of samples taken for this market. score The user's total score for
this market. totalScore The total score of all liquidity providers who are
eligible for liquidity rewards. makerVolume The maker volume for the user. 0 for
epochs 0-9 (old rewards formulas). totalMakerVolume The total maker volume for
all liquidity providers. 0 for epochs 0-4 (old rewards formula). totalRewards
The total number of tokens that will be given out at the end of the epoch for
this market. estimatedRewards The user's estimated number of dYdX tokens as
rewards for this market.


STAKEDDYDX

Parameter Description primaryStakedDYDX The average staked DYDX of the primary
user if own user linkType = SECONDARY or if secondaryAddress is included. '0'
for epochs 0-4 (old rewards formula). null otherwise. averageStakedDYDX The
average staked DYDX for the user. This value is '0' for epochs 0-4 (old rewards
formula does not take into account stakedDYDX). totalAverageStakedDYDX The total
average staked DYDX for all eligible users. This value is '0' for epochs 0-4
(old rewards formula does not take into account stakedDYDX).


GET RETROACTIVE MINING REWARDS

> Get Retroactive Mining Rewards

Copy to Clipboardrewards = client.private.get_retroactive_mining_rewards()


Copy to Clipboardconst rewards: {
  retroactiveMiningRewards: RetroactiveMiningRewardsResponseObject,
} = await client.private.getRetroactiveMiningRewards();


Copy to Clipboard{
  "epoch": 0,
  "epochStart": "2021-08-03T15:00:00.000Z",
  "epochEnd": "2021-08-31T15:00:00.000Z",
  "retroactiveMining": {
    "allocation": "1000",
    "targetVolume": "500",
    "volume": "100"
  },
  "estimatedRewards": "500"
}



HTTP REQUEST

GET v3/rewards/retroactive-mining

Description: Get the retroactive mining rewards of a given epoch.


RESPONSE

Parameter Description epoch Will always be '0'. epochStart Time when the epoch
starts. epochEnd Time when the epoch ends. retroactiveMining See
"RetroactiveMiningRewards" below. estimatedRewards The user's estimated number
of dYdX tokens as rewards.


RETROACTIVEMININGREWARDS

Parameter Description allocation The number of allocated dYdX tokens for the
user. targetVolume The user's required trade volume (in USD) to be able to claim
the allocation. volume The user's current total trade volume (in USD) in the
epoch.


SEND VERIFICATION EMAIL

> Send a verification email

Copy to Clipboardclient.private.send_verification_email()


Copy to Clipboardawait client.private.sendVerificationEmail();


Copy to Clipboard{}



HTTP REQUEST

PUT v3/emails/send-verification-email

Description: Send an email to the email address associated with the user,
requesting that they click on a link to verify their email address.


RESPONSE

On success, returns a 204 response with an empty body. Responds with a 400 error
if no email address is on file for the user, or their email address has already
been verified.


SETTING NOTIFICATION STATUS

In addition to verifying an email, notifications must be set in user.userData to
start receiving emails per category.

> Example userData:

Copy to Clipboarduser.userData = {
  notifications: {
    deposit: {
      email: true
    },
    trades: {
      email: true
    }
  }
}



REQUEST TESTNET TOKENS

> Request Testnet Tokens

Copy to Clipboardtransfer = client.private.request_testnet_tokens()


Copy to Clipboardconst transfer: { transfer: TransferResponseObject } = await client.private.requestTestnetTokens();


Copy to Clipboard{
    "transfer": {
        "id": "e5ed0207-27fe-5cfa-a74e-b3908a113dca",
        "type": "TRANSFER_OUT",
        "debitAsset": "USDC",
        "creditAsset": "USDC",
        "debitAmount": "10000",
        "creditAmount": "0",
        "transactionHash": null,
        "status": "PENDING",
        "createdAt": "2021-11-09T01:29:59.960Z",
        "confirmedAt": null,
        "clientId": "521ba97550e9299",
        "fromAddress": null,
        "toAddress": null
    }
}



HTTP REQUEST

POST v3/testnet/tokens

Description: Requests tokens on dYdX's staging server.

This endpoint is only enabled on Staging/Goerli, and will not work on
Mainnet/Production.

A fixed number of tokens will be transferred to the account. Please take note of
rate limits.

Accounts with high equity that request tokens will have their requests denied.


RESPONSE

Parameter Description transfer See Transfers.


GET PRIVATE PROFILE

Get private profile data for the user. This is a superset of the
/v3/profile/:publicId endpoint.

Copy to Clipboardprofile_private = client.private.get_profile()


Copy to Clipboardconst profilePrivate: ProfilePrivateResponseObject = await client.private.getProfilePrivate();


Copy to Clipboard{
    "username": "foo",
    "ethereumAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "DYDXHoldings": "250",
    "stakedDYDXHoldings": "250",
    "hedgiesHeld": [111],
    "twitterHandle": "bar",
    "affiliateLinks": [{
        "link": "mrAffiliate",
        "discountRate": "0.95",
    }],
    "affiliateApplicationStatus": "APPROVED",
    "publicId": "ABCDEFGH",
    "tradingLeagues": {
        "currentLeague": "SILVER",
        "currentLeagueRanking": 12,
    },
    "tradingPnls": {
        "absolutePnl30D": "324",
        "percentPnl30D": "25",
        "volume30D": "4000",
    },
    "tradingRewards": {
        "curEpoch": "8",
        "curEpochEstimatedRewards": 280,
        "prevEpochEstimatedRewards": 125,
    },
    "affiliateStatistics": {
        "currentEpoch": {
            "usersReferred": "12",
            "revenue": "12.50",
            "revenueShareRate": "0.24",
        },
        "previousEpochs": {
            "usersReferred": "20",
            "revenue": "1427.30",
        },
        "lastPaidEpoch": "9",
    }
}



HTTP REQUEST

GET v3/profile/private

Description: Get private profile data for the user.


RESPONSE

Parameter Description username Publically-displayed username. publicId User's
public id used in the public profile endpoint ethereumAddress User's associated
ethereum address. DYDXHoldings The user's DYDX token holdings. null if not
sharing ethereum address. stakedDYDXHoldings The user's stkDYDX token holdings.
null if not sharing ethereum address. hedgiesHeld Indices of all Hedgies held.
twitterHandle The username that appears at the end of a unique Twitter url.
affiliateLinks The affiliate links that the user can share and earn revenue on.
[] if the user is not an affiliate. See "AffiliateLinkData" below.
affiliateApplicationStatus The status of the affiliate application, can be
APPROVED, PENDING, REJECTED, and REJECTED_AND_BANNED. null if no affiliate
application had been submitted. tradingLeagues See "TradingLeagues" below.
tradingPnls See "TradingPnls" below. tradingRewards See "TradingRewards" below.
affiliateStatistics See "AffiliateStatistics" below.


AFFILIATELINKDATA

Parameter Description link The affiliate link. Ex: mrAffiliate in affiliate link
trade.dydx.exchange/r/mrAffiliate. discountRate The discount rate used to
calculate the referred user's fee. Ex: 0.95 would mean that users get a 5%
discount to their fees.


TRADINGLEAGUES

Parameter Description currentLeague null, "BRONZE", "SILVER", "GOLD",
"PLATINUM", or "DIAMOND". currentLeagueRanking null, or positive integer
ranking.


TRADINGPNLS

Parameter Description absolutePnl30D null, or user's 30 day absolute pnl (based
on leaderboard formula). percentPnl30D null, or user's 30 day percent pnl (based
on leaderboard formula). volume30D The sum of a user's 30 day maker and taker
trading volume.


TRADINGREWARDS

Parameter Description curEpoch Current epoch number. curEpochEstimatedRewards
The user's estimated number of dYdX tokens as rewards for the current epoch.
prevEpochEstimatedRewards The user's estimated number of dYdX tokens as rewards
for the previous epoch.


AFFILIATESTATISTICS

Parameter Description currentEpoch See "CurrentEpochAffiliateStatistics" below.
previousEpochs See "PreviousEpochAffiliateStatistics" below. lastEpochPaid The
last epoch that has been paid out to affiliates.


CURRENTEPOCHAFFILIATESTATISTICS

Parameter Description usersReferred Total number of users referred by this
affiliate in this epoch. revenue Expected current affiliate payout in this
epoch. revenueShareRate Current revenue share rate for the user depending on
their $stkDYDX and if manual override is enabled for the user. Will be a number
between 0 and 1 inclusive, 0.1 would indicate that the affiliate will receive
10% of all net revenue generated by their referred users.


PREVIOUSEPOCHSAFFILIATESTATISTICS

Parameter Description usersReferred Total number of users referred by this
affiliate in all previous epochs. revenue Total amount of revenue this user has
earned in all previous epochs.


PUBLIC HTTP API


GET MARKETS

> Get Markets

Copy to Clipboardmarkets = client.public.get_markets()


Copy to Clipboardconst markets: { markets: MarketsResponseObject } = await client.public.getMarkets();


Copy to Clipboard{
  "markets": {
    "LINK-USD": {
    "market": "LINK-USD",
    "status": "ONLINE",
    "baseAsset": "LINK",
    "quoteAsset": "USD",
    "stepSize": "0.1",
    "tickSize": "0.01",
    "indexPrice": "12",
    "oraclePrice": "101",
    "priceChange24H": "0",
    "nextFundingRate": "0.0000125000",
    "nextFundingAt": "2021-03-01T18:00:00.000Z",
    "minOrderSize": "1",
    "type": "PERPETUAL",
    "initialMarginFraction": "0.10",
    "maintenanceMarginFraction": "0.05",
    "baselinePositionSize": "1000",
    "incrementalPositionSize": "1000",
    "incrementalInitialMarginFraction": "0.2",
    "volume24H": "0",
    "trades24H": "0",
    "openInterest": "0",
    "maxPositionSize": "10000",
    "assetResolution": "10000000",
    "syntheticAssetId": "0x4c494e4b2d37000000000000000000",
  },
  ...
}



HTTP REQUEST

GET v3/markets

Description: Get one or all markets as well as metadata about each retrieved
market.


REQUEST

Parameter Description market (Optional): Specific market to be fetched.


RESPONSE


MARKET

Parameter Description markets Map of market objects. See below for individual
market.

Parameter Description market Symbol of the market. status Status of the market.
Can be one of ONLINE, OFFLINE, POST_ONLY or CANCEL_ONLY. baseAsset Symbol of the
base asset. e.g. "BTC". quoteAsset Symbol of the quote asset. e.g. "BTC".
stepSize The minimum step size (in base currency) of trade sizes for the market.
tickSize The Tick size of the market. indexPrice The current index price of the
market. oraclePrice The current oracle price of the market. priceChange24H The
absolute price change of the index price over the past 24 hours. nextFundingRate
The predicted next funding rate (as a 1-hour rate). Can be up to 5 seconds
delayed. nextFundingAt The timestamp of the next funding update. minOrderSize
Minimum order size for the market. type Type of the market. This will always be
PERPETUAL for now. initialMarginFraction The margin fraction needed to open a
position. maintenanceMarginFraction The margin fraction required to prevent
liquidation. baselinePositionSize The max position size (in base token) before
increasing the initial-margin-fraction. incrementalPositionSize The step size
(in base token) for increasing the initialMarginFraction by
(incrementalInitialMarginFraction per step). incrementalInitialMarginFraction
The increase of initialMarginFraction for each incrementalPositionSize above the
baselinePositionSize the position is. maxPositionSize The max position size for
this market in base token. volume24H The USD volume of the market in the
previous 24 hours. trades24H The number of trades in the market in the previous
24 hours. openInterest The open interest in base token. assetResolution The
asset resolution is the number of quantums (Starkware units) that fit within one
"human-readable" unit of the asset. syntheticAssetId The id of the synthetic
asset traded in the market. Only used for cryptographically signing orders.


GET ORDERBOOK

> Get Orderbook

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

orderbook = client.public.get_orderbook(
  market=MARKET_BTC_USD,
)


Copy to Clipboardconst orderbook: OrderbookResponseObject = await client.public.getOrderbook(
  Market.BTC_USD,
);


Copy to Clipboard{
  "bids": [
    {
      "price": "29000",
      "size": "1"
    },
    ...
  ],
  "asks": [
    {
      "price": "29500",
      "size": "0.499"
    },
    ...
  ]
}



HTTP REQUEST

GET v3/orderbook/:market

Returns bids and asks which are each Orderbook order arrays (price and size).

Description: Returns the active orderbook for a market. All bids and asks that
are fillable are returned.


REQUEST

Parameter Description market Market of the Orderbook.


RESPONSE

Parameter Description bids See Orderbook Order below. Sorted by price in
descending order. asks See Orderbook Order below. Sorted by price in ascending
order.


ORDERBOOK ORDER

Parameter Description price The price of the order (in quote / base currency).
size The size of the order (in base currency).


GET TRADES

> Get Trades

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

all_trades = client.public.get_trades(
  market=MARKET_BTC_USD,
)


Copy to Clipboardconst trades: { trades: Trade[] } = await client.public.getTrades({
  market: Market.BTC_USD,
  startingBeforeOrAt: "2021-01-05T17:33:43.163Z",
  limit: 1,
});


Copy to Clipboard{
  "trades": [
    {
      "side": "BUY",
      "size": "0.001",
      "price": "29000",
      "createdAt": "2021-01-05T16:33:43.163Z",
      "liquidation": false
    },
    ...
  ]
}



HTTP REQUEST

GET v3/trades/:market

Description: Get Trades by specified parameters. Passing in all query parameters
to the HTTP endpoint would look like: GET
v3/trades/BTC-USD?startingBeforeOrAt=2021-09-05T17:33:43.163Z&limit=1.

Trades will include information for all users and as such includes less
information on individual transactions than the fills endpoint.


REQUEST

Parameter Description market Market of the trades. startingBeforeOrAt
(Optional): Set a date by which the trades had to be created. limit (Optional):
The number of candles to fetch (Max 100).


RESPONSE

Parameter Description trades An array of trades. See trade below


TRADE

Parameter Description side Either BUY or SELL. size The size of the trade. price
The price of the trade. createdAt The time of the trade. liquidation true if the
trade was the result of a liquidation. false otherwise.


GET FAST WITHDRAWAL LIQUIDITY

> Get Fast Withdrawal Liquidity

Copy to Clipboardfast_withdrawals_info = client.public.get_fast_withdrawal()


Copy to Clipboardconst availableFundsMap: {
  liquidityProviders: {
    [positionId: string]: {
      availableFunds: string,
      starkKey: string,
      quote: {
        creditAsset: string,
        creditAmount: string,
        debitAmount: string,
      } | null,
    }
  }
} = await client.public.getFastWithdrawalAvailableFunds();


Copy to Clipboard{
  "liquidityProviders": {
    "1812": {
      "availableFunds": "1000",
      "starkKey": "180913017c740260fea4b2c62828a4008ca8b0d6e4",
      "quote": null,
    },
  }
}



HTTP REQUEST

GET v3/fast-withdrawals

Description: Returns a map of all LP provider accounts that have available funds
for fast withdrawals. Given a debitAmount and asset the user wants sent to L1,
this endpoint also returns the predicted amount of the desired asset the user
will be credited on L1. Given a creditAmount and asset the user wants sent to
L1, this endpoint also returns the predicted amount the user will be debited on
L2.


REQUEST

Parameter Description creditAsset (Optional): The asset that would be sent to
the user. Required if creditAmount or debitAmount are set. creditAmount
(Optional): Set this value if the user wants a quote based on the creditAmount.
debitAmount (Optional): Set this value if the user wants a quote based on the
debitAmount.

Both debitAmount and creditAmount cannot be provided in the same request.


RESPONSE

Parameter Description liquidityProviders Map of LP position IDs to Liquidity
Provider.


LIQUIDITY PROVIDER

Field Description availableFunds The funds available for the LP. starkKey The
public stark key for the LP. quote The Liquidity Provider Quote given the user's
request. Null if no request from the user or the request is unfillable by this
LP.


LIQUIDITY PROVIDER QUOTE

Field Description creditAsset The asset that would be sent to the user on L1.
creditAmount The amount of creditAsset that would be sent to the user (human
readable). debitAmount The amount of USD that would be deducted from the users
L2 account (human readable).


GET MARKET STATS

> Get Market Stats

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

market_statistics = client.public.get_stats(
  market=MARKET_BTC_USD,
  days=MARKET_STATISTIC_DAY_SEVEN,
)


Copy to Clipboardconst marketStatistics = await client.public.getStats({
  market: Market.BTC_USD,
  days: MarketStatisticDay.SEVEN,
});


Copy to Clipboard{
  "markets": {
    "ETH-USD": {
      "market": "ETH-USD",
      "open": "1100",
      "close": "1100",
      "high": "1100",
      "low": "1095",
      "baseVolume": "10000",
      "quoteVolume": "100000",
      "type": "PERPETUAL",
      "fees": "1000"
    }
  }
}



HTTP REQUEST

GET v3/stats/:market

Description: Get an individual market's statistics over a set period of time or
all available periods of time.


REQUEST

Parameter Description market Market whose statistics are being fetched. days
(Optional): Specified day range for the statistics to have been compiled over.
Can be one of 1, 7, 30. Defaults to 1.


RESPONSE

Parameter Description markets Map of market to MarketStats. See example below.


MARKETSTATS

Parameter Description market The symbol of the market, e.g. ETH-USD. open The
open price of the market. high The high price of the market. low The low price
of the market. close The close price of the market. baseVolume The total amount
of base asset traded. quoteVolume The total amount of quote asset traded. type
Type of the market. This will always be PERPETUAL for now.


GET HISTORICAL FUNDING

> Get Historical Funding

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

historical_funding = client.public.get_historical_funding(
  market=MARKET_BTC_USD,
)


Copy to Clipboardconst historicalFunding = await client.public.getHistoricalFunding({
  market: Market.BTC_USD,
});


Copy to Clipboard{
  "historicalFunding": [
    {
      "market": "BTC-USD",
      "rate": "0.0000125000",
      "price": "31297.5000008009374142",
      "effectiveAt": "2021-01-05T09:10:49.000Z"
    },
    ...
  ]
}



HTTP REQUEST

GET v3/historical-funding/:market

Description: Get the historical funding rates for a market.


REQUEST

Parameter Description market Market whose historical funding rates are being
fetched. effectiveBeforeOrAt (Optional): Set a date by which the historical
funding rates had to be created.


RESPONSE

Parameter Description historicalFunding Array of HistoricalFunding. See below
for individual example.


HISTORICAL FUNDING

Parameter Description market Market for which to query historical funding. rate
The funding rate (as a 1-hour rate). price Oracle price used to calculate the
funding rate. effectiveAt Time at which funding payments were exchanged at this
rate.


GET CANDLES FOR MARKET

> Get Candles for Market

Copy to Clipboardfrom dydx3.constants import MARKET_BTC_USD

candles = client.public.get_candles(
  market=MARKET_BTC_USD,
  resolution='1DAY',
)


Copy to Clipboardconst candles: {
  candles: CandleResponseObject,
} = await client.public.getCandles({
  market: Market.BTC_USD,
  resolution: CandleResolution.1DAY,
})


Copy to Clipboard  "candles": [
    {
      "startedAt": "2021-01-05T00:00:00.000Z",
      "updatedAt": "2021-01-05T00:00:00.000Z",
      "market": "BTC-USD",
      "resolution": "1DAY",
      "low": "40000",
      "high": "45000",
      "open": "45000",
      "close": "40000",
      "baseTokenVolume": "1.002",
      "trades": "3",
      "usdVolume": "45085",
      "startingOpenInterest": "28"
    },
    ...
  ]



HTTP REQUEST

GET v3/candles/:market

Description: Get the candle statistics for a market.


REQUEST

Parameter Description market Market whose candles are being fetched. resolution
(Optional): Specific candle resolution being fetched. Can be one of 1DAY,
4HOURS, 1HOUR, 30MINS, 15MINS, 5MINS, 1MIN. fromISO (Optional): Starting point
for the candles. toISO (Optional): Ending point for the candles. limit
(Optional): The number of candles to fetch (Max 100).


RESPONSE

Parameter Description startedAt When the candle started, time of first trade in
candle. updatedAt When the candle was last updated market Market the candle is
for. resolution Time-period of candle (currently 1HOUR or 1DAY). low Low trade
price of the candle. high High trade price of the candle. open Open trade price
of the candle. close Close trade price of the candle. baseTokenVolume Volume of
trade in baseToken currency for the candle. trades Count of trades during the
candle. usdVolume Volume of trade in USD for the candle. startingOpenInterest
The open interest in baseToken at the start of the candle.


GET GLOBAL CONFIGURATION VARIABLES

Copy to Clipboardconfig = client.public.get_config()


Copy to Clipboardconst config: ConfigResponseObject = await client.public.getConfig();


Copy to Clipboard  {
    "collateralAssetId": "0x02c04d8b650f44092278a7cb1e1028c82025dff622db96c934b611b84cc8de5a",
    "collateralTokenAddress": "0x8707a5bf4c2842d46b31a405ba41b858c0f876c4",
    "defaultMakerFee": "0.0005",
    "defaultTakerFee": "0.001",
    "exchangeAddress": "0x014F738EAd8Ec6C50BCD456a971F8B84Cd693BBe",
    "maxExpectedBatchLengthMinutes": "240",
    "maxFastWithdrawalAmount": "200000",
    "cancelOrderRateLimiting": {
      "maxPointsMulti": 3,
      "maxPointsSingle": 8500,
      "windowSecMulti": 10,
      "windowSecSingle": 10
    },
    "placeOrderRateLimiting": {
      "maxPoints": 1750,
      "windowSec": 10,
      "targetNotional": 40000,
      "minLimitConsumption": 4,
      "minMarketConsumption": 20,
      "minTriggerableConsumption": 100,
      "maxOrderConsumption": 100
    }
  }



HTTP REQUEST

GET v3/config

Description: Get any global configuration variables for the exchange as a whole.


RESPONSE

Parameter Description collateralAssetId The assetId of the collateral asset in
the Starkware system. collateralTokenAddress The address of the token used as
collateral. defaultMakerFee The default maker fee for new accounts.
defaultTakerFee The default taker fee for new accounts. exchangeAddress The
address of the exchange contract. maxExpectedBatchLengthMinutes The maximum
expected time between batches L2 (in minutes). maxFastWithdrawalAmount The
maximum amount (in USDC) allowed for fast withdrawals. cancelOrderRateLimiting
See cancelOrderRateLimiting below. placeOrderRateLimiting See
placeOrderRateLimiting below.


CANCELORDERRATELIMITING

Parameter Description maxPointsMulti The number of rate limiting points given
per window for canceling multiple orders. maxPointsSingle The number of rate
limiting points given per window for canceling single orders. windowSecMulti The
length of a rate limiting window for canceling multiple orders, in seconds.
windowSecSingle The length of a rate limiting window for canceling single
orders, in seconds.


PLACEORDERRATELIMITING

Parameter Description maxPoints The number of rate limiting points given per
window. windowSec The length of a rate limiting window, in seconds.
targetNotional The (size * price) target used for determining points
consumption. minLimitConsumption The minimum number of points used when placing
a limit order. minMarketConsumption The minimum number of points used when
placing a market order. minTriggerableConsumption The minimum number of points
used when placing a triggerable (e.g. stop-loss) order. maxOrderConsumption The
maximum number of points used when placing an order.


CHECK IF USER EXISTS

> Check If User Exists

Copy to Clipboarduser_exists = client.public.check_if_user_exists(
  ethereum_address='foo',
)


Copy to Clipboardconst userExists: { exists: boolean } = await client.public.doesUserExistWithAddress(
  'foo',
);


Copy to Clipboard{
  "exists": true
}



HTTP REQUEST

GET v3/users/exists

Description: Check if a user exists for a given Ethereum address.


REQUEST

Parameter Description ethereumAddress Ethereum address that the user would be
associated with.


RESPONSE

Parameter Description exists If a user exists for the given Ethereum address.


CHECK IF USERNAME EXISTS

> Check If Username Exists

Copy to Clipboardusername_exists = client.public.check_if_username_exists(
  username='username',
)


Copy to Clipboardconst usernameExists: { exists: boolean } = await client.public.doesUserExistWithUsername(
  'username',
);


Copy to Clipboard{
  "exists": true
}



HTTP REQUEST

GET v3/usernames

Description: Check if a username has been taken by a user.


REQUEST

Parameter Description username Unique username being checked.


RESPONSE

Parameter Description exists If a username has been taken by any user.


GET API SERVER TIME

> Get API Server Time

Copy to Clipboardtime_object = client.public.get_time()


Copy to Clipboardconst time: { time: { iso: string, epoch: number } } = await client.public.getTime();


Copy to Clipboard{
  "iso": "2021-02-02T18:35:45Z",
  "epoch": "1611965998.515",
}



HTTP REQUEST

GET v3/time

Description: Get the current time of the API server.


RESPONSE

Parameter Description iso ISO time of the server in UTC. epoch Epoch time in
seconds with milliseconds.


GET PUBLIC LEADERBOARD PNLS

> Get Public Leaderboard PNLs

Copy to Clipboardconst leaderboardPnls: { pnls: LeaderboardPnlResponseObject } = await client.public.getLeaderboardPnls(
  period=LeaderboardPnlPeriod.WEEKLY,
  sortBy=LeaderboardPnlSortBy.ABSOLUTE,
  limit=10,
);


Copy to Clipboard{
  "prizePool": 50000,
  "numHedgiesWinners": 1,
  "numPrizeWinners": 50,
  "ratioPromoted": 0.25,
  "ratioDemoted": 0.5,
  "minimumEquity": 500,
  "minimumDYDXTokens": 0,
  "seasonNumber": 16,
  "topPnls": [
    {
      "username": "user",
      "ethereumAddress": "0x3408105669f73e814be44cbf598679a50eb2f7ed",
      "publicId": "ABCDEFG",
      "absolutePnl": "10206.971314",
      "percentPnl": "0.409100",
      "absoluteRank": 20,
      "percentRank": 1,
      "seasonExpectedOutcome": "SAME_LEAGUE",
      "hedgieWon": null,
      "prizeWon": null
    },
    ...
  ],
    "numParticipants": 1,
    "updatedAt": "2022-02-02T15:31:10.813Z",
    "startedAt": "2022-02-01T15:30:00.000Z",
    "endsAt": "2022-02-02T15:30:00.000Z"
}



HTTP REQUEST

GET v3/leaderboard-pnl

Only available for the typescript client and http requests

Description: Get the top PNLs for a specified period and how they rank against
each other.


REQUEST

Parameter Description period "DAILY", "WEEKLY", "MONTHLY", "ALLTIME",
"COMPETITION", "DAILY_COMPETITION", or "LEAGUES". startingBeforeOrAt Latest the
leaderboard starts at. sortBy Which PNL to sort ranks by. "ABSOLUTE" or
"PERCENT". limit (Optional): The number of leaderboard PNLs to fetch (Max 100).


RESPONSE

Parameter Description topPnls Array of PNLForPeriod (see below). numParticipants
Number of participants in this leaderboard. Includes ranked and unranked
participants. startedAt Starting time for this pnl. Note: will only be set if
being used for a competition or leagues. Otherwise, this value will always be
null. endsAt Ending time for this pnl. Note: will only be set if being used for
a competition or leagues. Otherwise, this value will always be null. (Can be a
future time.) updatedAt The time this pnl was updated. seasonNumber Trading
leagues season number. Starts at 1. null if not leagues. prizePool Prize pool
size for period. null if not "COMPETITION" or leagues. numHedgiesWinners Number
of hedgies winners for league. null if not a leagues period. numPrizeWinners
Number of prize winners for league. null if not a leagues period. ratioPromoted
Ratio of users promoted for league. null if not a leagues period. ratioDemoted
Ratio of users demoted for league. null if not a leagues period. minimumEquity
Minimum account equity required to join league. null if not a leagues period.
minimumDYDXTokens Minimum user DYDX + stkDYDX Token balance required to join
league. null if not a leagues period. numHedgiesWinners Number of hedgies prizes
for period. null if not leagues.

PNLFORPERIOD

Parameter Description username Publically-displayed username. null if not
sharing. ethereumAddress User's associated ethereum address. null if not
sharing. publicId User's public id used in the public profile endpoint.
absolutePnl The PNL (in USD) for the specified period. Sorted DESC for
"ABSOLUTE" sortBy. percentPnl The percent PNL for the specified period. Sorted
DESC for "PERCENT" sortBy. absoluteRank User's absolute PNL rank. percentRank
User's percent PNL rank. seasonExpectedOutcome User's expected outcome of latest
season. "PROMOTION", "DEMOTION", or "SAME_LEAGUE". null if not leagues.


GET PUBLIC RETROACTIVE MINING REWARDS

> Get Public Retroactive Mining Rewards

Copy to Clipboardrewards = client.public.get_public_retroactive_mining_rewards(
  ethereum_address='foo',
)


Copy to Clipboardconst rewards: PublicRetroactiveMiningRewardsResponseObject = await client.public.getPublicRetroactiveMiningRewards(
  'foo'
);


Copy to Clipboard{
  "allocation": "0",
  "targetVolume": "0"
}



HTTP REQUEST

GET v3/rewards/public-retroactive-mining

Description: Get the retroactive mining rewards for an ethereum address.


REQUEST

Parameter Description ethereumAddress An Ethereum address.


RESPONSE

Parameter Description allocation The number of allocated dYdX tokens for the
address. targetVolume The addresses' required trade volume (in USD) to be able
to claim the allocation.


VERIFY AN EMAIL ADDRESS

> Verify an Email Address

Copy to Clipboardclient.public.verify_email(
  token='token',
)


Copy to Clipboardawait client.public.verifyEmail('token');


Copy to Clipboard{}



HTTP REQUEST

PUT v3/emails/verify-email

Description: Verify an email address by providing the verification token sent to
the email address.


REQUEST

Parameter Description token Confirmation token that was sent to a user's email.


RESPONSE

On success, returns a 204 response with an empty body. After receiving a 204,
the user associated with the email the token was sent to will begin getting
notification emails for all types they have specified in their userData.
Responds with a 400 error if the token is invalid.


GET CURRENTLY REVEALED HEDGIES

> Get Currently Revealed Hedgies

Copy to Clipboardconst currentlyRevealedHedgies: {
    daily?: HedgiePeriodResponseObject,
    weekly?: HedgiePeriodResponseObject,
} = await client.public.getCurrentlyRevealedHedgies();


Copy to Clipboard{
  "daily": {
    "blockNumber": 14135506,
    "competitionPeriod": 1,
    "tokenIds": [4100]
  },
  "weekly": {
    "blockNumber": 14135506,
    "competitionperiod": 0,
    "tokenIds": [2790, 3000, 4109]
  }
}



HTTP REQUEST

GET v3/hedgies/current

Only available for the typescript client and http requests.

Description: Get the currently revealed Hedgies for competition distribution.


RESPONSE

Parameter Description daily NftPeriodInformation for daily Hedgie or undefined.
weekly NftPeriodInformation for weekly Hedgies or undefined.


NFTPERIODINFORMATION

Parameter Description blockNumber The number of the block whose hash was used to
randomly select the Hedgie tokenId from the remaining unrevealed Hedgies (or
currently revealed Hedgies in the case of distributing weekly Hedgies).
competitionPeriod The zero-indexed period of the competition. Competition 0 was
the very first day a Hedgie was revealed for competition winners. tokenIds An
array of the numeric tokenIds of the Hedgies.


GET HISTORICALLY REVEALED HEDGIES

> Get Historically Revealed Hedgies

Copy to Clipboardconst historicallyRevealedHedgies: {
  historicalTokenIds: HedgiePeriodResponseObject[],
} = await client.public.getHistoricallyRevealedHedgies({
    nftRevealType: WEEK,
    start: 1,
  });


Copy to Clipboard{
  "historicalTokenIds": [{
    "blockNumber": 14135506,
    "competitionperiod": 0,
    "tokenIds": [2790, 3000, 4109]
  }]
}



HTTP REQUEST

GET v3/hedgies/history

Only available for the typescript client and http requests.

Description: Get the historically revealed Hedgies from competition
distributions.


REQUEST

Parameter Description nftRevealType The competition type the Hedgies are being
revealed for (Day or Week). start (Optional): Oldest competition period to be
looking from (inclusive). end (Optional): Newest competition period to be
looking up to (inclusive).


RESPONSE

Parameter Description historicalTokenIds NftPeriodInformation array.

Rows are returned from newest to oldest row. If start and end are not included,
return most recent 100 rows. If only one of startingFrom or endingAt is present,
get startingFrom and the 99 rows after or the 99 before and endingAt (both
ordered newest row to oldest). If start and end are both present then window
must be no greater than 100 inclusive or a 400 error will be returned. Also,
competition periods are zero-indexed.


GET INSURANCE FUND BALANCE

> Get Insurance Fund Balance

Copy to Clipboardbalance = client.public.get_insurance_fund_balance()


Copy to Clipboardconst balance: { balance: number } = await client.public.getInsuranceFundBalance();


Copy to Clipboard{
  "balance":"9868319.469028"
}



HTTP REQUEST

GET v3/insurance-fund/balance

Description: Get the balance of the dYdX insurance fund.


RESPONSE

Parameter Description balance Balance of the dYdX insurance fund in USD.


GET PUBLIC PROFILE

Get Public Profile data. This is a subset of the v3/profile/private endpoint.

Copy to Clipboardbalance = client.public.get_profile("publicId")


Copy to Clipboardconst publicProfile: ProfilePublicResponseObject = await client.public.getProfilePublic("publicId");


Copy to Clipboard{
    "username": "foo",
    "ethereumAddress": "0x0913017c740260fea4b2c62828a4008ca8b0d6e4",
    "DYDXHoldings": "250",
    "stakedDYDXHoldings": "250",
    "hedgiesHeld": [111],
    "twitterHandle": "bar",
    "tradingLeagues": {
        "currentLeague": "SILVER",
        "currentLeagueRanking": 12,
    },
    "tradingPnls": {
        "absolutePnl30D": "324",
        "percentPnl30D": "25",
        "volume30D": "4000",
    },
    "tradingRewards": {
        "curEpoch": "8",
        "curEpochEstimatedRewards": 280,
        "prevEpochEstimatedRewards": 125,
    },
}



HTTP REQUEST

GET v3/profile/:publicId

Description: Get the public profile of a user given their public id.


RESPONSE

Parameter Description balance Balance of the dYdX insurance fund in USD.


REQUEST

Parameter Description publicId Public id of the user


RESPONSE

Parameter Description username Publically-displayed username. publicId User's
public id used in the public profile endpoint ethereumAddress User's associated
ethereum address. DYDXHoldings The user's DYDX token holdings. null if not
sharing ethereum address. stakedDYDXHoldings The user's stkDYDX token holdings.
null if not sharing ethereum address. hedgiesHeld Indices of all Hedgies held.
twitterHandle The username that appears at the end of a unique Twitter url.
tradingLeagues See "TradingLeagues" below. tradingPnls See "TradingPnls" below.
tradingRewards See "TradingRewards" below.


TRADINGLEAGUES

Parameter Description currentLeague null, "BRONZE", "SILVER", "GOLD",
"PLATINUM", or "DIAMOND". currentLeagueRanking null, or positive integer
ranking.


TRADINGPNLS

Parameter Description absolutePnl30D null, or user's 30 day absolute pnl (based
on leaderboard formula). percentPnl30D null, or user's 30 day percent pnl (based
on leaderboard formula). volume30D The sum of a user's 30 day maker and taker
trading volume.


TRADINGREWARDS

Parameter Description curEpoch Current epoch number. curEpochEstimatedRewards
The user's estimated number of dYdX tokens as rewards for the current epoch.
prevEpochEstimatedRewards The user's estimated number of dYdX tokens as rewards
for the previous epoch.


V3 WEBSOCKET API

dYdX offers a WebSocket API for streaming v3 updates.

You can connect to the v3 WebSockets at:

 * Production: wss://api.dydx.exchange/v3/ws
 * Staging (Goerli): wss://api.stage.dydx.exchange/v3/ws

The server will send pings every 30s and expects a pong within 10s. The server
does not expect pings, but will respond with a pong if sent one.


ACCOUNTS CHANNEL

This channel provides realtime information about orders, fills, funding updates
and positions for a user. To subscribe, you will need to be authenticated.

To subscribe:

field type description type string Set to subscribe channel string Set to
v3_accounts accountNumber string The account number to subscribe to apiKey
string The apiKey for the user signature string validation signature. See below
timestamp string timestamp used for the signature passphrase string The
passphrase field of the API key

Authentication

The authentication in the accounts channel is identical to private endpoint
authentication with one key difference. The requestPath is /ws/accounts.


INITIAL RESPONSE:

The initial response will contain the information about the account, open
positions, recent transfers, and open orders, i.e. everything from GET
/v3/accounts/:id, GET /v3/transfers, GET /v3/funding and GET /v3/orders (with
accountId in the header).

Note that the freeCollateral and equity (also called total account value) for an
account are only sent in the initial response. To track these over time, refer
to this section.

> Example initial response

Copy to Clipboard{
  "type": "subscribed",
  "channel": "v3_accounts",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
  "message_id": 1,
  "contents": {
    "orders": [
      {
        "id": "797fc129eeb7c54163f3947f1f250594",
        "clientId": "2",
        "market": "BTC-USD",
        "accountId": "e33a8007-57ca-52ab-887d-d162d1666f3b",
        "side": "BUY",
        "size": "112",
        "remainingSize": "0",
        "price": "34",
        "limitFee": "0.0005",
        "type": "LIMIT",
        "status": "OPEN",
        "signature": "0x456...",
        "timeInForce": "FOK",
        "postOnly": "false",
        "expiresAt": "2021-09-22T20:22:26.399Z",
        "createdAt": "2020-09-22T20:22:26.399Z"
      }
    ],
    "account": {
      "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "positionId": "9356",
      "userId": "fe71e7df-c633-4ba1-870e-61f36580cfc5",
      "accountNumber": "0",
      "starkKey": "041c2ae647ee91807eed6471488983ab4addc2a602d4ceeb04dfda470e33f148",
      "quoteBalance": "300",
      "pendingDeposits": "0",
      "pendingWithdrawals": "0",
      "lastTransactionId": "14",
      "equity": "1879.090000",
      "freeCollateral": "1879.090000",
      "createdAt": "2021-04-09T21:08:34.984Z",
      "openPositions": {
        "LINK-USD": {
          "id": "677dad3b-d848-5e7c-84bf-18760f3414f6",
          "accountId": "e33a8007-57ca-52ab-887d-d162d1666f3b",
          "market": "LINK-USD",
          "side": "LONG",
          "status": "OPEN",
          "size": "200",
          "maxSize": "300",
          "entryPrice": "36",
          "exitPrice": "38",
          "realizedPnl": "50",
          "createdAt": "2020-09-22T20:25:26.399Z",
          "openTransactionId": "2",
          "lastTransactionId": "14",
          "sumOpen": "300",
          "sumClose": "100"
        }
      }
    }
  },
  "transfers": [
    {
      "id": "8d303634-da14-56bb-99f5-122e34b1ce34",
      "type": "FAST_WITHDRAWAL",
      "debitAsset": "USDC",
      "creditAsset": "USDC",
      "debitAmount": "500",
      "creditAmount": "500",
      "transactionHash": "0xb86e98d05098de6249d7c10616ffefa0b001976238083dc34a8e747fd7960029",
      "status": "CONFIRMED",
      "createdAt": "2021-02-05T00:37:43.009Z",
      "confirmedAt": null,
      "clientId": "9407156494718159",
      "fromAddress": "0x3ebe6781be6d436cb7999cfce8b52e40819721cb",
      "toAddress": "0x14c2a496e5b7a52d54748cba0bd9f4b24ed27fdd"
    }
  ],
  "fundingPayments": [],
}



CHANNEL DATA

Subsequent responses will contain any updates to open orders, or changes to
account balance, or the open positions, or transfers, in a single message.

> A fill occurs, and a position is closed, and the account balance modified

Copy to Clipboard{
  "type": "channel_data",
  "channel": "v3_accounts",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
  "message_id": 2,
  "contents": {
    "fills": [{
        "id": "677dad3b-d848-5e7c-84bf-18760f3414f6",
        "accountId": "e33a8007-57ca-52ab-887d-d162d1666f3b",
        "side": "BUY",
        "liquidity": "TAKER",
        "market": "LINK-USD",
        "orderId": "797fc129eeb7c54163f3947f1f250594",
        "size": "112",
        "price": "35",
        "fee": "10",
        "transactionId": "1",
        "orderClientId": "31391968951033844",
        "createdAt": "2020-09-22T20:25:26.399Z",
    }],
    "orders": [{
      "id": "797fc129eeb7c54163f3947f1f250594",
      "clientId": "2",
      "market": "BTC-USD",
      "accountId": "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "side": "BUY",
      "size": "112",
      "remainingSize": "0",
      "price": "34",
      "limitFee": "0.0005",
      "type": "LIMIT",
      "status": "ENTIRELY_FILLED",
      "signature": "0x456...",
      "timeInForce": "FOK",
      "postOnly": "false",
      "expiresAt": "2021-09-22T20:22:26.399Z",
      "createdAt": "2020-09-22T20:22:26.399Z"
    }],
    "positions": [{
      "id": "677dad3b-d848-5e7c-84bf-18760f3414f6",
      "accountId": "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "market": "LINK-USD",
      "side": "LONG",
      "status": "CLOSED",
      "size": "200",
      "maxSize": "300",
      "entryPrice": "36",
      "exitPrice": "38",
      "realizedPnl": "50",
      "createdAt": "2020-09-22T20:25:26.399Z",
      "openTransactionId": "2",
      "closeTransactionId": "23",
      "lastTransactionId": "23",
      "closedAt": "2020-14-22T20:25:26.399Z",
      "sumOpen": "300",
      "sumClose": "100"
    }],
    "accounts": [{
      "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "positionId": "b2759094-12af-4b59-8071-661e99148a14",
      "userId": "fe71e7df-c633-4ba1-870e-61f36580cfc5",
      "accountNumber": "0",
      "starkKey": "0x456...",
      "quoteBalance": "700",
      "pendingDeposits": "400",
      "pendingWithdrawals": "0",
      "lastTransactionId": "14"
    }]
  }
}


> a deposit occurs

Copy to Clipboard{
  "type": "channel_data",
  "channel": "v3_accounts",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
  "message_id": 2,
  "contents": {
    "fills": [],
    "orders": [],
    "positions": [],
    "accounts": [{
      "id": "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "positionId": "b2759094-12af-4b59-8071-661e99148a14",
      "userId": "fe71e7df-c633-4ba1-870e-61f36580cfc5",
      "accountNumber": "0",
      "starkKey": "0x456...",
      "quoteBalance": "7000",
      "pendingDeposits": "200",
      "pendingWithdrawals": "0",
      "lastTransactionId": "14"
    }],
    "transfers": [{
      "id" : "35bb84a8-d8b5-5f8e-a49e-8ad979fb7567",
      "accountId" : "e33a8007-57ca-52ab-887d-d162d1666f3b",
      "type" : "DEPOSIT",
      "debitAsset" : "USDC",
      "creditAsset" : "USDC",
      "debitAmount" : "10000",
      "creditAmount" : "10000",
      "transactionHash" : "0xec2bd16e73e4bb54c1ee25415233ded15f6e8c4edb8480ce9774a28c7846d4f0",
      "status" : "PENDING",
      "clientId" : "18",
      "updatedAt" : "2021-01-17 22:24:54.661+00",
      "createdAt" :  "2021-01-17 22:24:54.560426+00",
    }]
  }
}



ORDERBOOK

To subscribe:

field type description type string Set to subscribe channel string Set to
v3_orderbook id string The market to subscribe to e.g. BTC-USD, LINK-USD
includeOffsets (optional) boolean If specified, this will return an initial
response with per-price level offsets


INITIAL RESPONSE:

The initial response will contain the state of the orderbook and will be the
same structure as GET /v3/orderbook/:market. If includeOffsets is sent and set
to true in the subscription message, there will be an offset included for each
price level. (See the example included)

field description type will be subscribed channel the channel name, i.e.
v3_orderbook id the market subscribed to e.g. BTC-USD contents the message
contents

The contents is structured as:

field type description offset string A number used for ordering. See offset
below. bids array See PublicOrder below. Sorted by price in descending order
asks array See PublicOrder below. Sorted by price in ascending order

PublicOrder:

field type description price string human readable price of the order (in quote
/ base currency) size string human readable size of the order (in base currency)
offset string (if includeOffsets is set to true) the offset for the specific
price

Offset:

The price updates are not guaranteed to be sent in order. So it is possible to
receive an older price update later. For this reason, the offset is included in
the message, to help order. The offset increases monotonically, and increasing
values of offsets indicate more recent values.

To keep a valid orderbook, you should store the offset for each price level
independently. A given price level should be updated if and only if an update
for the price level is received with a higher offset than what you have stored.
To get a per-price level offset in the initial response, you can set
includeOffsets to true when subscribing.

Example messages:

> Example initial response:

Copy to Clipboard{
  "type": "subscribed",
  "connection_id": "87b25218-0170-4111-bfbf-d9f0a506fcab",
  "message_id": 1,
  "channel": "v3_orderbook",
  "id": "ETH-USD",
  "contents": {
    "bids": [
      {
        "price": "1779",
        "size": "11.24"
      },
      {
        "price": "1778.5",
        "size": "18"
      }
    ],
    "asks": [
      {
        "price": "1782.8",
        "size": "10"
      },
      {
        "price": "1784",
        "size": "2.81"
      }
    ]
  }
}


> Example initial response if includeOffsets is set to true:

Request:

Copy to Clipboard{
  "type": "subscribe",
  "channel": "v3_orderbook",
  "id": "ETH-USD",
  "includeOffsets": "true"
}


Response:

Copy to Clipboard{
  "type": "subscribed",
  "connection_id": "14f7c481-1e1f-4f5c-8c5c-7b114209d8ce",
  "message_id": 1,
  "channel": "v3_orderbook",
  "id": "ETH-USD",
  "contents": {
    "bids": [
      {
        "price": "1778.8",
        "offset": "36850163",
        "size": "11"
      },
      {
        "price": "1776.7",
        "offset": "36849225",
        "size": "5.9"
      }
    ],
    "asks": [
      {
        "price": "1783",
        "offset": "36848764",
        "size": "13"
      },
      {
        "price": "1784",
        "offset": "36848433",
        "size": "4.3"
      }
    ]
  }
}



CHANNEL DATA

Subsequent responses will contain the new order sizes for any price levels that
have changed since the previous update:

e.g:

> Subsequent messages

Copy to Clipboard{
  "type": "channel_data",
  "id": "BTC-USD",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "channel": "v3_orderbook",
  "message_id": 2,
  "contents": {
    "offset": "178",
    "bids": [["102", "12"]],
    "asks": [["104", "0" ]]
  }
}


E.g: if some orders at "102" price, get filled, then the update would be ["102",
"12"], where "12" is the new size. If there are no more asks at "104", then the
ask update would be ["104", "0"].


TRADES

To subscribe:

field type description type string Set to subscribe channel string Set to
v3_trades id string The market to subscribe to e.g. BTC-USD, LINK-USD


INITIAL RESPONSE:

The initial response will contain the historical trades and will be the same
structure as GET /v3/trades/:market.

field description type will be subscribed channel the channel name, i.e.
v3_trades id the market subscribed to e.g. BTC-USD contents the message contents

The contents is structured as:

field type description trades array See PublicTrade below.

PublicTrade:

field type description side string BUY or SELL size string size of the trade
price string price of the trade createdAt ISO time of the trade time of the
trade liquidation boolean true if the trade was the result of a liquidation,
false otherwise

Example messages:

> Example initial response:

Copy to Clipboard{
  "type": "subscribed",
  "id": "BTC-USD",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "channel": "v3_trades",
  "message_id": 1,
  "contents": {
    "trades": [
      {
        "side": "BUY",
        "size": "100",
        "price": "4000",
        "createdAt": "2020-10-29T00:26:30.759Z"
      },
      {
        "side": "BUY",
        "size": "100",
        "price": "4000",
        "createdAt": "2020-11-02T19:45:42.886Z"
      },
      {
        "side": "BUY",
        "size": "100",
        "price": "4000",
        "createdAt": "2020-10-29T00:26:57.382Z"
      }
    ]
  }
}



CHANNEL DATA

Subsequent responses will contain the recently created trades. e.g:

> Subsequent responses

Copy to Clipboard{
  "type": "channel_data",
  "id": "BTC-USD",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "channel": "v3_trades",
  "message_id": 2,
  "contents": {
    "trades": [
      {
        "side": "BUY",
        "size": "100",
        "price": "4000",
        "createdAt": "2020-11-29T00:26:30.759Z"
      },
      {
        "side": "SELL",
        "size": "100",
        "price": "4000",
        "createdAt": "2020-11-29T14:00:03.382Z"
      }
    ]
  }
}



MARKETS

To subscribe:

field type description type string Set to subscribe channel string Set to
v3_markets


INITIAL RESPONSE:

Same as GET /v3/markets


CHANNEL DATA

Subsequent responses will contain an update for one or more markets. Updates
will be sent any time a field(s) changes on a market(s). Updates will only
contain the field(s) that have changed:

> Subsequent responses

Copy to Clipboard{
  "type": "channel_data",
  "connection_id": "e2a6c717-6f77-4c1c-ac22-72ce2b7ed77d",
  "channel": "v3_markets",
  "message_id": 2,
  "contents": {
    "ETH-USD": {
        "oraclePrice": "100.23"
    },
    "BTC-USD": {
        "indexPrice": "100.23",
        "priceChange24H": "0.12",
        "initialMarginFraction": "1.23"
    }
  }
}



SECURITY


INDEPENDENT AUDITS

The Starkware Perpetual smart contracts were audited independently by
PeckShield.

PeckShield Audit Report


VULNERABILITY DISCLOSURE POLICY

The disclosure of security vulnerabilities helps us ensure the security of our
users.

How to report a security vulnerability?

If you believe you’ve found a security vulnerability in one of our contracts or
platforms, send it to us by emailing security@dydx.exchange. Please include the
following details with your report:

 * A description of the location and potential impact of the vulnerability.

 * A detailed description of the steps required to reproduce the vulnerability.

Scope

Any vulnerability not previously disclosed by us or our independent auditors in
their reports.

Guidelines

We require that all reporters:

 * Make every effort to avoid privacy violations, degradation of user
   experience, disruption to production systems, and destruction of data during
   security testing.

 * Use the identified communication channels to report vulnerability information
   to us.

 * Keep information about any vulnerabilities you’ve discovered confidential
   between yourself and dYdX until we’ve had 30 days to resolve the issue.

If you follow these guidelines when reporting an issue to us, we commit to:

 * Not pursue or support any legal action related to your findings.

 * Work with you to understand and resolve the issue quickly (including an
   initial confirmation of your report within 72 hours of submission).

 * Grant a monetary reward based on the OWASP risk assessment methodology.

Python TypeScript HTTP