docs: sync Polymarket docs updates 2026-07-13 - add 90 new pages incl. Perps section

This commit is contained in:
GLaDOS
2026-07-13 01:40:25 +02:00
parent 714c66e5b3
commit 2d608bd891
91 changed files with 31279 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+653
View File
@@ -0,0 +1,653 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Authenticated Sessions
> Set up authenticated access for Perps trading and account data
An authenticated session is a two-way authenticated communication channel with
the Perps system that allows your app to place orders, read private Perps account
data, and receive private real-time updates.
## Set Up Perps Access
<Tabs>
<Tab title="TypeScript">
<Steps>
<Step title="Create a Secure Client">
Create a `SecureClient` for the Polymarket wallet that owns the Perps account,
using the signer that controls it.
```ts theme={null}
import { createSecureClient } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
signer: privateKey(process.env.PRIVATE_KEY!),
});
```
<Note>
This example uses Viem for wallet signing. See the [TypeScript tooling
guide](/dev-tooling/typescript#wallet-integrations) for other wallet library
integrations.
</Note>
</Step>
<Step title="Open a Perps Session">
Open a Perps session. By default, delegated Perps credentials expire after one
week.
```ts theme={null}
const session = await client.openPerpsSession();
```
You can also set the session lifetime and label explicitly. `expiresIn` is
measured in milliseconds.
```ts theme={null}
const session = await client.openPerpsSession({
expiresIn: 7 * 24 * 60 * 60 * 1000,
label: "trading-app",
});
```
</Step>
</Steps>
</Tab>
<Tab title="Python">
<Steps>
<Step title="Create a Secure Client">
Create an `AsyncSecureClient` for the Polymarket wallet that owns the Perps
account, using the signer that controls it.
```python theme={null}
import os
from polymarket import AsyncSecureClient
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
)
```
</Step>
<Step title="Open a Perps Session">
Open a Perps session. By default, delegated Perps credentials expire after one
week.
```python theme={null}
session = await client.open_perps_session()
```
You can also set the session lifetime and label explicitly. `expires_in` is a
`timedelta`.
```python theme={null}
from datetime import timedelta
session = await client.open_perps_session(
expires_in=timedelta(days=7),
label="trading-app",
)
```
</Step>
</Steps>
</Tab>
<Tab title="API">
Start by registering new proxy credentials for an existing Polymarket account.
If you do not have one yet, create an account at
[polymarket.com](https://polymarket.com) first.
<Steps>
<Step title="Generate a Proxy Signer">
Generate a fresh keypair for the proxy signer. Perps uses this key to authorize
trading operations on behalf of the Polymarket account signer, without requiring
the account signer to sign every order.
Use any secure EVM key-generation flow.
<CodeGroup>
```bash Foundry theme={null}
$ cast wallet new
Successfully created new keypair.
Address: <proxy_address>
Private key: <proxy_private_key>
```
```ts Viem theme={null}
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
const privateKey = generatePrivateKey();
const { address } = privateKeyToAccount(privateKey);
```
</CodeGroup>
Store the private key securely. It will be used to sign Perps trading operations
for the Polymarket account signer.
</Step>
<Step title="Create Proxy Typed Data">
Create an EIP-712 `CreateProxy` payload.
```json theme={null}
{
"domain": {
"name": "Polymarket",
"version": "1",
"chainId": 137
},
"primaryType": "CreateProxy",
"types": {
"CreateProxy": [
{ "name": "addr", "type": "address" },
{ "name": "exp", "type": "uint64" },
{ "name": "salt", "type": "uint64" },
{ "name": "ts", "type": "uint64" }
]
},
"message": {
"addr": "<proxy_address>",
"exp": 1767225600000,
"salt": 123456789,
"ts": 1767000000000
}
}
```
Use these values consistently in the typed data and request body.
| Field | Value |
| ------ | ----------------------------------------------------------------------- |
| `addr` | `<proxy_address>` from the previous step. |
| `exp` | Unix timestamp in milliseconds when the proxy signer stops being valid. |
| `ts` | Current Unix timestamp in milliseconds. |
| `salt` | Random integer generated for this signed request. |
</Step>
<Step title="Sign Proxy Typed Data">
Sign the `CreateProxy` typed data with the signer for the Polymarket account.
```ts Viem theme={null}
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("<polymarket_account_signer_private_key>");
const signature = await account.signTypedData({
domain: {
name: "Polymarket",
version: "1",
chainId: 137,
},
primaryType: "CreateProxy",
types: {
CreateProxy: [
{ name: "addr", type: "address" },
{ name: "exp", type: "uint64" },
{ name: "salt", type: "uint64" },
{ name: "ts", type: "uint64" },
],
},
message: {
addr: "<proxy_address>",
exp: 1767225600000,
salt: 123456789,
ts: 1767000000000,
},
});
```
</Step>
<Step title="Authorize the Proxy Signer">
Authorize the generated proxy signer for your Perps account.
```bash theme={null}
curl -X POST "https://api.perpetuals.polymarket.com/v1/account/proxy" \
-H "content-type: application/json" \
-d '{
"op": {
"type": "createProxy",
"args": {
"owner": "<polymarket_account_signer_address>",
"proxy": "<proxy_address>",
"expiry": 1767225600000
}
},
"sig": "<signature>",
"salt": 123456789,
"ts": 1767000000000,
"label": "trading-app"
}'
```
Map the request fields to the values from the previous steps.
* `owner` is the signer address for the Polymarket account.
* `proxy` is `<proxy_address>` from the first step.
* `sig` is `<signature>` from the previous step.
* `salt` and `ts` are the same values used in the typed data from step 2.
* `label` is an identifier for this proxy credential instance.
The response contains the proxy secret.
```json theme={null}
{
"secret": "<proxy_secret>"
}
```
Store the proxy private key, proxy address, proxy secret, and expiry securely.
</Step>
</Steps>
</Tab>
</Tabs>
## Session Lifecycle
Open an authenticated session to start trading, read private Perps account data,
and receive private real-time updates.
<Tabs>
<Tab title="TypeScript">
<Steps>
<Step title="Listen for Session Events">
After opening a Perps session, iterate over it to receive private real-time
updates.
```ts theme={null}
const session = await client.openPerpsSession();
for await (const event of session) {
switch (event.type) {
case "order":
// Update local order state.
break;
case "fill":
// Update position, PnL, or execution history.
break;
case "portfolio":
// Refresh margin, equity, and position views.
break;
}
}
```
This example handles a few common session events. `order` and `fill` are the
core trading updates, while `portfolio` provides periodic account-level snapshots
for margin, equity, positions, and withdrawable balance.
See [Reconcile Trade State](/perps/trading#reconcile-trade-state) for how to use
these events to keep local trading state in sync.
</Step>
<Step title="Close the Session">
You can close the session at any time by calling `session.close()`. Closing a
session releases local resources; stored credentials can still be resumed until
they expire.
```ts theme={null}
for await (const event of session) {
if (shouldCloseSession) {
await session.close();
break;
}
// …
}
```
</Step>
</Steps>
</Tab>
<Tab title="Python">
<Steps>
<Step title="Listen for Session Events">
After opening a Perps session, iterate over it to receive private real-time
updates.
```python theme={null}
session = await client.open_perps_session()
async for event in session:
if event.type == "order":
# Update local order state.
pass
elif event.type == "fill":
# Update position, PnL, or execution history.
pass
elif event.type == "portfolio":
# Refresh margin, equity, and position views.
pass
```
This example handles a few common session events. `order` and `fill` are the
core trading updates, while `portfolio` provides periodic account-level snapshots
for margin, equity, positions, and withdrawable balance.
See [Reconcile Trade State](/perps/trading#reconcile-trade-state) for how to use
these events to keep local trading state in sync.
</Step>
<Step title="Close the Session">
You can close the session at any time by calling `session.close()`. Closing a
session releases local resources; stored credentials can still be resumed until
they expire.
```python theme={null}
async for event in session:
if should_close_session:
await session.close()
break
# …
```
</Step>
</Steps>
</Tab>
<Tab title="API">
<Steps>
<Step title="Authenticate a WebSocket Connection">
Connect to the Perps WebSocket production URL.
```text theme={null}
wss://ws.perpetuals.polymarket.com/v1/ws
```
After the connection opens, send an authentication frame with the proxy address
and proxy secret.
```json theme={null}
{
"id": 1,
"req": "post",
"op": {
"type": "auth",
"args": {
"proxy": "<proxy_address>",
"secret": "<proxy_secret>"
}
}
}
```
Check the authentication response before subscribing to private channels.
<CodeGroup>
```json Success theme={null}
{
"id": 1,
"data": {
"status": "ok"
}
}
```
```json Failure theme={null}
{
"id": 1,
"data": {
"status": "err",
"error": "<error_message>"
}
}
```
</CodeGroup>
</Step>
<Step title="Handle Session Events">
Authenticated WebSocket connections receive private session update frames. These
examples show a few common events: `orders` and `fills` for trading activity,
and `portfolio` for periodic account-level snapshots.
<CodeGroup>
```json Order theme={null}
{
"ch": "orders",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"oid": 1234567890,
"iid": 1,
"buy": true,
"p": "65000.00",
"qty": "0.01",
"tif": "gtc",
"po": false,
"status": "open",
"rest": "0.01",
"fill": "0",
"cts": 1767225600000,
"uts": 1767225600000
}
}
```
```json Fill theme={null}
{
"ch": "fills",
"ts": 1767225600000,
"sq": 1234567891,
"data": {
"tid": 987654321,
"oid": 1234567890,
"iid": 1,
"side": "long",
"p": "65000.00",
"qty": "0.01",
"taker": true,
"fee": "0.26",
"fea": "pUSD",
"psz": "0",
"pep": "0",
"pnl": "0",
"liq": false,
"ts": 1767225600000
}
}
```
```json Portfolio theme={null}
{
"ch": "portfolio",
"ts": 1767225600000,
"sq": 1234567892,
"data": {
"positions": [],
"margin": {
"total_account_value": "10.00",
"total_initial_margin": "0",
"total_maintenance_margin": "0",
"total_position_value": "0"
},
"withdrawable": "10.00",
"in_liquidation": false,
"timestamp": 1767225600000
}
}
```
</CodeGroup>
These are examples of common session events, not the full event list.
</Step>
<Step title="Keep the Connection Alive">
Send an application-level ping from the client about every 25 seconds.
```json theme={null}
{
"id": 0,
"req": "post",
"op": {
"type": "ping"
}
}
```
The server responds with a pong payload.
```json theme={null}
{
"id": 0,
"data": {
"status": "ok",
"ts": 1767225600000,
"sq": 1234567890
}
}
```
Treat the connection as stale if no messages arrive for about 65 seconds.
</Step>
<Step title="Close the Connection">
Close the WebSocket connection when the current workflow is finished. Closing the
connection does not revoke the proxy credential.
</Step>
</Steps>
</Tab>
</Tabs>
## Resume a Session
Resume a session when stored credentials are still valid and a Perps workflow
needs to continue in a new runtime context.
<Tabs>
<Tab title="TypeScript">
Read `session.credentials` after opening a session and store the object in secure
credential storage.
```ts theme={null}
const credentials = session.credentials;
// credentials: PerpsCredentials
```
where `PerpsCredentials` is:
<CodeGroup>
```ts Type theme={null}
type PerpsCredentials = {
proxy: EvmAddress;
privateKey: PrivateKey;
secret: string;
expiresAt: number;
};
```
```json Example theme={null}
{
"proxy": "0x1111111111111111111111111111111111111111",
"privateKey": "0x2222222222222222222222222222222222222222222222222222222222222222",
"secret": "<proxy_secret>",
"expiresAt": 1766725200000
}
```
</CodeGroup>
Pass stored credentials back to `openPerpsSession()` while they are still valid.
The SDK validates them and resumes the session.
```ts theme={null}
const session = await client.openPerpsSession({
credentials,
});
// session: PerpsSession
```
</Tab>
<Tab title="Python">
Read `session.credentials` after opening a session and store the object in secure
credential storage.
```python theme={null}
credentials = session.credentials
# credentials: PerpsCredentials
```
where `PerpsCredentials` is:
<CodeGroup>
```python Type theme={null}
from polymarket import PerpsCredentials
# credentials: PerpsCredentials
```
```json Example theme={null}
{
"proxy": "0x1111111111111111111111111111111111111111",
"private_key": "0x2222222222222222222222222222222222222222222222222222222222222222",
"secret": "<proxy_secret>",
"expires_at": "2026-01-25T18:20:00Z"
}
```
</CodeGroup>
For JSON-backed storage, serialize the model and keep the result encrypted.
```python theme={null}
stored_credentials = credentials.model_dump(mode="json")
```
Pass stored credentials back to `open_perps_session()` while they are still
valid. The SDK validates them and resumes the session.
```python theme={null}
from polymarket import PerpsCredentials
credentials = PerpsCredentials.model_validate(stored_credentials)
session = await client.open_perps_session(credentials=credentials)
# session: PerpsSession
```
</Tab>
<Tab title="API">
Resume an API session by reusing stored proxy credentials while they are still
valid.
Store the credential material from the setup flow in secure credential storage.
| Field | Use it to |
| --------------------- | ----------------------------------------------- |
| `<proxy_address>` | Identify the proxy credential. |
| `<proxy_private_key>` | Sign Perps trading operations. |
| `<proxy_secret>` | Authenticate private REST and real-time access. |
| `expiry` | Know when to register a new proxy credential. |
For private REST reads, pass the proxy address and proxy secret as headers.
```bash theme={null}
curl "https://api.perpetuals.polymarket.com/v1/account/portfolio" \
-H "polymarket-proxy: <proxy_address>" \
-H "polymarket-secret: <proxy_secret>"
```
For a new WebSocket connection, send the same authentication frame used when the
session was opened.
```json theme={null}
{
"id": 1,
"req": "post",
"op": {
"type": "auth",
"args": {
"proxy": "<proxy_address>",
"secret": "<proxy_secret>"
}
}
}
```
If the credential has expired, register a new proxy credential before resuming
private workflows.
</Tab>
</Tabs>
+53
View File
@@ -0,0 +1,53 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Changelog
> Recent changes to the Polymarket Perps API and platform
Notable changes to the Polymarket Perps API.
<Update label="Jun 11, 2026" description="Cancel responses include order IDs">
Cancel responses now include `oid` and `coid` fields.
</Update>
<Update label="Jun 10, 2026" description="Taker delay added for immediately matching orders">
Added a 20ms taker delay for orders that immediately match on entry.
</Update>
<Update label="Jun 9, 2026" description="Reduce-only orders added">
Added the reduce-only field to order submission and order updates.
</Update>
<Update label="Jun 8, 2026" description="Auto-cancel and rate-limit updates">
<ul>
<li>
Added <code>PATCH /v1/trade/auto-cancel</code> to arm or clear a dead
man's switch that cancels all open orders at a specified time.
</li>
<li>
Added <code>GET /v1/account/auto-cancel</code> to check the current
auto-cancel status, trigger count, and daily reset time.
</li>
<li>Auto-cancel is limited to 10 triggers per UTC day per account.</li>
<li>
Added <code>updateLeverage</code> and <code>autoCancel</code> WebSocket
post messages.
</li>
<li>
<code>portfolio</code> and <code>balances</code> WebSocket channels no
longer push updates on every order or fill, only periodically.
</li>
<li>
Rate limit error messages now distinguish between{" "}
<code>ip\_rate\_limited</code>, <code>action\_rate\_limited</code>, and{" "}
<code>message\_rate\_limited</code>.
</li>
</ul>
</Update>
+186
View File
@@ -0,0 +1,186 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Concepts
> Core concepts for Polymarket perpetual markets
Perps trading depends on how order fills create or change positions, how prices
affect account equity, and how collateral supports trading risk. The concepts
below describe the moving parts that determine what an account can trade and when
a position is at risk.
## Instruments
An instrument identifies a Perps market: a tradable perpetual contract that
tracks an underlying asset such as the S\&P 500 Index, gold, or bitcoin. Each
instrument carries the information needed to identify the market and the rules
for trading it.
| Attribute | Meaning |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| ID | The instrument identifier used in market data and orders |
| Symbol | A short market label, such as `SP500-USD`, `GOLD-USD`, or `BTC-USD` |
| Underlying asset | The asset or index the market tracks, such as the S\&P 500 Index, gold, or bitcoin |
| Collateral asset | The asset used to fund Perps accounts and support open positions. Polymarket Perps use pUSD. |
| Trading constraints | Market-specific rules such as price precision, quantity precision, order limits, and leverage. |
## Perps Accounts
A Perps account is tied to a signer account. The signer account controls private
actions such as trading and withdrawals.
The Perps account holds the state created by those actions: collateral, open
positions, orders, fills, and history. Later sections explain how those pieces
change as orders execute, prices move, and funding payments settle.
Perps accounts are funded through onchain collateral deposits.
<Note>
If you're building on Perps, delegated credentials let your app act for the
Perps account without using the owner key for every private action. See
[Authenticated Sessions](/perps/authenticated-sessions).
</Note>
## Prices
A Perps market has two broad categories of prices: execution prices and
calculated prices. Execution prices come from trades in the order book.
Calculated prices are produced by Polymarket and used for reference, margin, and
liquidation checks.
This separation matters because one small or isolated trade should not be able to
change an account's risk state or trigger liquidation by itself.
| Price | Category | Meaning | Used for |
| ------------ | ---------------- | ---------------------------------------------------------- | --------------------------------------------------- |
| Traded price | Execution price | The price of an executed order book fill | Trade history and execution records |
| Index price | Calculated price | Polymarket's estimate of the underlying asset's fair value | Reference price and price anchoring |
| Mark price | Calculated price | The price used to value positions | Unrealized PnL, margin checks, and liquidation risk |
Calculated prices are computed from external price feeds. The feed set can
change with market sessions, such as regular hours, overnight trading, and
weekends, while funding, margin, and liquidation rules stay the same around the
clock. See [Market Sessions](/perps/learn-about-trading/market-sessions).
## Orders And Fills
Orders are requests to trade in a Perps market. They can execute immediately or
rest in the order book until another order matches them.
The order book is the list of resting buy and sell orders for a market. A fill is
an executed match between orders in that book.
<Note>
Fills update Perps account state; they are not separate onchain transactions.
</Note>
```mermaid theme={null}
flowchart LR
A[Submit order] --> B{Matches now?}
B -->|Yes| C[Fill updates account]
B -->|No| D[Order rests in book]
D --> E[Later fill or cancel]
E --> C
```
Limit orders are useful when the trade needs an explicit price. If the order does
not fill immediately, it can rest in the book where it can be inspected,
modified, or cancelled.
## Trading Positions
Once an order fills, it changes the account's position in that market. A position
is what the account currently holds: long exposure, short exposure, or no open
exposure.
| Position | Benefits when | Loses when |
| -------- | ----------------------- | ----------------------- |
| Long | The tracked asset rises | The tracked asset falls |
| Short | The tracked asset falls | The tracked asset rises |
A fill that adds to the account's current side increases exposure. A fill against
the current side reduces exposure. When the position size reaches zero, the
position is closed. If losses exceed what the account can support, the position
can also be liquidated.
## Margin And Liquidation
Perps accounts use collateral to support open positions. Margin checks compare
the account's current value against the collateral required to open, increase, or
maintain those positions.
Margin checks use these terms:
| Term | Meaning |
| ------------------ | --------------------------------------------------------------------------------------------- |
| Collateral | Funds available to support positions and withdrawals |
| Account equity | The current value of the account after open-position gains, losses, fees, and funding effects |
| Initial margin | Collateral required to open or increase a position |
| Maintenance margin | Minimum collateral required to keep a position open |
| Liquidation | Forced position closing when account equity falls below maintenance margin |
Account equity moves as the mark price changes and as account debits or credits
settle. It can move up or down even before a position is closed.
<Tip>
If you're building on Perps, monitor account equity to decide when to reduce
exposure, add collateral, or stop placing new orders.
</Tip>
At a high level, account equity is the account's collateral plus open-position
gains or losses, minus amounts owed.
```text theme={null}
Account equity = collateral + unrealized PnL - amounts owed
```
If account equity falls below maintenance margin, the account is at risk of
liquidation. Liquidation closes exposure to prevent losses from exceeding the
account's collateral.
## Funding Payments
**Funding payments** help keep a Perps market close to its index price. They are
not order-book trades; they are account debits or credits applied to open
positions over time.
<Note>
Funding payments are different from collateral deposits. Deposits add
collateral to a Perps account; funding payments are debits or credits between
long and short positions.
</Note>
| Market state | Typical payment direction |
| ------------------------------- | ------------------------- |
| Market trades above index price | Longs pay shorts |
| Market trades below index price | Shorts pay longs |
A funding payment credited to the account increases account equity. A funding
payment owed by the account reduces account equity.
The **funding rate** is the rate used to calculate these payments. Public market
data shows funding rates over time, while private account history shows the
funding payments applied to an account.
## Realtime Account State
If you're building on Perps, realtime account state helps your integration keep a
local view in sync.
Integrations often keep a local view of account state so they can react quickly
to fills, risk changes, and collateral movements. Realtime updates help keep that
local view in sync.
| State change | Why it matters |
| --------------------- | -------------------------------------------------------------- |
| Order update | A resting order opened, changed, filled, or cancelled |
| Fill | A trade executed and changed the account's position or balance |
| Portfolio update | Account equity, margin, or position state changed |
| Funding payment | A funding debit or credit changed account state |
| Deposit or withdrawal | Collateral moved into or out of the account |
Realtime streams can reconnect or detect gaps. When that happens, the integration
should resync by refetching the account state it depends on before trusting the
local view again.
+261
View File
@@ -0,0 +1,261 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# FAQ
> Common questions about Polymarket Perps trading, pricing, margin, liquidation, fees, and integration
Common questions about Polymarket Perps.
## General
<AccordionGroup>
<Accordion title="What is Polymarket Perps?">
Polymarket Perps is a perpetual futures exchange offering continuous exposure to equities, indices, commodities, and other underlyings. Positions have no expiry. A funding rate keeps the contract price tethered to the underlying's spot price over time.
</Accordion>
<Accordion title="Which instruments can I trade?">
Fetch the current product list, symbols, underlyings, reference feeds, and
leverage settings from [`GET
/v1/info/instruments`](/perps/market-data#fetch-instruments).
</Accordion>
<Accordion title="Is the exchange on-chain or off-chain?">
Hybrid. Order matching, margin, and funding run off-chain for low latency.
Deposits and withdrawals settle on Polygon, and the exchange periodically
posts state-root commitments on-chain so off-chain activity stays verifiable.
</Accordion>
<Accordion title="Does the perp trade 24/7, even when the underlying market is closed?">
Yes. The order book, matching, funding, margin checks, and liquidations all
run continuously. What changes outside of regular hours is the set of external
feeds used to compute Index and Mark.
</Accordion>
<Accordion title="Do Polymarket Perps expire?">
No. Perpetual futures have no expiration date. A Perps position stays open
until you close it or it is force-closed by liquidation.
</Accordion>
<Accordion title="Are perps and perpetual futures the same thing?">
Yes. "Perps" is trader shorthand for "perpetual futures." Both refer to the
same derivative contract: a futures-style instrument with no expiry, anchored
to the underlying's spot price through periodic funding.
</Accordion>
<Accordion title="How are Perps different from Polymarket prediction markets?">
Polymarket's prediction markets settle Yes or No shares at $1 or $0 based on a discrete event outcome. Perps are continuous: there is no event resolution and no $0/$1 settlement. Instead you take a long or short position whose value moves with the underlying asset's price, subject to funding payments and margin requirements like any perpetual futures contract.
</Accordion>
</AccordionGroup>
## Trading and Orders
<AccordionGroup>
<Accordion title="What order types are supported?">
Limit and market-style orders are supported with `gtc`, `ioc`, and `fok` time-in-force values. GTC orders can be tagged post-only, which rejects the order if it would take liquidity. Closing orders can be tagged reduce-only, which prevents the order from increasing exposure. See [Configure Order Behavior](/perps/trading#configure-order-behavior) and [Close a Position](/perps/trading#close-a-position).
</Accordion>
<Accordion title="Why was my order rejected when my balance looks fine?">
Pre-trade margin uses the worst-case position size from your existing exposure plus all resting orders on each side, not just the current position.
```text theme={null}
WorstCaseSize = max(|Position + OpenBuys|, |Position - OpenSells|)
```
If `Equity < IM_required` for that worst case, the order is rejected even though current equity is comfortable.
</Accordion>
<Accordion title="What is self-trade prevention?">
Self-trade prevention is on by default for every order and runs in CancelMaker mode: when a taker would match against a resting order on the same account, the conflicting resting maker is canceled and the taker continues matching against other makers. It is not an API setting. There is no way to turn it off or change its mode.
</Accordion>
</AccordionGroup>
## Pricing, Mark, Index, and Funding
<AccordionGroup>
<Accordion title="What's the difference between Mark Price, Index Price, and last trade price?">
* Index Price is the protocol's estimate of the underlying's fair value, aggregated from external oracle feeds.
* Mark Price is the price the system uses for margin, PnL, liquidation, and funding.
* Last trade price is the price of the most recent fill on the local book. It is not used for margining.
See [Prices](/perps/concepts#prices).
</Accordion>
<Accordion title="What happens to Mark when external feeds go down?">
Each Mark candidate degrades gracefully to the Index. If the order book mid is
missing, the candidate falls back to Index. If there are no recent trades or
quotes, the candidate falls back to Index. If external mark feeds are
unavailable, the candidate falls back to Index. In the worst case, all
candidates converge to Index and Mark tracks Index directly.
</Accordion>
<Accordion title="How is funding calculated and when does it settle?">
A premium index is sampled every 5 seconds by walking the book for 1,000
quote-asset notional on each side. Samples are averaged over a 1-hour charge
window, run through an 8-hour formula with a fixed interest leg and clamp,
divided by 8, and capped at +/-4% per hour. Settlement happens once per
window. Longs pay shorts when the rate is positive, and shorts pay longs when
negative. The protocol takes no cut.
</Accordion>
<Accordion title="Can I see funding pressure between settlements?">
Yes. A rolling 5-second premium sample and its implied 8-hour rate are published continuously through public market data. You can also read funding history with [`GET /v1/info/funding`](/perps/market-data#list-funding-history).
</Accordion>
</AccordionGroup>
## Margin and Leverage
<AccordionGroup>
<Accordion title="What's the difference between cross and isolated margin?">
* Isolated margin funds each position with a dedicated margin allocation. Liquidation only closes the affected position.
* Cross margin shares account collateral across all cross positions. Unrealized PnL on one position can offset margin on another, but a liquidation evaluates and can unwind the whole cross account.
The web app opens new positions in isolated mode by default. Cross is opt-in through the API using leverage configuration. See [Update Leverage](/perps/trading#update-leverage).
</Accordion>
<Accordion title="What are leverage tiers and why does my margin go up as my position grows?">
Margin requirements scale with position notional through tiers. Larger
positions need proportionally more margin to limit system-wide risk and reduce
liquidation cascades. Margin is calculated incrementally across tiers,
equivalent to summing bracket by bracket. Fetch live tier values from [`GET
/v1/info/instruments`](/perps/market-data#fetch-instruments).
</Accordion>
<Accordion title="Why is maintenance margin always half of initial margin?">
By design, maintenance margin rate is half of the maximum leverage requirement
for the tier. A position is liquidated only after losing roughly half of the
margin posted to open it, which gives traders a buffer between entering a
position and being force-closed.
</Accordion>
<Accordion title="What happens between margin call and liquidation?">
Three states are evaluated continuously.
| State | Condition | Behavior |
| ----------- | ------------------- | ------------------------------------------------- |
| Healthy | `Equity >= IM` | Normal trading |
| Margin call | `MM <= Equity < IM` | Reduce-only: close exposure or deposit collateral |
| Liquidation | `Equity < MM` | System closes the position |
A deposit during margin call instantly increases equity and can restore healthy status.
</Accordion>
<Accordion title="Can I withdraw collateral while I have an open position?">
Yes, as long as `Equity_after >= IM_required` after the withdrawal. You cannot withdraw yourself into a margin call.
</Accordion>
</AccordionGroup>
## Liquidation
<AccordionGroup>
<Accordion title="When am I liquidated?">
Liquidation occurs when account equity falls below maintenance margin. Cross and isolated positions are checked independently: each isolated position has its own equity and maintenance margin, while cross uses the account's combined equity and combined maintenance margin. See [Margin and Liquidation](/perps/concepts#margin-and-liquidation).
</Accordion>
<Accordion title="Why does my liquidation price move when I haven't changed anything?">
For cross positions, the liquidation price depends on available balance:
everything in the cross account that is not this position's own equity. Mark
moves on other cross positions, size changes, or collateral changes can all
shift the liquidation price for every cross position simultaneously.
</Accordion>
<Accordion title="What happens during liquidation?">
The affected scope is flagged and new orders on it are blocked. Cross blocks
the whole account. Isolated blocks just that instrument. The system closes
positions with reduce-only IOC orders, rate-limited per account, re-evaluating
margin between fills. Cross liquidation closes one position at a time across
cycles. If equity recovers above the recovery initial margin, the flag clears.
</Accordion>
<Accordion title="What is the insurance fund and when does it step in?">
When equity falls below two-thirds of maintenance margin, order-book
liquidation is unlikely to recover value, so the system absorbs the position
directly into the insurance-fund account along with its margin. For cross
backstop, the system absorbs all cross positions plus quote balance.
</Accordion>
<Accordion title="Are there extra fees on liquidation fills?">
Yes. While flagged, every fill pays an additional liquidation fee rate on top of the maker or taker rate.
```text theme={null}
FillFee = Notional * (MakerOrTakerRate + LiquidationFeeRate)
```
Fetch the live rate per instrument from [`GET /v1/info/instruments`](/perps/market-data#fetch-instruments).
</Accordion>
</AccordionGroup>
## Fees
<AccordionGroup>
<Accordion title="What are the current maker and taker fees?">
Fees are tiered by trailing 30-day trading volume. New accounts start at the \$0 tier and move up as their volume crosses each threshold.
| 30-Day Volume ≥ | Taker | Maker |
| --------------- | ------- | -------- |
| \$0 | 0.0400% | 0.0125% |
| \$1M | 0.0370% | 0.0100% |
| \$5M | 0.0350% | 0.0080% |
| \$25M | 0.0300% | 0.0050% |
| \$100M | 0.0270% | 0.0020% |
| \$500M | 0.0250% | 0.0000% |
| \$1B | 0.0200% | -0.0050% |
Fees are calculated per fill as `abs(Price * Quantity) * Rate`, denominated in the instrument's quote asset (pUSD). Only the top tier earns a maker rebate; lower tiers pay a positive maker fee. See [Fees](/perps/learn-about-trading/fees) and [Trading Fees](/perps/trading#trading-fees).
</Accordion>
</AccordionGroup>
## API and Integration
<AccordionGroup>
<Accordion title="What's the difference between my main wallet and the proxy?">
Your main wallet signs the one-time create-proxy request and never trades directly. The returned proxy address and secret are what you use day to day: the proxy private key signs trade requests, and the `(proxy, secret)` pair authenticates private REST and WebSocket reads. This isolates the trading key from the wallet that holds funds. See [Set Up Authentication](/perps/authenticated-sessions#set-up-authentication).
</Accordion>
<Accordion title="What address identifies my Perps account?">
Your account is keyed by your EOA base address, the externally-owned account
that signs `createProxy`, not a Safe smart-contract wallet address. Even if
you use a Safe wallet elsewhere on Polymarket, your Perps balances, positions,
and history are all tracked against the underlying EOA. Use that EOA when
looking up your account or referencing it in support requests.
</Accordion>
<Accordion title="Which requests need a signature vs. just headers?">
* Signed requests with `sig`, `salt`, and `ts`: `POST /account/key`, all `/trade/*` actions, and `PATCH /trade/leverage`. The signer is the main address for `createProxy` and the proxy address for everything else.
* Header credentials with `POLYMARKET-PROXY` and `POLYMARKET-SECRET`: private `/account/*` reads.
* WebSocket authentication: send a single `auth` message after connecting, then subscribe to private channels.
See [Authenticated Sessions](/perps/authenticated-sessions).
</Accordion>
<Accordion title="How do I avoid clock-skew rejections?">
Each signed request must include a fresh `ts` request timestamp in
milliseconds and `salt`. Reused or stale values are rejected. Sync against
`GET /v1/info/time` and do not sign requests far in the past or future. The
optional `expa` field caps the validity window.
</Accordion>
<Accordion title="How do deposits and withdrawals work?">
Deposits and withdrawals are the only operations that move assets in or out of the exchange. Both settle on Polygon. Deposits credit equity as soon as the engine sees them. Withdrawals are signed off-chain and require `Equity_after >= IM_required`. See [Fund Your Account](/perps/fund-your-account).
</Accordion>
<Accordion title="Are there geographic restrictions on order placement?">
Yes. Order placement is not permitted from the United States, Canada, Cuba, Iran, North Korea, Syria, Crimea, Donetsk, or Luhansk. Builders are responsible for verifying user location before submitting orders.
</Accordion>
</AccordionGroup>
## Sessions
<AccordionGroup>
<Accordion title="What do market sessions actually change?">
Sessions affect which set of external feeds is used to compute Index Price and Mark Price. They do not change funding, margin, leverage tiers, order matching, or liquidation triggers. Those run identically around the clock.
</Accordion>
<Accordion title="What's the difference between Disrupted and Halted?">
* Disrupted means external feeds are unavailable or failing sanity checks. The system falls back to whatever feed set is still healthy.
* Halted means the underlying itself has a trading halt or corporate-action freeze.
Both are categorizations of feed-source health and only affect Index and Mark sourcing. The perp continues to match orders.
</Accordion>
</AccordionGroup>
+740
View File
@@ -0,0 +1,740 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Fund Your Account
> Deposit and withdraw pUSD collateral for Perps trading
Fund the Perps account with pUSD before placing orders. Deposits move pUSD from
the user's Polymarket wallet into the Perps account. Withdrawals move available
pUSD back to the authenticated wallet.
## Deposit Collateral
Deposit pUSD when the account needs collateral for opening or maintaining Perps
positions.
<Tabs>
<Tab title="TypeScript">
<Steps>
<Step title="Create a Secure Client">
Create a `SecureClient` for the wallet that will fund the Perps account. If you
already have a Polymarket wallet, pass it as `wallet` and include a Relayer API
key so the SDK can submit gasless transactions. If you are creating a wallet
programmatically, use a Builder API key so the SDK can create the Deposit Wallet
for that signer.
<CodeGroup>
```ts Existing Account theme={null}
import { createSecureClient, relayerApiKey } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
signer: privateKey(process.env.PRIVATE_KEY!),
apiKey: relayerApiKey({
key: process.env.RELAYER_API_KEY!,
address: process.env.RELAYER_API_KEY_ADDRESS!,
}),
});
```
```ts New Programmatic Wallet theme={null}
import { createSecureClient } from "@polymarket/client";
import { builderApiKey } from "@polymarket/client/node";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
signer: privateKey(process.env.PRIVATE_KEY!),
apiKey: builderApiKey({
key: process.env.BUILDER_API_KEY!,
secret: process.env.BUILDER_SECRET!,
passphrase: process.env.BUILDER_PASSPHRASE!,
}),
});
```
</CodeGroup>
</Step>
<Step title="Set Up Deposit Approvals">
Set up the approvals required for Perps collateral deposits. The SDK skips work
that is already complete.
```ts theme={null}
await client.setupTradingApprovals();
```
</Step>
<Step title="Deposit Collateral">
Deposit pUSD from the user's Polymarket wallet into the Perps account. Make sure
the wallet has pUSD before depositing. The minimum Perps deposit is 10 pUSD.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000n`.
```ts theme={null}
const deposit = await client.depositToPerps({
amount: 10_000_000n,
});
const receipt = await deposit.wait();
// receipt.transactionHash: TxHash
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that.
</Step>
<Step title="Verify the Deposit">
Open a Perps session and read account state after the deposit settles.
```ts theme={null}
const session = await client.openPerpsSession();
try {
const portfolio = await session.fetchPortfolio();
const deposits = await session.listDeposits().firstPage();
} finally {
await session.close();
}
```
Use `portfolio.withdrawable` to check available collateral and `deposits.items`
to reconcile deposit history.
</Step>
</Steps>
</Tab>
<Tab title="Python">
<Steps>
<Step title="Create a Secure Client">
Create an `AsyncSecureClient` for the wallet that will fund the Perps account.
If you already have a Polymarket wallet, pass it as `wallet` and include a
Relayer API key so the SDK can submit gasless transactions. If you are creating a
wallet programmatically, use a Builder API key so the SDK can create the Deposit
Wallet for that signer.
<CodeGroup>
```python Existing Account theme={null}
import os
from polymarket import AsyncSecureClient, RelayerApiKey
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
api_key=RelayerApiKey(
key=os.environ["RELAYER_API_KEY"],
address=os.environ["RELAYER_API_KEY_ADDRESS"],
),
)
```
```python New Programmatic Wallet theme={null}
import os
from polymarket import AsyncSecureClient, BuilderApiKey
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
api_key=BuilderApiKey(
key=os.environ["BUILDER_API_KEY"],
secret=os.environ["BUILDER_SECRET"],
passphrase=os.environ["BUILDER_PASSPHRASE"],
),
)
```
</CodeGroup>
</Step>
<Step title="Set Up Deposit Approvals">
Set up the approvals required for Perps collateral deposits. The SDK skips work
that is already complete.
```python theme={null}
await client.setup_trading_approvals()
```
</Step>
<Step title="Deposit Collateral">
Deposit pUSD from the user's Polymarket wallet into the Perps account. Make sure
the wallet has pUSD before depositing. The minimum Perps deposit is 10 pUSD.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000`.
```python theme={null}
deposit = await client.deposit_to_perps(amount=10_000_000)
receipt = await deposit.wait()
# receipt.transaction_hash: TransactionHash
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that.
</Step>
<Step title="Verify the Deposit">
Open a Perps session and read account state after the deposit settles.
```python theme={null}
session = await client.open_perps_session()
try:
portfolio = await session.fetch_portfolio()
deposits = await session.list_deposits().first_page()
finally:
await session.close()
```
Use `portfolio.withdrawable` to check available collateral and `deposits.items`
to reconcile deposit history.
</Step>
</Steps>
</Tab>
<Tab title="API">
<Steps>
<Step title="Check Deposit Approval">
Before depositing, the Polymarket wallet must approve the Perps deposit contract
to spend pUSD. If the approval is already in place, skip the approval call.
```solidity Approval Call theme={null}
pUSD.approve(PerpsDepositContract, maxUint256)
```
Use these contract addresses when building the approval call.
| Contract | Address |
| ---------------------- | -------------------------------------------- |
| pUSD collateral token | `0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB` |
| Perps deposit contract | `0xDCa4af75705dbB50f62437045afF9921947917d2` |
<Note>
The following steps show the Deposit Wallet batch path. If you are trading
with a Safe or Poly Proxy wallet, use an SDK that handles the wallet-specific
transaction flow for you.
</Note>
</Step>
<Step title="Build the Deposit Call">
Create the Perps deposit call. Deposit amounts use pUSD base units, so 10 pUSD
is `10000000`.
```solidity theme={null}
function deposit(address token, uint256 amount, address to);
```
Encode the deposit calldata with these arguments.
| Argument | Value |
| -------- | -------------------------------------------- |
| `token` | `0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB` |
| `amount` | `10000000` |
| `to` | Signer address for the Polymarket account. |
Build the final ordered call list. Include the approval call first only when
approval is needed.
<CodeGroup>
```json Without Approval theme={null}
[
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": "<deposit_calldata>"
}
]
```
```json With Approval theme={null}
[
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": "<approve_calldata>"
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": "<deposit_calldata>"
}
]
```
</CodeGroup>
</Step>
<Step title="Fetch a Relayer Nonce">
Fetch a fresh `WALLET` nonce before submitting the Deposit Wallet batch.
```bash theme={null}
curl -G "https://relayer-v2.polymarket.com/v1/account/transactions/params" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS" \
--data-urlencode "address=<polymarket_account_signer_address>" \
--data-urlencode "type=WALLET"
```
The response includes the nonce to sign with the batch.
```json theme={null}
{
"address": "<polymarket_account_signer_address>",
"nonce": "<wallet_nonce>"
}
```
</Step>
<Step title="Build the Deposit Wallet Batch">
Build the EIP-712 `Batch` typed data for the Deposit Wallet. Use the final
ordered call list from the previous step, and omit the approval call when
allowance is already sufficient. Set `deadline` to a Unix timestamp in seconds
after which the relayer should reject the batch.
```json theme={null}
{
"domain": {
"name": "DepositWallet",
"version": "1",
"chainId": 137,
"verifyingContract": "<polymarket_wallet_address>"
},
"primaryType": "Batch",
"types": {
"Call": [
{ "name": "target", "type": "address" },
{ "name": "value", "type": "uint256" },
{ "name": "data", "type": "bytes" }
],
"Batch": [
{ "name": "wallet", "type": "address" },
{ "name": "nonce", "type": "uint256" },
{ "name": "deadline", "type": "uint256" },
{ "name": "calls", "type": "Call[]" }
]
},
"message": {
"wallet": "<polymarket_wallet_address>",
"nonce": "<wallet_nonce>",
"deadline": "<unix_seconds>",
"calls": [
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": "<approve_calldata>"
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": "<deposit_calldata>"
}
]
}
}
```
Sign this typed data with the signer for the Polymarket account.
</Step>
<Step title="Submit the Deposit Transaction">
Submit the signed batch to the Relayer API. Use the same ordered call list you
signed in the previous step.
```bash theme={null}
curl -X POST "https://relayer-v2.polymarket.com/submit" \
-H "Content-Type: application/json" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS" \
-d '{
"type": "WALLET",
"from": "<polymarket_account_signer_address>",
"to": "0x00000000000Fb5C9ADea0298D729A0CB3823Cc07",
"nonce": "<wallet_nonce>",
"signature": "<wallet_batch_signature>",
"metadata": "Deposit pUSD to Perps",
"depositWalletParams": {
"depositWallet": "<polymarket_wallet_address>",
"deadline": "<unix_seconds>",
"calls": [
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": "<approve_calldata>"
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": "<deposit_calldata>"
}
]
}
}'
```
The response includes the relayer transaction ID.
```json theme={null}
{
"transactionID": "<transaction_id>",
"state": "STATE_NEW"
}
```
</Step>
<Step title="Poll the Deposit Transaction">
Poll the relayer transaction until it reaches `STATE_CONFIRMED` before relying
on the deposited collateral.
```bash theme={null}
curl "https://relayer-v2.polymarket.com/v1/account/transactions/<transaction_id>" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS"
```
```json theme={null}
{
"transaction_id": "<transaction_id>",
"transaction_hash": "<transaction_hash>",
"state": "STATE_CONFIRMED",
"error_msg": null
}
```
Perps may take a moment to credit the account after the onchain transaction
settles. Treat `STATE_FAILED` and `STATE_INVALID` as terminal failures.
</Step>
</Steps>
</Tab>
</Tabs>
## Withdraw Collateral
Withdraw pUSD when the account has available collateral that should return to the
authenticated wallet.
<Tabs>
<Tab title="TypeScript">
Request a withdrawal to the authenticated wallet.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000n`.
```ts theme={null}
const withdrawalId = await client.withdrawFromPerps({
amount: 10_000_000n,
});
```
The SDK signs the withdrawal request with the Polymarket account signer and
returns the Perps withdrawal ID.
To track the withdrawal, open a Perps session and list withdrawals.
```ts theme={null}
const session = await client.openPerpsSession();
try {
const withdrawals = await session.listWithdrawals().firstPage();
} finally {
await session.close();
}
```
For more details on authenticated sessions, see [Authenticated
Sessions](/perps/authenticated-sessions).
</Tab>
<Tab title="Python">
Request a withdrawal to the authenticated wallet. Amounts use raw pUSD base
units, so 10 pUSD is `10_000_000`.
```python theme={null}
withdrawal_id = await client.withdraw_from_perps(amount=10_000_000)
```
The SDK signs the withdrawal request with the Polymarket account signer and
returns the Perps withdrawal ID.
To track the withdrawal, open a Perps session and list withdrawals.
```python theme={null}
session = await client.open_perps_session()
try:
withdrawals = await session.list_withdrawals().first_page()
finally:
await session.close()
```
For more details on authenticated sessions, see [Authenticated
Sessions](/perps/authenticated-sessions).
</Tab>
<Tab title="API">
<Steps>
<Step title="Build the Withdrawal Operation">
Create a `withdraw` operation with the account signer, pUSD token, raw token
amount, and destination wallet. For withdrawals, `amount` is the raw pUSD token
amount, so 10 pUSD is `10000000`.
```json theme={null}
{
"type": "withdraw",
"args": {
"account": "<polymarket_account_signer_address>",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"to": "<polymarket_wallet_address>"
}
}
```
| Field | Value |
| --------- | ------------------------------------------ |
| `account` | Signer address for the Polymarket account. |
| `token` | pUSD collateral token address. |
| `amount` | Raw pUSD token amount. |
| `to` | Wallet that receives the withdrawal. |
</Step>
<Step title="Create Withdrawal Typed Data">
The withdrawal signature uses EIP-712 typed data with `Withdraw` as the primary
type. Use the same `account`, `token`, `amount`, and `to` values from the
withdrawal operation.
For withdrawals, `ts` is a Unix timestamp in seconds because the onchain contract
validates it against `block.timestamp`. It must match the `ts` value in the
request body.
```json theme={null}
{
"domain": {
"name": "Polymarket",
"version": "1",
"chainId": 137,
"verifyingContract": "0xDCa4af75705dbB50f62437045afF9921947917d2"
},
"primaryType": "Withdraw",
"types": {
"Withdraw": [
{ "name": "account", "type": "address" },
{ "name": "token", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "fee", "type": "uint256" },
{ "name": "to", "type": "address" },
{ "name": "salt", "type": "uint64" },
{ "name": "ts", "type": "uint64" }
]
},
"message": {
"account": "<polymarket_account_signer_address>",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"fee": "0",
"to": "<polymarket_wallet_address>",
"salt": 555555555,
"ts": 1767000014
}
}
```
| Field | Value |
| ------ | ---------------------------------------------------- |
| `salt` | Random integer generated for this signed request. |
| `ts` | Current Unix timestamp in seconds, not milliseconds. |
</Step>
<Step title="Sign Withdrawal Typed Data">
Sign the typed data with the Polymarket account signer. The example below uses
Viem.
```ts Viem theme={null}
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("<polymarket_account_signer_private_key>");
const signature = await account.signTypedData({
domain: {
name: "Polymarket",
version: "1",
chainId: 137,
verifyingContract: "0xDCa4af75705dbB50f62437045afF9921947917d2",
},
primaryType: "Withdraw",
types: {
Withdraw: [
{ name: "account", type: "address" },
{ name: "token", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "fee", type: "uint256" },
{ name: "to", type: "address" },
{ name: "salt", type: "uint64" },
{ name: "ts", type: "uint64" },
],
},
message: {
account: "<polymarket_account_signer_address>",
token: "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
amount: 10000000n,
fee: 0n,
to: "<polymarket_wallet_address>",
salt: 555555555n,
ts: 1767000014n,
},
});
```
</Step>
<Step title="Submit the Withdrawal">
Submit the signed withdrawal request to `POST /v1/account/withdraw`. Use the
same operation values, `salt`, and `ts` from the typed data.
```bash theme={null}
curl -X POST "https://api.perpetuals.polymarket.com/v1/account/withdraw" \
-H "content-type: application/json" \
-d '{
"op": {
"type": "withdraw",
"args": {
"account": "<polymarket_account_signer_address>",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"to": "<polymarket_wallet_address>"
}
},
"sig": "<signature>",
"salt": 555555555,
"ts": 1767000014
}'
```
The response indicates whether the withdrawal was accepted.
<CodeGroup>
```json Success theme={null}
{
"status": "ok",
"withdraw_id": 1234567890
}
```
```json Failure theme={null}
{
"status": "err",
"withdraw_id": 1234567890,
"error": "insufficient_balance"
}
```
</CodeGroup>
</Step>
<Step title="Track the Withdrawal">
Use the returned `withdraw_id` to match the withdrawal against history results.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/withdrawals" \
-H "polymarket-proxy: <proxy_address>" \
-H "polymarket-secret: <proxy_secret>" \
--data-urlencode "withdrawal_status=pending"
```
For more details on proxy credentials and private account-read headers, see
[Authenticated Sessions](/perps/authenticated-sessions).
</Step>
</Steps>
</Tab>
</Tabs>
## Review Funding History
Use deposit and withdrawal history to reconcile collateral movements after your
integration submits funding requests.
See [Authenticated Sessions](/perps/authenticated-sessions) for how to create an
authenticated session for private account history reads.
<Tabs>
<Tab title="TypeScript">
List deposit or withdrawal history from an authenticated Perps session.
<CodeGroup>
```ts Deposits theme={null}
import type { PerpsDeposit } from "@polymarket/client";
const session = await client.openPerpsSession();
try {
const deposits: PerpsDeposit[] = [];
for await (const page of session.listDeposits()) {
deposits.push(...page.items);
}
} finally {
await session.close();
}
```
```ts Withdrawals theme={null}
import type { PerpsWithdrawal } from "@polymarket/client";
const session = await client.openPerpsSession();
try {
const withdrawals: PerpsWithdrawal[] = [];
for await (const page of session.listWithdrawals()) {
withdrawals.push(...page.items);
}
} finally {
await session.close();
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
List deposit or withdrawal history from an authenticated Perps session.
<CodeGroup>
```python Deposits theme={null}
session = await client.open_perps_session()
try:
deposits = []
async for page in session.list_deposits():
deposits.extend(page.items)
finally:
await session.close()
```
```python Withdrawals theme={null}
session = await client.open_perps_session()
try:
withdrawals = []
async for page in session.list_withdrawals():
withdrawals.extend(page.items)
finally:
await session.close()
```
</CodeGroup>
</Tab>
<Tab title="API">
List deposit history.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/deposits" \
-H "polymarket-proxy: <proxy_address>" \
-H "polymarket-secret: <proxy_secret>"
```
List withdrawal history.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/withdrawals" \
-H "polymarket-proxy: <proxy_address>" \
-H "polymarket-secret: <proxy_secret>"
```
Use the optional `deposit_status`, `withdrawal_status`, `start_timestamp`, and
`end_timestamp` query parameters when reconciling a specific window.
</Tab>
</Tabs>
@@ -0,0 +1,49 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Architecture
> High-level architecture of the Polymarket Perps exchange
Polymarket Perps is a hybrid exchange: matching happens offchain for speed, while
custody and settlement live on Polygon. Exchange state is periodically committed
onchain so offchain activity remains verifiable.
## Offchain Matching
When a trader places an order, the matching engine maintains the order book,
applies risk checks, matches orders, and updates balances, positions, margin, and
funding offchain. This gives the exchange its latency profile because matching
does not wait on block times.
Orders are authorized by the trader, so the system can only act on trades the
trader approved.
## Onchain Components
The following operations are onchain and settle on Polygon:
* Deposits move funds from a user's Polymarket wallet into the exchange and
credit their Perps account.
* Withdrawals move funds out of the exchange back to a user's Polymarket wallet.
Deposits and withdrawals are the only way assets enter or leave the exchange.
Trading itself does not produce per-trade onchain transactions.
## State Root Commitments
The exchange periodically commits its trading state onchain in the form of state
root commitments. A state root summarizes the offchain ledger at a point in time,
including account balances, and lets observers verify that reported exchange
state matches what Polymarket has committed to Polygon.
## Data Flow
1. A trader deposits collateral from their Polymarket wallet into the exchange,
crediting their Perps account.
2. The engine credits the deposit and opens the account for trading.
3. The trader authorizes and places orders.
4. The engine matches orders and updates state offchain.
5. The engine publishes state root commitments onchain on a recurring cadence.
6. The trader authorizes a withdrawal, and funds move back to their Polymarket wallet on Polygon.
+78
View File
@@ -0,0 +1,78 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Fees
> Tiered maker and taker trading fees for Polymarket Perps
Perps trading fees are tiered by an account's trailing 30-day trading volume.
Higher-volume accounts pay lower taker fees, and the top tier earns a maker
rebate instead of paying a maker fee.
## Fee Calculation
For each fill, the fee is calculated on the notional value of the trade:
```text theme={null}
Fee = abs(Price * Quantity) * Rate
```
Fees are denominated in the instrument's quote asset (pUSD). The rate applied
to a fill is set by the account's current volume tier.
| 30-Day Volume ≥ | Taker | Maker |
| --------------- | ------- | -------- |
| \$0 | 0.0400% | 0.0125% |
| \$1M | 0.0370% | 0.0100% |
| \$5M | 0.0350% | 0.0080% |
| \$25M | 0.0300% | 0.0050% |
| \$100M | 0.0270% | 0.0020% |
| \$500M | 0.0250% | 0.0000% |
| \$1B | 0.0200% | -0.0050% |
New accounts start at the \$0 tier and move up as trailing 30-day volume crosses
each threshold.
A negative maker fee is a rebate: the maker receives the rebate amount, and the
fee recipient's internal ledger is debited by the same amount.
<Note>
A subset of accounts created during the Perps beta are temporarily on the
top-tier fee schedule regardless of trailing 30-day volume. Standard
volume-based tiering applies to these accounts once the transition period
ends.
</Note>
If you're integrating Perps, read the current fee schedule from
[Trading Fees](/perps/trading#trading-fees).
## Fee Metrics
Trailing 7-day activity metrics are available for visibility. They are a
rolling view of recent activity and do not, on their own, determine the volume
tier used to set fees.
| Metric | Meaning |
| ------------------- | ------------------------------------------------------------------------------ |
| Total volume | Total Perps trading volume |
| Taker volume | Perps volume that removed liquidity |
| Maker volume | Perps volume that added liquidity |
| Account maker share | Account maker volume divided by total exchange volume |
| Entity maker share | Entity maker volume divided by total exchange volume, when the account has one |
These metrics are cached by UTC day and may be stale by up to 24 hours.
If you're integrating Perps, read account metrics from
[Account Stats](/perps/account-management#account-stats).
## Fee Accounting
Every fill's fee flows through a single fee-recipient account on the internal
ledger:
* Taker fees credit the recipient.
* Maker fees credit the recipient at every tier where the maker rate is
non-negative.
* At the top tier the maker rate is a rebate, so it debits the recipient and
credits the maker.
+99
View File
@@ -0,0 +1,99 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Funding
> Funding rate calculation and settlement
Unlike futures contracts, perpetuals have no expiry date. Funding is the
mechanism that keeps the perpetual price anchored to the underlying's fair value.
When the perpetual trades above Index, longs pay shorts. When it trades below
Index, shorts pay longs.
Funding runs continuously across all sessions, regardless of whether the
underlying reference market is open. This keeps the convergence incentive active
and prevents positions from being left unanchored from fair value.
## How Funding Works
Funding is computed in three stages:
1. A premium index is sampled from the order book every 5 seconds.
2. Samples are averaged over the 1-hour charge window to produce an hourly rate.
3. The rate is settled against every open position at the end of the window.
### Premium Index
Every 5 seconds, the protocol takes one snapshot per market of how far the book
has drifted from Index. It walks the book for a fixed quote notional on each side.
```text theme={null}
bid_impact = VWAP of top bids filling 1,000 quote notional
ask_impact = VWAP of top asks filling 1,000 quote notional
```
If one side of the book cannot fill the notional because it is too thin or empty,
that side falls back to Index, which zeros its contribution.
The impact price difference and premium index are:
```text theme={null}
IPD = max(bid_impact - Index, 0) - max(Index - ask_impact, 0)
PremiumIndex = IPD / Index
```
A positive premium means the perpetual is trading rich versus Index. A negative
premium means it is trading cheap.
### Funding Rate
At the end of each charge window, premium samples are averaged, passed through the
8-hour funding formula, divided by 8 to get an hourly rate, and capped.
```text theme={null}
mean_P = average of PremiumIndex samples over the window
scale = 1.0 for crypto markets; 0.5 otherwise
F_8h = scale * (mean_P + clamp(0.0001 - mean_P, +/-0.0005))
FR_hour = clamp(F_8h / 8, +/-0.04)
```
* The 0.01% term is a fixed interest leg per 8 hours.
* The +/-0.05% clamp bounds the interest-versus-premium adjustment.
* Crypto markets use a 1.0 scale.
* Non-crypto markets use a 0.5 scale.
* The 4% per hour cap prevents extreme funding during sustained dislocation.
### Payment
At the end of each charge window, every open position in the market settles a
funding payment proportional to position size and the hourly rate.
| Condition | Longs | Shorts |
| ------------------------------------- | ------- | ------- |
| Hourly rate > 0, perp rich vs Index | Pay | Receive |
| Hourly rate \< 0, perp cheap vs Index | Receive | Pay |
Funding is a direct transfer between longs and shorts. The protocol takes no cut.
Settlement credits or debits the quote balance, and realized funding is tracked
separately from trading PnL.
### Interval
The charge window is 1 hour. Samples are averaged over the hour, and the hourly
rate is applied once at the end.
Between settlements, rolling premium samples and implied rates are published so
traders can see funding pressure build in real time.
## Parameters
| Parameter | Default | Description |
| ---------------- | ------------------------- | ----------------------------------------- |
| Sample interval | 5 seconds | Cadence of premium index samples |
| Impact notional | 1,000 quote notional | Quote notional used for impact VWAP |
| Interest leg | 0.01% per 8 hours | Fixed component in the 8-hour formula |
| Interest clamp | +/-0.05% | Symmetric clamp on interest minus premium |
| Funding scale | 1.0 crypto; 0.5 otherwise | Multiplier applied to the 8-hour formula |
| Charge window | 1 hour | Interval between funding settlements |
| Funding rate cap | 4% per hour | Maximum absolute hourly funding rate |
@@ -0,0 +1,43 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Geographic Restrictions
> Jurisdictions where Polymarket Perps order placement is not permitted
Polymarket restricts order placement from certain geographic locations to comply
with regulatory requirements and international sanctions. Users in restricted
jurisdictions cannot place Perps orders.
## Restricted Jurisdictions
Order placement is not permitted from:
* United States
* Canada
* Cuba
* Iran
* North Korea
* Syria
* Crimea
* Donetsk
* Luhansk
<Warning>
This list can change. Additional restrictions may apply under Polymarket
notices or applicable law.
</Warning>
## For Builders
If you're integrating Perps, enforce these restrictions before submitting orders
for a user:
* Verify the end user's location before [placing orders](/perps/trading#place-orders).
* Block order submission entirely for users in any of the listed jurisdictions.
Do not only display a warning.
* Apply the same check to any flow that results in a new position, including
programmatic strategies that act on behalf of a user.
Read-only market data is not subject to these restrictions.
@@ -0,0 +1,33 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Index Price
> How the Index Price is computed for Perps
Index Price is Polymarket's estimate of the underlying asset's fair value. It is
computed from external price feeds, aggregated to resist stale or anomalous
inputs, and published every 200 milliseconds per market.
## Feed Sources
Index Price can use feeds from external sources such as:
* Pyth
* Chainlink Data Streams
* Hyperliquid
## Feed Selection
The system selects different feeds based on the current market session so it can
use the most accurate feed set for each market. See [Market Sessions](/perps/learn-about-trading/market-sessions).
## Aggregation
Index Price is computed as a weighted average across the selected feeds after
dropping stale prices and filtering outliers. This prevents any single stale or
anomalous feed from moving the Index.
The same aggregation approach is used to build the [C3 candidate in Mark Price](/perps/learn-about-trading/mark-price),
using a separate mark feed set.
@@ -0,0 +1,94 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Liquidation Mechanics
> Detection, execution, and insurance-fund backstop
When a trader's equity drops below maintenance margin, the system closes the
position before it becomes insolvent. Normal liquidations route through the order
book as reduce-only immediate-or-cancel orders. If the breach is severe, the
position is absorbed directly by the insurance fund instead.
## Trigger
An account or isolated position is at risk when:
```text theme={null}
MarginRatio = Equity / MaintenanceMargin
```
Liquidation starts when `MarginRatio < 1.0`, which means `Equity < MM`.
Cross and isolated positions are checked independently:
* Cross uses the account's cross equity and combined cross maintenance margin.
* Isolated evaluates each isolated position using its own equity and maintenance margin.
Margin health is re-evaluated continuously, so the system reacts as soon as a new
Mark Price, fill, or deposit moves the account across the threshold.
## While Liquidating
When liquidation starts, the affected scope is flagged:
* Cross liquidation blocks new orders on every market for the account.
* Isolated liquidation blocks new orders only on the affected market.
Order submissions from the account are rejected while the flag is set. Existing
resting orders remain on the book.
## Execution
The system closes flagged positions with reduce-only immediate-or-cancel orders.
These orders execute immediately against available liquidity and cancel any
unfilled quantity. Margin health is re-evaluated between orders, so partial fills
that restore the account naturally stop the process.
### Target Selection
Cross liquidation closes one position at a time. After each fill settles, the
system re-evaluates and picks again from the remaining cross positions, so a
trader with multiple cross positions is unwound across several cycles rather than
all at once.
Isolated liquidation closes the flagged position in full.
### Order Shape
Liquidation orders are IOC, reduce-only, and market-priced. They sweep whatever
liquidity is resting on the book at the moment they land. There is no protective
spread off Mark.
## Recovery
When a liquidating account's equity recovers to or above its recovery initial
margin, the flag clears and normal order submission resumes.
If a position is fully closed during liquidation, the flag is also cleared because
the market no longer has a position to liquidate.
## Insurance-Fund Backstop
If equity falls far enough below maintenance margin that order-book liquidation is
unlikely to recover value, the system skips the order book and absorbs the
position into the insurance fund.
* Cross backstop absorbs all of the trader's cross positions plus their quote-asset balance into the insurance-fund account.
* Isolated backstop absorbs the specific isolated position and its allocated isolated margin.
Once absorbed, the insurance fund holds the position and manages it like any other
account.
## Fees
The liquidating account pays an extra liquidation fee on every fill while flagged,
on top of its normal maker or taker rate.
```text theme={null}
FillFee = Notional * (MakerOrTakerRate + LiquidationFeeRate)
```
Liquidation fee rates vary by market. If you're integrating Perps, read current
values from [Market Data](/perps/market-data#fetch-instruments).
+86
View File
@@ -0,0 +1,86 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Margin
> Initial margin, maintenance margin, and equity calculations
Margin is the collateral required to open and maintain leveraged positions. It
ensures traders have enough collateral to cover potential losses and gives the
system a buffer to close positions before they become insolvent.
There are two thresholds. **Initial margin (IM)** is the collateral required to
open or increase a position. **Maintenance margin (MM)** is the minimum
collateral required to keep a position open. When equity drops below maintenance
margin, the position is [liquidated](/perps/learn-about-trading/liquidation-mechanics).
## Equity
Equity is the real-time value of an account, incorporating all open positions at
current Mark Price.
```text theme={null}
Equity = Collateral + UnrealizedPnL(Mark) - FeesDue - FundingDue
```
### Unrealized PnL
```text theme={null}
Long PnL = PositionSize * (Mark - EntryPrice)
Short PnL = PositionSize * (EntryPrice - Mark)
```
Because equity depends on Mark Price, equity follows live mark updates. See
[Mark Price](/perps/learn-about-trading/mark-price).
## Margin Requirements
```text theme={null}
IM = Notional / L_max
MM = Notional / L_maint
```
Margin requirements scale with position size through leverage tiers. Larger
positions require proportionally more margin. Margin is calculated incrementally
across tiers, so a position spanning two tiers uses the lower tier's rate on
notional up to its upper bound and the next tier's rate on the remainder.
Margin requirements are static across sessions.
## Margin States
An account is always in one of three states.
| State | Condition | What Happens |
| ----------- | ------------------- | ---------------------------------------------- |
| Healthy | `Equity >= IM` | Normal trading |
| Margin call | `MM <= Equity < IM` | Can only reduce exposure or deposit collateral |
| Liquidation | `Equity < MM` | The system begins closing the position |
## Margin Checks
### Pre-Trade
Before any order executes, the system verifies the account can afford it:
1. Compute the new position after the order fills.
2. Calculate required initial margin using the market's leverage tiers.
3. Reject the order if equity is below required initial margin.
This prevents accounts from entering a margin-call state through new trades.
### Continuous Monitoring
The system continuously evaluates accounts:
* If equity falls below maintenance margin, liquidation begins.
* If equity is between maintenance margin and initial margin, the account may enter reduce-only mode.
## Deposits and Withdrawals
Deposits increase equity. A deposit during margin call can restore the account to
healthy status immediately.
Withdrawals require the account to remain above required initial margin after the
withdrawal. You cannot withdraw yourself into a margin call.
@@ -0,0 +1,92 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Mark Price
> How the Mark Price is computed for Perps
Mark Price is the price used across the system for margin, unrealized PnL,
liquidation triggers, funding premium computation, and risk checks. It is updated
every 200 milliseconds.
Mark Price is computed as the median of three candidates, each capturing a
different view of fair value.
```text theme={null}
Mark = median(C1, C2, C3)
```
## C1: Smoothed Order Book Mid
C1 anchors to Index and adjusts gradually based on where the local order book mid
is trading relative to it.
```text theme={null}
C1 = Index + EMA(Mid - Index)
```
* `Mid = (BestBid + BestAsk) / 2` when both sides of the book exist.
* The EMA uses a 150-second window, so C1 moves slowly and resists short-term manipulation.
* If the order book mid is unavailable, C1 falls back to Index.
## C2: Local Market Activity
C2 reflects what is actually trading on the local book.
```text theme={null}
C2 = median(BestBid, BestAsk, LastTrade)
```
* Last trade is only included if it is recent.
* Stale trades are excluded so one old print cannot anchor the price.
* If no usable values exist, C2 falls back to Index.
## C3: Aggregated External Mark
C3 is built from external mark feeds, separate from Index feeds, that provide an
independent view of fair value outside the local order book.
For each market, the system:
1. Selects active mark feeds from eligible external sources.
2. Drops stale samples.
3. Computes the candidate median and filters outliers beyond the allowed tolerance.
4. Returns the weighted average of the remaining samples.
If no valid external mark data is available, C3 falls back to Index.
## Why Three Candidates?
Using the median of three independent price signals provides resilience:
* C1 is slow-moving and resistant to sudden order book manipulation, but can lag during fast moves.
* C2 is responsive to real local trading activity, but can be influenced by thin liquidity.
* C3 is independent of the local book, but depends on external feed availability.
The median ensures that no single signal can unilaterally move Mark Price. At
least two of the three candidates must agree for the mark to shift.
## Finalization
After computing `median(C1, C2, C3)`, the raw mark is normalized before being
published:
* Snapped to the nearest tick size
* Rounded to the market's price precision
## Fallback Summary
Every input degrades gracefully to [Index Price](/perps/learn-about-trading/index-price).
| Condition | Behavior |
| ------------------------------- | ----------------------------------------------------------- |
| Index input stale | Falls back to last known market index |
| Order book mid unavailable | C1 falls back to Index |
| No recent trades or quotes | C2 falls back to Index |
| External mark feeds unavailable | C3 falls back to Index |
| All inputs missing | Mark tracks Index because all candidates fall back to Index |
In the worst case, when there is no local book, no recent trades, and no external
mark feeds, all three candidates converge to Index and Mark Price tracks Index
directly.
@@ -0,0 +1,46 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Market Sessions
> How session state affects pricing feed selection
Perps trade 24/7, but the underlying markets do not. Liquidity and external price
feed availability vary by time of day and day of week. Sessions are the system's
categorization of these conditions.
## What Sessions Affect
Sessions affect one thing: which set of external feeds is used to compute [Index Price](/perps/learn-about-trading/index-price) and the [C3 candidate in Mark Price](/perps/learn-about-trading/mark-price).
Each category can use its own feed set. For example, primary venue feeds may be
used during regular hours and after-hours venue feeds may be used overnight. If
the current category has no dedicated feed set, the system falls back to the
overnight feed set.
## What Sessions Do Not Affect
Sessions do not change:
* Funding
* Margin and leverage tiers
* Order matching
* Liquidation triggers
Those systems run identically around the clock.
## Categories
* Regular: the underlying is open and primary feeds are available.
* Overnight: the underlying is closed but some external feeds may still exist.
* Weekend: a calendar-based closed period with thin or absent external data.
* Disrupted: external feeds are unavailable or failing sanity checks.
* Halted: a trading halt or corporate-action freeze on the underlying.
## How the Category Is Determined
Each market has a schedule that defines its time windows and exceptions. The
system evaluates the schedule on time boundaries to produce the current category.
When the category changes, subsequent Index and Mark updates use the feed set
assigned to the new category.
+48
View File
@@ -0,0 +1,48 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Markets
> Listed perpetual markets and trading parameters
Polymarket Perps markets track underlying assets across indices, commodities,
crypto assets, and equities. Each market has its own trading parameters.
## Instruments
Perps markets are represented by instruments, which are the listed perpetual
contracts available to trade.
| ID | Symbol | Category | Base Asset | Max Leverage |
| -- | ------------ | ----------- | ---------- | ------------ |
| 1 | `SP500-USD` | `index` | `SP500` | 20x |
| 2 | `GOLD-USD` | `commodity` | `GOLD` | 20x |
| 3 | `WTIOIL-USD` | `commodity` | `WTIOIL` | 20x |
| 4 | `NAS100-USD` | `index` | `NAS100` | 20x |
| 5 | `SILVER-USD` | `commodity` | `SILVER` | 20x |
| 6 | `BTC-USD` | `crypto` | `BTC` | 20x |
| 7 | `ETH-USD` | `crypto` | `ETH` | 20x |
| 8 | `SOL-USD` | `crypto` | `SOL` | 20x |
| 9 | `SPCX-USD` | `equity` | `SPCX` | 10x |
Each instrument also includes details that shape how it trades:
* Underlying asset
* Collateral and quote asset
* Price and quantity precision
* Tick size
* Minimum order size
* Risk tiers and leverage caps
* Mark, index, and funding configuration
<Note>
Market parameters can change as markets evolve. Builders should read live
instrument details from [Market Data](/perps/market-data#fetch-instruments)
before submitting orders.
</Note>
## Price Feeds
Each market tracks an underlying market through external price feeds. Those
feeds drive the [Index Price](/perps/learn-about-trading/index-price), and the Index Price helps anchor the [Mark Price](/perps/learn-about-trading/mark-price).
@@ -0,0 +1,53 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Overview
> The market mechanics behind Perps trading
Perps markets follow a small set of system rules. This section explains how
those rules work so you can anticipate how positions are valued, when they are
at risk, and why account balances change.
<CardGroup cols={2}>
<Card title="Architecture" icon="sitemap" href="/perps/learn-about-trading/architecture">
How offchain matching and onchain settlement fit together.
</Card>
<Card title="Markets" icon="list" href="/perps/learn-about-trading/markets">
Available Perps markets and the parameters that shape trading.
</Card>
<Card title="Fees" icon="percent" href="/perps/learn-about-trading/fees">
What each fill costs and how the volume-based fee tiers work.
</Card>
<Card title="Margin" icon="scale-balanced" href="/perps/learn-about-trading/margin">
Equity, initial margin, maintenance margin, and margin states.
</Card>
<Card title="Liquidation Mechanics" icon="triangle-exclamation" href="/perps/learn-about-trading/liquidation-mechanics">
How liquidation is detected, executed, and backstopped.
</Card>
<Card title="Funding" icon="repeat" href="/perps/learn-about-trading/funding">
How funding rates are computed and settled against open positions.
</Card>
<Card title="Mark Price" icon="chart-line" href="/perps/learn-about-trading/mark-price">
How the price used for margin, PnL, and liquidation is computed.
</Card>
<Card title="Index Price" icon="crosshairs" href="/perps/learn-about-trading/index-price">
How the underlying's fair value is sourced and aggregated.
</Card>
<Card title="Market Sessions" icon="clock" href="/perps/learn-about-trading/market-sessions">
How session state affects pricing feed selection.
</Card>
<Card title="Geographic Restrictions" icon="globe" href="/perps/learn-about-trading/geographic-restrictions">
Where order placement is restricted.
</Card>
</CardGroup>
+846
View File
@@ -0,0 +1,846 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Market Data
> Discover Perps markets and monitor public market activity
Use market data to understand what can be traded, where the market is trading
now, and how activity has changed over time.
<Tabs>
<Tab title="TypeScript">
The TypeScript examples on this page use a `PublicClient`. The same market-data
methods are also available on `SecureClient` instances.
```ts theme={null}
import { createPublicClient } from "@polymarket/client";
const client = createPublicClient();
```
</Tab>
<Tab title="Python">
The Python examples on this page use an `AsyncPublicClient`. The same market-data
methods are also available on `AsyncSecureClient` instances.
```python theme={null}
from polymarket import AsyncPublicClient
client = AsyncPublicClient()
```
</Tab>
<Tab title="API">
Use the Perps REST API production URL.
```text theme={null}
https://api.perpetuals.polymarket.com
```
</Tab>
</Tabs>
## Fetch Instruments
Fetch instruments before your integration lets users choose or submit orders for
a Perps market. Instrument data gives you the constraints needed to validate that
workflow.
<Tabs>
<Tab title="TypeScript">
Fetch the available instruments.
```ts theme={null}
const instruments = await client.fetchPerpsInstruments();
// instruments: PerpsInstrument[]
```
where `PerpsInstrument` is:
<CodeGroup>
```ts Type theme={null}
type PerpsInstrument = {
id: PerpsInstrumentId;
category: PerpsInstrumentCategory;
symbol: string;
baseAsset: string;
quoteAsset: string;
fundingInterval: PerpsFundingInterval;
quantityDecimals: number;
priceDecimals: number;
priceBounds: DecimalString;
liquidationFee: DecimalString;
maxOrderCount: number;
minNotional: DecimalString;
maxMarketNotional: DecimalString;
maxLimitNotional: DecimalString;
maxLeverage: number;
riskTiers: PerpsRiskTier[];
};
type PerpsRiskTier = {
lowerBound: DecimalString;
maxLeverage: number;
};
```
```json Example theme={null}
{
"id": 1,
"category": "crypto",
"symbol": "BTC-PERP",
"baseAsset": "BTC",
"quoteAsset": "USD",
"fundingInterval": "1h",
"quantityDecimals": 4,
"priceDecimals": 2,
"priceBounds": "0.1",
"liquidationFee": "0.01",
"maxOrderCount": 200,
"minNotional": "1",
"maxMarketNotional": "100000",
"maxLimitNotional": "1000000",
"maxLeverage": 10,
"riskTiers": [{ "lowerBound": "0", "maxLeverage": 10 }]
}
```
</CodeGroup>
`PerpsInstrument` includes the market metadata and trading constraints your app
needs before submitting orders.
| Field | Description |
| ------------------- | ------------------------------------------------------------- |
| `id` | Instrument identifier. |
| `category` | Market category, such as crypto, index, equity, or commodity. |
| `symbol` | Human-readable market symbol. |
| `baseAsset` | Base asset for the instrument. |
| `quoteAsset` | Quote asset used for prices. |
| `fundingInterval` | Funding interval for the instrument, such as `1h`. |
| `quantityDecimals` | Decimal precision for quantities. |
| `priceDecimals` | Decimal precision for prices. |
| `priceBounds` | Price-bound value for the instrument. |
| `liquidationFee` | Liquidation fee value for the instrument. |
| `maxOrderCount` | Maximum order count for the instrument. |
| `minNotional` | Minimum notional value for orders. |
| `maxMarketNotional` | Maximum notional value for market orders. |
| `maxLimitNotional` | Maximum notional value for limit orders. |
| `maxLeverage` | Maximum leverage allowed for the instrument. |
| `riskTiers` | Risk tiers for larger position sizes. |
</Tab>
<Tab title="Python">
Fetch the available instruments.
```python theme={null}
instruments = await client.fetch_perps_instruments()
# instruments: tuple[PerpsInstrument, ...]
```
Filter by instrument ID when you already know the market you need.
```python theme={null}
instruments = await client.fetch_perps_instruments(instrument_id=1)
```
`PerpsInstrument` includes the market metadata and trading constraints your app
needs before submitting orders.
```json Example theme={null}
{
"id": 1,
"category": "crypto",
"symbol": "BTC-PERP",
"base_asset": "BTC",
"quote_asset": "USD",
"funding_interval": "1h",
"quantity_decimals": 4,
"price_decimals": 2,
"price_bounds": "0.1",
"liquidation_fee": "0.01",
"max_order_count": 200,
"min_notional": "1",
"max_market_notional": "100000",
"max_limit_notional": "1000000",
"max_leverage": 10,
"risk_tiers": [{ "lower_bound": "0", "max_leverage": 10 }]
}
```
`PerpsInstrument` exposes these attributes:
| Attribute | Description |
| --------------------------- | ------------------------------------------------------------- |
| `id` | Instrument identifier. |
| `category` | Market category, such as crypto, index, equity, or commodity. |
| `symbol` | Human-readable market symbol. |
| `base_asset` | Base asset for the instrument. |
| `quote_asset` | Quote asset used for prices. |
| `funding_interval` | Funding interval for the instrument, such as `1h`. |
| `quantity_decimals` | Decimal precision for quantities. |
| `price_decimals` | Decimal precision for prices. |
| `price_bounds` | Price-bound value for the instrument. |
| `liquidation_fee` | Liquidation fee value for the instrument. |
| `max_order_count` | Maximum order count for the instrument. |
| `min_notional` | Minimum notional value for orders. |
| `max_market_notional` | Maximum notional value for market orders. |
| `max_limit_notional` | Maximum notional value for limit orders. |
| `max_leverage` | Maximum leverage allowed for the instrument. |
| `risk_tiers` | Risk tiers for larger position sizes. |
| `risk_tiers[].lower_bound` | Lower notional bound for the risk tier. |
| `risk_tiers[].max_leverage` | Maximum leverage allowed for the risk tier. |
</Tab>
<Tab title="API">
Fetch the available instruments.
```bash theme={null}
curl "https://api.perpetuals.polymarket.com/v1/info/instruments"
```
Filter by instrument ID when you already know the market you need.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/instruments" \
--data-urlencode "instrument_id=1"
```
The response is an array of instruments.
```json theme={null}
[
{
"instrument_id": 1,
"instrument_type": "perpetual",
"category": "crypto",
"symbol": "BTC-PERP",
"base_asset": "BTC",
"quote_asset": "USD",
"funding_interval": "1h",
"quantity_decimals": 4,
"price_decimals": 2,
"price_bounds": "0.1",
"liquidation_fee": "0.01",
"max_order_count": 200,
"min_notional": "1",
"max_market_notional": "100000",
"max_limit_notional": "1000000",
"max_leverage": 10,
"risk_tiers": [{ "lower_bound": "0", "max_leverage": 10 }]
}
]
```
Each instrument object includes the market metadata and trading constraints your
app needs before submitting orders.
| Field | Description |
| --------------------------- | --------------------------------------------------------------------- |
| `instrument_id` | Instrument identifier. |
| `instrument_type` | Instrument type. Perps instruments use `perpetual`. |
| `category` | Market category, such as `crypto`, `index`, `equity`, or `commodity`. |
| `symbol` | Human-readable market symbol. |
| `base_asset` | Base asset for the instrument. |
| `quote_asset` | Quote asset used for prices. |
| `funding_interval` | Funding interval for the instrument, such as `1h`. |
| `quantity_decimals` | Decimal precision for quantities. |
| `price_decimals` | Decimal precision for prices. |
| `price_bounds` | Price-bound value for the instrument. |
| `liquidation_fee` | Liquidation fee value for the instrument. |
| `max_order_count` | Maximum order count for the instrument. |
| `min_notional` | Minimum notional value for orders. |
| `max_market_notional` | Maximum notional value for market orders. |
| `max_limit_notional` | Maximum notional value for limit orders. |
| `max_leverage` | Maximum leverage allowed for the instrument. |
| `risk_tiers` | Risk tiers for larger position sizes. |
| `risk_tiers[].lower_bound` | Lower notional bound for the risk tier. |
| `risk_tiers[].max_leverage` | Maximum leverage allowed for the risk tier. |
</Tab>
</Tabs>
## Fetch Tickers
Use tickers when you need a lightweight view of where one or more markets are
trading now.
<Tabs>
<Tab title="TypeScript">
Fetch one ticker when you already know which instrument your integration is
tracking.
```ts theme={null}
const ticker = await client.fetchPerpsTicker({
instrumentId: instrument.id,
});
// ticker: PerpsTicker
```
Fetch all tickers to build a market list or refresh a dashboard.
```ts theme={null}
const tickers = await client.fetchPerpsTickers();
// tickers: PerpsTicker[]
```
where `PerpsTicker` is:
<CodeGroup>
```ts Type theme={null}
type PerpsTicker = {
instrumentId: PerpsInstrumentId;
symbol: string;
indexPrice: DecimalString;
markPrice: DecimalString;
lastPrice: DecimalString;
midPrice: DecimalString;
openInterest: DecimalString;
fundingRate: DecimalString;
nextFunding: EpochMilliseconds;
volume24h?: DecimalString;
openPrice?: DecimalString;
timestamp?: EpochMilliseconds;
};
```
```json Example theme={null}
{
"instrumentId": 1,
"symbol": "BTC-PERP",
"indexPrice": "65000.00",
"markPrice": "65012.50",
"lastPrice": "65010.00",
"midPrice": "65011.25",
"openInterest": "125.4",
"fundingRate": "0.0001",
"nextFunding": 1766124000000,
"volume24h": "2450000",
"openPrice": "64250.00",
"timestamp": 1766120400000
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Fetch one ticker when you already know which instrument your integration is
tracking.
```python theme={null}
ticker = await client.fetch_perps_ticker(instrument_id=instrument.id)
# ticker: PerpsTicker
```
Fetch all tickers to build a market list or refresh a dashboard.
```python theme={null}
tickers = await client.fetch_perps_tickers()
# tickers: tuple[PerpsTicker, ...]
```
Use the returned ticker for current price, open interest, and funding state.
```json Example theme={null}
{
"instrument_id": 1,
"symbol": "BTC-PERP",
"index_price": "65000.00",
"mark_price": "65012.50",
"last_price": "65010.00",
"mid_price": "65011.25",
"open_interest": "125.4",
"funding_rate": "0.0001",
"next_funding": 1766124000000,
"volume_24h": "2450000",
"open_price": "64250.00",
"timestamp": 1766120400000
}
```
</Tab>
<Tab title="API">
Fetch all tickers to build a market list or refresh a dashboard.
```bash theme={null}
curl "https://api.perpetuals.polymarket.com/v1/info/tickers"
```
Filter by instrument ID when you only need one ticker.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/tickers" \
--data-urlencode "instrument_id=1"
```
The response is an array of ticker snapshots.
```json theme={null}
[
{
"instrument_id": 1,
"symbol": "BTC-PERP",
"index_price": "65000.00",
"mark_price": "65012.50",
"last_price": "65010.00",
"mid_price": "65011.25",
"open_interest": "125.4",
"funding_rate": "0.0001",
"next_funding": 1766124000000,
"timestamp": 1766120400000
}
]
```
</Tab>
</Tabs>
## Fetch the Order Book
Use the order book before choosing an order price or size. It shows available
liquidity at the requested depth.
<Tabs>
<Tab title="TypeScript">
Choose how many price levels to request. Supported depths are `10`, `100`,
`500`, and `1000`. When omitted, the SDK requests `100` levels.
```ts theme={null}
// depth: PerpsBookDepth
const depth = 100;
```
Fetch the book for the selected instrument. Bids and asks are returned as price
levels with decimal string prices and quantities.
```ts theme={null}
const book = await client.fetchPerpsBook({
instrumentId: instrument.id,
depth,
});
const bestBid = book.bids[0];
const bestAsk = book.asks[0];
// book: PerpsBook
// bestBid: PerpsBookLevel | undefined
// bestAsk: PerpsBookLevel | undefined
```
where `PerpsBook` and `PerpsBookLevel` are:
<CodeGroup>
```ts Type theme={null}
type PerpsBook = {
instrumentId: PerpsInstrumentId;
bids: PerpsBookLevel[];
asks: PerpsBookLevel[];
timestamp: EpochMilliseconds;
sequence: number;
};
type PerpsBookLevel = {
price: DecimalString;
quantity: DecimalString;
};
```
```json Example theme={null}
{
"instrumentId": 1,
"bids": [
{ "price": "65010.00", "quantity": "0.75" },
{ "price": "65009.50", "quantity": "1.2" }
],
"asks": [
{ "price": "65012.50", "quantity": "0.6" },
{ "price": "65013.00", "quantity": "1.1" }
],
"timestamp": 1766120400000,
"sequence": 123456
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Choose how many price levels to request. Supported depths are `10`, `100`,
`500`, and `1000`. When omitted, the SDK requests `100` levels.
```python theme={null}
depth = 100
```
Fetch the book for the selected instrument. Bids and asks are returned as price
levels with decimal string prices and quantities.
```python theme={null}
book = await client.fetch_perps_book(
instrument_id=instrument.id,
depth=depth,
)
best_bid = book.bids[0] if book.bids else None
best_ask = book.asks[0] if book.asks else None
# book: PerpsBook
# best_bid: PerpsBookLevel | None
# best_ask: PerpsBookLevel | None
```
Use `book.bids` and `book.asks` for bid and ask price levels.
```json Example theme={null}
{
"instrument_id": 1,
"bids": [
{ "price": "65010.00", "quantity": "0.75" },
{ "price": "65009.50", "quantity": "1.2" }
],
"asks": [
{ "price": "65012.50", "quantity": "0.6" },
{ "price": "65013.00", "quantity": "1.1" }
],
"timestamp": 1766120400000,
"sequence": 123456
}
```
</Tab>
<Tab title="API">
Fetch the order book for an instrument. Supported depths are `10`, `100`, `500`,
and `1000`; when omitted, the API uses `100`.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/book" \
--data-urlencode "instrument_id=1" \
--data-urlencode "depth=100"
```
The response returns bids and asks as `[price, quantity]` levels.
```json theme={null}
{
"instrument_id": 1,
"bids": [
["65010.00", "0.75"],
["65009.50", "1.2"]
],
"asks": [
["65012.50", "0.6"],
["65013.00", "1.1"]
],
"timestamp": 1766120400000,
"sequence": 123456
}
```
Each `bids` and `asks` level is `[price, quantity]`.
</Tab>
</Tabs>
## List Candles
Use candles when your workflow needs time-bucketed price history for charts,
backtests, or trading signals.
<Tabs>
<Tab title="TypeScript">
The SDK paginates candle history. When `start` is omitted, it starts from the
past 24 hours.
```ts theme={null}
import { PerpsKlineInterval } from "@polymarket/client";
const pages = client.listPerpsCandles({
instrumentId: instrument.id,
interval: PerpsKlineInterval.OneMinute,
});
for await (const page of pages) {
for (const candle of page.items) {
// candle: PerpsCandle
}
}
```
where `PerpsCandle` is:
<CodeGroup>
```ts Type theme={null}
type PerpsCandle = {
timestamp: EpochMilliseconds;
open: DecimalString;
high: DecimalString;
low: DecimalString;
close: DecimalString;
volume: DecimalString;
trades: number;
};
```
```json Example theme={null}
{
"timestamp": 1766120400000,
"open": "65000.00",
"high": "65025.00",
"low": "64980.00",
"close": "65010.00",
"volume": "42.5",
"trades": 18
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
The SDK paginates candle history. When `start` is omitted, it starts from the
past 24 hours.
```python theme={null}
pages = client.list_perps_candles(
instrument_id=instrument.id,
interval="1m",
)
async for page in pages:
for candle in page.items:
# candle: PerpsCandle
pass
```
Each candle contains one OHLCV bucket.
```json Example theme={null}
{
"timestamp": 1766120400000,
"open": "65000.00",
"high": "65025.00",
"low": "64980.00",
"close": "65010.00",
"volume": "42.5",
"trades": 18
}
```
</Tab>
<Tab title="API">
Fetch candles for an instrument and interval. `start_timestamp` is required;
`end_timestamp` is optional. The API returns at most 1000 candles per request.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/klines" \
--data-urlencode "instrument_id=1" \
--data-urlencode "interval=1m" \
--data-urlencode "start_timestamp=1766120400000"
```
The response returns candles in `data` and a `more` flag for continuation.
```json theme={null}
{
"data": [
[1766120400000, "65000.00", "65025.00", "64980.00", "65010.00", "42.5", 18]
],
"more": false
}
```
Each candle is `[timestamp, open, high, low, close, volume, trades]`.
</Tab>
</Tabs>
## List Trades
Use public trades when recent executions matter more than aggregated candles.
This is useful for trade tape views and execution analysis.
<Tabs>
<Tab title="TypeScript">
The SDK paginates trade history, including cursor handling and boundary
deduplication.
```ts theme={null}
const pages = client.listPerpsTrades({
instrumentId: instrument.id,
});
for await (const page of pages) {
for (const trade of page.items) {
// trade: PerpsPublicTrade
}
}
```
where `PerpsPublicTrade` is:
<CodeGroup>
```ts Type theme={null}
type PerpsPublicTrade = {
tradeId: PerpsTradeId;
instrumentId: PerpsInstrumentId;
side: PerpsSide;
price: DecimalString;
quantity: DecimalString;
timestamp: EpochMilliseconds;
hash?: TxHash;
};
```
```json Example theme={null}
{
"tradeId": 987654,
"instrumentId": 1,
"side": "long",
"price": "65010.00",
"quantity": "0.25",
"timestamp": 1766120400000,
"hash": "0x1111111111111111111111111111111111111111111111111111111111111111"
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
The SDK paginates trade history, including cursor handling and boundary
deduplication.
```python theme={null}
pages = client.list_perps_trades(instrument_id=instrument.id)
async for page in pages:
for trade in page.items:
# trade: PerpsTrade
pass
```
Each trade contains one public execution.
```json Example theme={null}
{
"trade_id": 987654,
"instrument_id": 1,
"side": "long",
"price": "65010.00",
"quantity": "0.25",
"timestamp": 1766120400000,
"hash": "0x1111111111111111111111111111111111111111111111111111111111111111"
}
```
</Tab>
<Tab title="API">
Fetch recent public trades for an instrument. `start_timestamp` and
`end_timestamp` are optional. The API returns at most 100 trades per request.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/trades" \
--data-urlencode "instrument_id=1"
```
The response returns trades in `data` and a `more` flag for continuation.
```json theme={null}
{
"data": [
{
"trade_id": 987654,
"instrument_id": 1,
"side": "long",
"price": "65010.00",
"quantity": "0.25",
"timestamp": 1766120400000,
"hash": "0x1111111111111111111111111111111111111111111111111111111111111111"
}
],
"more": false
}
```
</Tab>
</Tabs>
## List Funding History
Use funding-rate history when estimating carry costs or explaining why Perps
prices differ from the index over time.
<Tabs>
<Tab title="TypeScript">
The SDK paginates funding-rate history.
```ts theme={null}
const pages = client.listPerpsFundingHistory({
instrumentId: instrument.id,
});
for await (const page of pages) {
for (const fundingRate of page.items) {
// fundingRate: PerpsFundingRate
}
}
```
where `PerpsFundingRate` is:
<CodeGroup>
```ts Type theme={null}
type PerpsFundingRate = {
fundingRate: DecimalString;
timestamp: EpochMilliseconds;
};
```
```json Example theme={null}
{
"fundingRate": "0.0001",
"timestamp": 1766120400000
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
The SDK paginates funding-rate history.
```python theme={null}
pages = client.list_perps_funding_history(instrument_id=instrument.id)
async for page in pages:
for funding_rate in page.items:
# funding_rate: PerpsFundingRate
pass
```
Each funding-rate entry contains one historical observation.
```json Example theme={null}
{
"funding_rate": "0.0001",
"timestamp": 1766120400000
}
```
</Tab>
<Tab title="API">
Fetch historical funding rates for an instrument. `start_timestamp` and
`end_timestamp` are optional. The API returns at most 100 funding-rate entries
per request.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/info/funding" \
--data-urlencode "instrument_id=1"
```
The response returns funding rates in `data` and a `more` flag for continuation.
```json theme={null}
{
"data": [
{
"funding_rate": "0.0001",
"timestamp": 1766120400000
}
],
"more": false
}
```
</Tab>
</Tabs>
+78
View File
@@ -0,0 +1,78 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Overview
> Start here for Polymarket perpetual markets
Polymarket Perps are perpetual contracts that track an underlying asset such as
an index, commodity, crypto asset, or equity. Perps trade continuously and do not
expire, so traders can open, manage, and close leveraged positions without
waiting for a market resolution event.
<Note>
Polymarket Perps is in early access. Access requires a valid [Perps referral
link or code](/perps/referral-program).
</Note>
## How Perps Work
A Perps trade starts as an order in the order book. When it fills, it becomes a
position whose value changes as the tracked market moves, until the trader closes
it or the system closes it because the account can no longer support the risk.
<CardGroup cols={2}>
<Card title="Prices" icon="chart-line">
A Perps market has a traded price from the order book and reference prices
used by the system. The index price tracks the underlying asset, while the
mark price is used for account equity, margin checks, and liquidation risk.
</Card>
<Card title="Trading Positions" icon="arrow-right-arrow-left">
Trading a Perps market creates or changes a position. A long position benefits
when the tracked asset rises, and a short position benefits when it falls.
Orders trade through the order book; fills update the account's position,
balance, and history.
</Card>
<Card title="Margin And Liquidation" icon="shield">
Perps require collateral to support open positions. That collateral is the
account's margin: the buffer that covers losses while a position is open. If
account equity falls too far relative to the required margin, the position can
be liquidated to close exposure.
</Card>
<Card title="Funding Payments" icon="repeat">
Funding payments keep the contract price close to the index price. When a
market trades above its index price, long positions generally pay short
positions. When it trades below its index price, shorts generally pay longs.
</Card>
</CardGroup>
## Building on Perps
If you are here to see what you can build on top of Polymarket Perps, common use
cases include:
* Trading bots that react to market signals
* Market making systems that quote Perps markets
* Portfolio dashboards that track balances and positions
* Risk monitors that track margin and liquidation risk
* Market data products that analyze books, trades, and funding payments
## Next Steps
<CardGroup cols={3}>
<Card title="Concepts" icon="book" href="/perps/concepts">
Learn the shared terms used across Perps docs.
</Card>
<Card title="Learn About Trading" icon="book-open" href="/perps/learn-about-trading/overview">
Understand the market mechanics behind Perps.
</Card>
<Card title="Place Your First Trade" icon="bolt" href="/perps/place-your-first-trade">
Build a first end-to-end Perps trading flow.
</Card>
</CardGroup>
+245
View File
@@ -0,0 +1,245 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Place Your First Trade
> Learn how to prepare a Perps account and submit a first buy order
This guide walks through the shortest safe path to a first Perps trade. You will
set up a Perps account, add collateral, and place a small buy order.
You need a Polymarket account with pUSD available before you start. Create one at
[polymarket.com](https://polymarket.com).
<Note>
Building directly against the API? Start with [Authenticated
Sessions](/perps/authenticated-sessions), then use [Fund Your
Account](/perps/fund-your-account) and [Trading](/perps/trading).
</Note>
<Tabs>
<Tab title="TypeScript">
<Steps>
<Step title="Install the SDK">
Install the Unified TypeScript SDK with the package manager of your choice.
<CodeGroup>
```bash pnpm theme={null}
pnpm add @polymarket/client@beta viem
```
```bash npm theme={null}
npm install @polymarket/client@beta viem
```
```bash yarn theme={null}
yarn add @polymarket/client@beta viem
```
</CodeGroup>
<Note>
This page uses Viem for wallet signing. See the [TypeScript tooling
guide](/dev-tooling/typescript#wallet-integrations) for other wallet library
integrations.
</Note>
</Step>
<Step title="Create a Secure Client">
Create a `SecureClient` with the wallet and signer that owns the Perps account.
Include a Relayer API key so the SDK can submit gasless transactions.
```ts theme={null}
import { createSecureClient, relayerApiKey } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
signer: privateKey(process.env.PRIVATE_KEY!),
apiKey: relayerApiKey({
key: process.env.RELAYER_API_KEY!,
address: process.env.RELAYER_API_KEY_ADDRESS!,
}),
});
```
Create a [Relayer API key](https://polymarket.com/settings?tab=api-keys) from
polymarket.com → Settings → API Keys.
</Step>
<Step title="Fund the Account">
Set up the approvals required for Perps collateral deposits, then deposit pUSD
from the user's Polymarket wallet into the Perps account. The minimum Perps
deposit is 10 pUSD. Amounts use raw pUSD base units, so 10 pUSD is
`10_000_000n`.
```ts theme={null}
await client.setupTradingApprovals();
const deposit = await client.depositToPerps({
amount: 10_000_000n,
});
await deposit.wait();
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that. See [Fund Your
Account](/perps/fund-your-account) for the full funding workflow.
</Step>
<Step title="Open a Perps Session">
Open a Perps session for private reads and trading.
```ts theme={null}
const session = await client.openPerpsSession();
```
</Step>
<Step title="Choose a Market">
Fetch the available Perps instruments and choose the market you want to trade.
```ts theme={null}
const instruments = await client.fetchPerpsInstruments();
const instrument = instruments.find(
(instrument) => instrument.symbol === "SP500-USD",
);
if (instrument === undefined) {
throw new Error("Instrument not found.");
}
```
</Step>
<Step title="Place the Order">
Place a long buy order for `1` quantity unit of `SP500-USD` with an explicit
limit price of `100` USD per quantity unit and immediate-or-cancel execution.
```ts theme={null}
import { OrderSide, PerpsTimeInForce } from "@polymarket/client";
const order = await session.placeOrder({
instrumentId: instrument.id,
side: OrderSide.BUY,
quantity: "1",
price: "100",
timeInForce: PerpsTimeInForce.IOC,
});
// order.id: PerpsOrderId
```
The returned order includes the accepted order state. See
[Trading](/perps/trading) for direction, order behavior, cancellation, and state
reconciliation.
</Step>
</Steps>
</Tab>
<Tab title="Python">
<Steps>
<Step title="Install the SDK">
Install the Unified Python SDK with the package manager of your choice.
<CodeGroup>
```bash uv theme={null}
uv add polymarket-client
```
```bash pip theme={null}
pip install polymarket-client
```
```bash poetry theme={null}
poetry add polymarket-client
```
</CodeGroup>
</Step>
<Step title="Create a Secure Client">
Create an `AsyncSecureClient` with the wallet and signer that owns the Perps
account. Include a Relayer API key so the SDK can submit gasless transactions.
```python theme={null}
import os
from polymarket import AsyncSecureClient, RelayerApiKey
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
api_key=RelayerApiKey(
key=os.environ["RELAYER_API_KEY"],
address=os.environ["RELAYER_API_KEY_ADDRESS"],
),
)
```
Create a [Relayer API key](https://polymarket.com/settings?tab=api-keys) from
polymarket.com → Settings → API Keys.
</Step>
<Step title="Fund the Account">
Set up the approvals required for Perps collateral deposits, then deposit pUSD
from the user's Polymarket wallet into the Perps account. The minimum Perps
deposit is 10 pUSD. Amounts use raw pUSD base units, so 10 pUSD is `10_000_000`.
```python theme={null}
await client.setup_trading_approvals()
deposit = await client.deposit_to_perps(amount=10_000_000)
await deposit.wait()
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that. See [Fund Your
Account](/perps/fund-your-account) for the full funding workflow.
</Step>
<Step title="Open a Perps Session">
Open a Perps session for private reads and trading.
```python theme={null}
session = await client.open_perps_session()
```
</Step>
<Step title="Choose a Market">
Fetch the available Perps instruments and choose the market you want to trade.
```python theme={null}
instruments = await client.fetch_perps_instruments()
instrument = next(
(item for item in instruments if item.symbol == "SP500-USD"),
None,
)
if instrument is None:
raise RuntimeError("Instrument not found.")
```
</Step>
<Step title="Place the Order">
Place a long buy order for `1` quantity unit of `SP500-USD` with an explicit
limit price of `100` USD per quantity unit and immediate-or-cancel execution.
```python theme={null}
result = await session.place_order(
instrument_id=instrument.id,
side="BUY",
quantity="1",
price="100",
time_in_force="ioc",
)
# result.order.id: PerpsOrderId
```
The returned order includes the accepted order state. See
[Trading](/perps/trading) for direction, order behavior, cancellation, and state
reconciliation.
</Step>
</Steps>
</Tab>
</Tabs>
+86
View File
@@ -0,0 +1,86 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Rate Limits
> IP rate limits, action rate limits, and WebSocket limits for Perps integrations
Perps uses separate rate-limit buckets for different traffic types. Hitting one
bucket does not consume another bucket, so request volume, account trading
actions, and WebSocket traffic should be monitored separately.
## How Limits Work
Use the error type to identify which bucket rejected the request or message.
| Bucket | Scope | Applies To | Error |
| ---------------------- | -------------- | ---------------------------------- | --------------------------------------------------------------------- |
| IP | IP address | HTTP request volume | HTTP `429` or `ip_rate_limited` |
| Action | Perps account | Order placement and trade actions | `action_rate_limited` |
| WebSocket message | IP address | Inbound WebSocket messages | `message_rate_limited` |
| WebSocket subscription | WebSocket link | Active subscriptions on one socket | Per-channel subscription error when the subscription cap is exhausted |
## IP Rate Limits
Every IP address gets **1,000 weighted tokens per minute**. Each HTTP request
consumes tokens equal to its request weight.
Use scoped requests when possible. Broad, unfiltered reads consume more of the IP
budget than narrow reads.
| Request Pattern | Weight |
| ------------------------------ | --------------------------------------------- |
| Lightweight reads | 1 |
| Broad unfiltered reads | Up to 20 |
| Order book depth 10 | 2 |
| Order book depth 100 | 5 |
| Order book depth 500 | 10 |
| Order book depth 1000 | 20 |
| Batch order actions | `1 + floor(n / 20)`, where `n` is order count |
| Account orders by ID | 1 |
| Account orders without ID | 10 |
| Open orders by instrument | 1 |
| Open orders without instrument | 20 |
## Action Rate Limits
Every account has an action budget from its current limit tier. The default tier
is **5,000 action tokens per minute** with an open-order cap of **1,000**.
Action limits are account-scoped, not IP-scoped. Batching can reduce IP weight,
but it does not reduce the number of order actions consumed.
| Action | Action Cost |
| ------------------- | --------------------------- |
| Place one order | 1 token |
| Place 10 orders | 10 tokens |
| Auto-cancel request | 10 tokens |
| Open-order count | Limited by account tier cap |
Legacy request-rate fields on limit-tier responses are not used for request-rate
enforcement. Use the IP bucket for request volume and the action bucket for
account trading activity.
## WebSocket Limits
WebSocket connections have separate limits for connection count, active
subscriptions, and inbound messages.
| Limit | Scope | Value |
| ---------------------- | ---------- | ---------------------------------- |
| Concurrent connections | IP address | 50 WebSocket connections |
| Active subscriptions | Connection | 100 active subscriptions |
| Inbound messages | IP address | 1,000 messages per minute |
| Subscribe message | Message | 1 message token |
| Unsubscribe message | Message | 1 message token |
| Trade post message | Message | Same batch-size weighting as trade |
| Other post messages | Message | 1 message token |
## Integration Guidance
* Scope reads whenever possible. For example, request one instrument's open orders instead of all open orders.
* Batch order placement when it reduces request volume, but do not expect batching to reduce action-token usage.
* Treat `429`, `ip_rate_limited`, `action_rate_limited`, and `message_rate_limited` as retryable after backoff.
* Track active WebSocket subscriptions per connection so reconnects do not accidentally exceed the subscription cap.
* If you operate many users behind shared infrastructure, monitor IP usage separately from account action usage.
+987
View File
@@ -0,0 +1,987 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Realtime Updates
> Stream public Perps market data
Stream public market data as prices, books, trades, candles, tickers, and market
statistics change.
<Note>
Private order, fill, and account-state reconciliation is covered in [Reconcile
Trade State](/perps/trading#reconcile-trade-state).
</Note>
Start with the stream that matches the view you are building. Subscribe to the
updates you need, read events while the view is active, then stop the stream when
the view no longer needs live data.
<Tabs>
<Tab title="TypeScript">
Subscribe from a `PublicClient` and iterate over the merged event stream.
```ts theme={null}
import { createPublicClient } from "@polymarket/client";
const client = createPublicClient();
const stream = await client.subscribe([
{ topic: "perps.bbo", instrumentId: 1 },
{ topic: "perps.trades", instrumentId: 1 },
]);
for await (const event of stream) {
switch (event.type) {
case "bbo":
// event: PerpsBboEvent
break;
case "trade":
// event: PerpsTradeEvent
break;
}
if (shouldClose) {
await stream.close();
}
}
```
The stream yields typed events for each subscription and can be closed when the
live view no longer needs updates.
</Tab>
<Tab title="Python">
Subscribe from an `AsyncPublicClient` and iterate over the merged event stream.
```python theme={null}
from polymarket import AsyncPublicClient
from polymarket.streams import PerpsBboSpec, PerpsTradesSpec
client = AsyncPublicClient()
stream = await client.subscribe(
[
PerpsBboSpec(instrument_id=1),
PerpsTradesSpec(instrument_id=1),
]
)
async for event in stream:
if event.type == "bbo":
# event: PerpsBboEvent
pass
elif event.type == "trade":
# event: PerpsTradeEvent
pass
if should_close:
await stream.close()
```
The stream yields typed events for each subscription and can be closed when the
live view no longer needs updates.
</Tab>
<Tab title="API">
Connect to the Perps WebSocket production URL.
```text theme={null}
wss://ws.perpetuals.polymarket.com/v1/ws
```
The example below opens a JavaScript WebSocket client, subscribes to public
market-data updates, then unsubscribes and closes the connection.
```ts theme={null}
const ws = new WebSocket("wss://ws.perpetuals.polymarket.com/v1/ws");
const channels = ["bbo::1", "trades::1", "klines::1::1m"];
ws.addEventListener("open", () => {
ws.send(
JSON.stringify({
id: 1,
req: "sub",
chs: channels,
}),
);
});
ws.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
// message: public market data frame
});
function unsubscribeAndClose() {
ws.send(
JSON.stringify({
id: 2,
req: "unsub",
chs: channels,
}),
);
ws.close();
}
```
Use `req: "sub"` to subscribe and `req: "unsub"` with the same `chs` values to
unsubscribe. Each request may include an `id` for request-response matching.
</Tab>
</Tabs>
## Best Bid and Offer
Use best bid and offer updates for top-of-book quotes.
<Tabs>
<Tab title="TypeScript">
Subscribe to best bid and offer updates for one instrument.
```ts theme={null}
const bbo = await client.subscribe([{ topic: "perps.bbo", instrumentId: 1 }]);
for await (const event of bbo) {
// event: PerpsBboEvent
}
```
After subscribing, the stream yields `PerpsBboEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsBboEvent = {
topic: "perps.bbo";
type: "bbo";
channel: string;
timestamp: number;
sequence: number;
payload: {
instrumentId: number;
bidPrice: string;
bidQuantity: string;
askPrice: string;
askQuantity: string;
};
};
```
```json Example theme={null}
{
"topic": "perps.bbo",
"type": "bbo",
"channel": "bbo::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrumentId": 1,
"bidPrice": "99.50",
"bidQuantity": "10.00",
"askPrice": "100.50",
"askQuantity": "10.00"
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to best bid and offer updates for one instrument.
```python theme={null}
from polymarket.streams import PerpsBboSpec
bbo = await client.subscribe(PerpsBboSpec(instrument_id=1))
async for event in bbo:
# event: PerpsBboEvent
pass
```
After subscribing, the stream yields `PerpsBboEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.bbo",
"type": "bbo",
"channel": "bbo::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrument_id": 1,
"bid_price": "99.50",
"bid_quantity": "10.00",
"ask_price": "100.50",
"ask_quantity": "10.00"
}
}
```
</Tab>
<Tab title="API">
Subscribe to best bid and offer updates for one instrument.
```json Subscribe theme={null}
{
"id": 1,
"req": "sub",
"chs": ["bbo::<instrument_id>"]
}
```
After subscribing, the stream emits BBO update frames like this.
```json theme={null}
{
"ch": "bbo::1",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"iid": 1,
"bp": "99.50",
"bq": "10.00",
"ap": "100.50",
"aq": "10.00"
}
}
```
</Tab>
</Tabs>
## Order Book
Use order book updates for depth across bid and ask price levels.
<Tabs>
<Tab title="TypeScript">
Subscribe to order book updates for one instrument.
```ts theme={null}
const book = await client.subscribe([{ topic: "perps.book", instrumentId: 1 }]);
for await (const event of book) {
// event: PerpsBookEvent
}
```
After subscribing, the stream yields `PerpsBookEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsBookEvent = {
topic: "perps.book";
type: "book";
channel: string;
timestamp: number;
sequence: number;
payload: {
instrumentId: number;
bids: Array<{ price: string; quantity: string }>;
asks: Array<{ price: string; quantity: string }>;
};
};
```
```json Example theme={null}
{
"topic": "perps.book",
"type": "book",
"channel": "book::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrumentId": 1,
"bids": [{ "price": "100.00", "quantity": "10.00" }],
"asks": [{ "price": "101.00", "quantity": "8.00" }]
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to order book updates for one instrument.
```python theme={null}
from polymarket.streams import PerpsBookSpec
book = await client.subscribe(PerpsBookSpec(instrument_id=1))
async for event in book:
# event: PerpsBookEvent
pass
```
After subscribing, the stream yields `PerpsBookEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.book",
"type": "book",
"channel": "book::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrument_id": 1,
"bids": [{ "price": "100.00", "quantity": "10.00" }],
"asks": [{ "price": "101.00", "quantity": "8.00" }]
}
}
```
</Tab>
<Tab title="API">
Subscribe to order book updates for one instrument.
```json Subscribe theme={null}
{
"id": 2,
"req": "sub",
"chs": ["book::<instrument_id>"]
}
```
After subscribing, the stream emits book update frames like this.
```json theme={null}
{
"ch": "book::1",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"b": [["100.00", "10.00"]],
"a": [["101.00", "8.00"]]
}
}
```
</Tab>
</Tabs>
## Trades
Use trades to update recent-print lists, last-trade displays, or execution-based
analytics.
<Tabs>
<Tab title="TypeScript">
Subscribe to public trade updates for one instrument.
```ts theme={null}
const trades = await client.subscribe([
{ topic: "perps.trades", instrumentId: 1 },
]);
for await (const event of trades) {
// event: PerpsTradeEvent
}
```
After subscribing, the stream yields `PerpsTradeEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsTradeEvent = {
topic: "perps.trades";
type: "trade";
channel: string;
timestamp: number;
sequence: number;
payload: {
tradeId: number;
instrumentId: number;
side: "long" | "short";
price: string;
quantity: string;
timestamp: number;
hash?: string;
};
};
```
```json Example theme={null}
{
"topic": "perps.trades",
"type": "trade",
"channel": "trades::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"tradeId": 1,
"instrumentId": 1,
"side": "long",
"price": "100.00",
"quantity": "10.00",
"timestamp": 1767225600000,
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to public trade updates for one instrument.
```python theme={null}
from polymarket.streams import PerpsTradesSpec
trades = await client.subscribe(PerpsTradesSpec(instrument_id=1))
async for event in trades:
# event: PerpsTradeEvent
pass
```
After subscribing, the stream yields `PerpsTradeEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.trades",
"type": "trade",
"channel": "trades::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"trade_id": 1,
"instrument_id": 1,
"side": "long",
"price": "100.00",
"quantity": "10.00",
"timestamp": 1767225600000,
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
}
}
```
</Tab>
<Tab title="API">
Subscribe to public trade updates for one instrument.
```json Subscribe theme={null}
{
"id": 3,
"req": "sub",
"chs": ["trades::<instrument_id>"]
}
```
After subscribing, the stream emits trade update frames like this.
```json theme={null}
{
"ch": "trades::1",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"tid": 1,
"iid": 1,
"side": "long",
"p": "100.00",
"qty": "10.00",
"ts": 1767225600000,
"hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
}
}
```
</Tab>
</Tabs>
## Tickers
Use ticker updates for the current mark, index, last price, open interest, and
funding state.
<Tabs>
<Tab title="TypeScript">
Subscribe to ticker updates for one instrument or all active instruments.
<CodeGroup>
```ts Subscribe to one market theme={null}
const tickers = await client.subscribe([
{ topic: "perps.tickers", instrumentId: 1 },
]);
```
```ts Subscribe to all markets theme={null}
const tickers = await client.subscribe([{ topic: "perps.tickers" }]);
```
</CodeGroup>
```ts theme={null}
for await (const event of tickers) {
// event: PerpsTickerEvent
}
```
Omit `instrumentId` to subscribe to ticker updates for all active instruments.
After subscribing, the stream yields `PerpsTickerEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsTickerEvent = {
topic: "perps.tickers";
type: "ticker";
channel: string;
timestamp: number;
sequence: number;
payload: {
instrumentId: number;
indexPrice: string;
markPrice: string;
lastPrice: string;
midPrice: string;
openInterest: string;
fundingRate: string;
nextFunding: number;
};
};
```
```json Example theme={null}
{
"topic": "perps.tickers",
"type": "ticker",
"channel": "tickers::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrumentId": 1,
"indexPrice": "100.00",
"markPrice": "100.00",
"lastPrice": "100.00",
"midPrice": "100.00",
"openInterest": "10.00",
"fundingRate": "0.0001",
"nextFunding": 1767225600000
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to ticker updates for one instrument or all active instruments.
<CodeGroup>
```python Subscribe to one market theme={null}
from polymarket.streams import PerpsTickersSpec
tickers = await client.subscribe(PerpsTickersSpec(instrument_id=1))
```
```python Subscribe to all markets theme={null}
from polymarket.streams import PerpsTickersSpec
tickers = await client.subscribe(PerpsTickersSpec())
```
</CodeGroup>
```python theme={null}
async for event in tickers:
# event: PerpsTickerEvent
pass
```
Omit `instrument_id` to subscribe to ticker updates for all active instruments.
After subscribing, the stream yields `PerpsTickerEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.tickers",
"type": "ticker",
"channel": "tickers::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrument_id": 1,
"index_price": "100.00",
"mark_price": "100.00",
"last_price": "100.00",
"mid_price": "100.00",
"open_interest": "10.00",
"funding_rate": "0.0001",
"next_funding": 1767225600000
}
}
```
</Tab>
<Tab title="API">
Subscribe to ticker updates for one instrument or all active instruments.
<CodeGroup>
```json Subscribe to one market theme={null}
{
"id": 4,
"req": "sub",
"chs": ["tickers::<instrument_id>"]
}
```
```json Subscribe to all markets theme={null}
{
"id": 5,
"req": "sub",
"chs": ["tickers::all"]
}
```
</CodeGroup>
After subscribing, the stream emits ticker update frames like this.
```json theme={null}
{
"ch": "tickers::1",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"iid": 1,
"idx": "100.00",
"mark": "100.00",
"last": "100.00",
"mid": "100.00",
"oi": "10.00",
"fr": "0.0001",
"nxf": 1767225600000
}
}
```
</Tab>
</Tabs>
## Statistics
Use statistics for 24-hour volume, opening price, and the rolling kline window.
<Tabs>
<Tab title="TypeScript">
Subscribe to 24-hour statistics for one instrument or all active instruments.
<CodeGroup>
```ts Subscribe to one market theme={null}
const statistics = await client.subscribe([
{ topic: "perps.statistics", instrumentId: 1 },
]);
```
```ts Subscribe to all markets theme={null}
const statistics = await client.subscribe([{ topic: "perps.statistics" }]);
```
</CodeGroup>
```ts theme={null}
for await (const event of statistics) {
// event: PerpsStatisticEvent
}
```
Omit `instrumentId` to subscribe to statistics updates for all active instruments.
After subscribing, the stream yields `PerpsStatisticEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsStatisticEvent = {
topic: "perps.statistics";
type: "statistic";
channel: string;
timestamp: number;
sequence: number;
payload: {
instrumentId: number;
volume: string;
openPrice: string;
klines: Array<{
timestamp: number;
open: string;
high: string;
low: string;
close: string;
volume: string;
trades: number;
}>;
};
};
```
```json Example theme={null}
{
"topic": "perps.statistics",
"type": "statistic",
"channel": "statistics::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrumentId": 1,
"volume": "1000.00",
"openPrice": "100.50",
"klines": [
{
"timestamp": 1767225600000,
"open": "100.00",
"high": "105.00",
"low": "99.00",
"close": "102.00",
"volume": "500.00",
"trades": 42
}
]
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to 24-hour statistics for one instrument or all active instruments.
<CodeGroup>
```python Subscribe to one market theme={null}
from polymarket.streams import PerpsStatisticsSpec
statistics = await client.subscribe(PerpsStatisticsSpec(instrument_id=1))
```
```python Subscribe to all markets theme={null}
from polymarket.streams import PerpsStatisticsSpec
statistics = await client.subscribe(PerpsStatisticsSpec())
```
</CodeGroup>
```python theme={null}
async for event in statistics:
# event: PerpsStatisticEvent
pass
```
Omit `instrument_id` to subscribe to statistics updates for all active
instruments.
After subscribing, the stream yields `PerpsStatisticEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.statistics",
"type": "statistic",
"channel": "statistics::1",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrument_id": 1,
"volume": "1000.00",
"open_price": "100.50",
"klines": [
{
"timestamp": 1767225600000,
"open": "100.00",
"high": "105.00",
"low": "99.00",
"close": "102.00",
"volume": "500.00",
"trades": 42
}
]
}
}
```
</Tab>
<Tab title="API">
Subscribe to 24-hour statistics for one instrument or all active instruments.
<CodeGroup>
```json Subscribe to one market theme={null}
{
"id": 6,
"req": "sub",
"chs": ["statistics::<instrument_id>"]
}
```
```json Subscribe to all markets theme={null}
{
"id": 7,
"req": "sub",
"chs": ["statistics::all"]
}
```
</CodeGroup>
After subscribing, the stream emits statistics update frames like this.
```json theme={null}
{
"ch": "statistics::1",
"ts": 1767225600000,
"sq": 1234567890,
"data": {
"iid": 1,
"vol": "1000.00",
"open": "100.50",
"klines": [
[1767225600000, "100.00", "105.00", "99.00", "102.00", "500.00", 42]
]
}
}
```
</Tab>
</Tabs>
## Candles
Use candles to update charts with live OHLCV data.
<Tabs>
<Tab title="TypeScript">
Subscribe to candle updates for one instrument and interval.
```ts theme={null}
import { PerpsKlineInterval } from "@polymarket/client";
const candles = await client.subscribe([
{
topic: "perps.candles",
instrumentId: 1,
interval: PerpsKlineInterval.OneMinute,
},
]);
for await (const event of candles) {
// event: PerpsCandleEvent
}
```
The public stream supports `1m`, `5m`, `15m`, `1h`, `4h`, `1d`, and `1w`
candle intervals.
After subscribing, the stream yields `PerpsCandleEvent` objects like this.
<CodeGroup>
```ts Type theme={null}
type PerpsCandleEvent = {
topic: "perps.candles";
type: "candle";
channel: string;
timestamp: number;
sequence: number;
payload: {
instrumentId: number;
interval: "1m" | "5m" | "15m" | "1h" | "4h" | "1d" | "1w";
candles: Array<{
timestamp: number;
open: string;
high: string;
low: string;
close: string;
volume: string;
trades: number;
}>;
};
};
```
```json Example theme={null}
{
"topic": "perps.candles",
"type": "candle",
"channel": "klines::1::1m",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrumentId": 1,
"interval": "1m",
"candles": [
{
"timestamp": 1767225600000,
"open": "100.00",
"high": "105.00",
"low": "99.00",
"close": "102.00",
"volume": "500.00",
"trades": 42
}
]
}
}
```
</CodeGroup>
</Tab>
<Tab title="Python">
Subscribe to candle updates for one instrument and interval.
```python theme={null}
from polymarket.streams import PerpsCandlesSpec
candles = await client.subscribe(
PerpsCandlesSpec(
instrument_id=1,
interval="1m",
)
)
async for event in candles:
# event: PerpsCandleEvent
pass
```
The public stream supports `1m`, `5m`, `15m`, `1h`, `4h`, `1d`, and `1w`
candle intervals.
After subscribing, the stream yields `PerpsCandleEvent` objects like this.
```json Example theme={null}
{
"topic": "perps.candles",
"type": "candle",
"channel": "klines::1::1m",
"timestamp": 1767225600000,
"sequence": 1234567890,
"payload": {
"instrument_id": 1,
"interval": "1m",
"candles": [
{
"timestamp": 1767225600000,
"open": "100.00",
"high": "105.00",
"low": "99.00",
"close": "102.00",
"volume": "500.00",
"trades": 42
}
]
}
}
```
</Tab>
<Tab title="API">
Subscribe to candle updates for one instrument and interval.
```json Subscribe theme={null}
{
"id": 8,
"req": "sub",
"chs": ["klines::<instrument_id>::1m"]
}
```
The public stream supports `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `6h`, `12h`,
`1d`, and `1w` candle intervals.
After subscribing, the stream emits kline update frames like this.
```json theme={null}
{
"ch": "klines::1::1m",
"ts": 1767225600000,
"sq": 1234567890,
"data": [[1767225600000, "100.00", "105.00", "99.00", "102.00", "500.00", 42]]
}
```
</Tab>
</Tabs>
+84
View File
@@ -0,0 +1,84 @@
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Referral Program
> Earn a share of Perps trading fees from traders you refer
Refer traders to Polymarket Perps and earn a share of the trading fees they pay.
Each account has one Perps referral code. Share your Perps link, and when a new
trader opens Perps through it, your code is applied to their account
automatically.
<Note>
This is the first version of the Perps referral program. The mechanics,
attribution rules, and program details are set for launch and may change as
the program expands.
</Note>
## How It Works
Every Perps account has one referral code. Your referral code and your Perps
invite code are the same string, so the same link invites traders and credits you
for the referral.
```text theme={null}
https://polymarket.com/perps?c={code}
```
When someone opens Perps through your link, your code is applied to their account
automatically. You start earning on the trading fees they generate after they are
attributed to your code.
A referral code can be applied only once. An account keeps the first code it is
given and cannot switch to a different code later. You also cannot apply your own
code.
## Rewards
You earn **20% of the trading fees** paid by every Perps trader you refer. There
is no cap on how much a single referred trader can earn you.
| Detail | Perps referral program |
| ------------- | --------------------------------------------------- |
| Reward | 20% of trading fees paid by referred Perps traders |
| Recipient | The referrer |
| Trader bonus | No separate bonus is paid to the trader you invite |
| Per-user cap | No cap on how much one referred trader can earn you |
| Payout timing | Weekly |
## Code Limits
A standard Perps referral code can be used by up to **15 people**. After 15
traders sign up through your code, anyone who opens your link sees a referral
expired state.
If you are running a larger campaign and need more than 15 uses, reach out to the
Polymarket team to discuss a higher limit.
## Payouts
Referral earnings are paid out weekly. You can see referral payouts in your
Perpetuals portfolio history.
## Find and Track Your Code
Your referral code is available from your profile and on Perps market pages, so
you can copy and share it while you trade.
The referrals dashboard shows how the program is performing for your account:
* Sign-ups against your code limit
* Total trading volume from referred traders
* Total referral earnings
* Per-referral details, including the trader, sign-up time, and earnings
## Perps vs. Prediction Market Referrals
The Perps referral program is separate from the prediction market referral
program. They use different codes and track earnings independently.
Referring a Perps trader does not affect your prediction market referrals, and a
prediction market referral does not affect your Perps referrals. Each program
shows up in its own place.
File diff suppressed because it is too large Load Diff