Update Polymarket documentation (2026-02-19)

- Added new documentation URLs from llms.txt index
- Updated TARGET.md with 244 total documentation pages
- Scraped new pages for trading, concepts, and API reference sections
- Updated changelog and new index pages
This commit is contained in:
AI Agent
2026-02-19 14:31:02 +01:00
parent 81f77eff3c
commit b2a29fe51f
250 changed files with 33306 additions and 9659 deletions
+232
View File
@@ -0,0 +1,232 @@
> ## 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.
# Getting Started
> One-time setup for market making on Polymarket
Before you can start market making, you need to complete these one-time setup steps — deposit USDC.e to Polygon, deploy a wallet, approve tokens for trading, and generate API credentials.
<Steps>
<Step title="Deposit USDC.e">
Market makers need USDC.e on Polygon to fund their trading operations.
| Method | Best For | Documentation |
| ----------------------- | ------------------------------------ | ---------------------------------------------------- |
| Bridge API | Automated deposits from other chains | [Bridge Deposit](/trading/bridge/deposit) |
| Direct Polygon transfer | Already have USDC.e on Polygon | N/A |
| Cross-chain bridge | Large deposits from Ethereum | [Supported Assets](/trading/bridge/supported-assets) |
### Using the Bridge API
```typescript theme={null}
// Get deposit addresses for your Polymarket wallet
const deposit = await fetch("https://bridge.polymarket.com/deposit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
address: "YOUR_POLYMARKET_WALLET_ADDRESS",
}),
});
// Returns deposit addresses for EVM, SVM, and BTC networks
const addresses = await deposit.json();
// Send USDC to the appropriate address for your source chain
```
</Step>
<Step title="Deploy a Wallet">
### EOA (Externally Owned Account)
Standard Ethereum wallet. You pay for all onchain transactions (approvals, splits, merges, trade execution).
### Safe Wallet (Recommended)
Gnosis Safe-based wallet deployed via Polymarket's relayer. Benefits:
* **Gasless transactions** — Polymarket pays gas fees for onchain operations
* **Contract wallet** — Enables advanced features like batched transactions
Deploy a Safe wallet using the Relayer Client:
<CodeGroup>
```typescript TypeScript theme={null}
import { RelayClient, RelayerTxType } from "@polymarket/builder-relayer-client";
const client = new RelayClient(
"https://relayer-v2.polymarket.com/",
137, // Polygon mainnet
signer,
builderConfig,
RelayerTxType.SAFE,
);
// Deploy the Safe wallet
const response = await client.deploy();
const result = await response.wait();
console.log("Safe Address:", result?.proxyAddress);
```
```python Python theme={null}
from py_builder_relayer_client.client import RelayClient
# client initialized with builder_config
# Deploy the Safe wallet
response = client.deploy()
result = response.wait()
print("Safe Address:", result.get("proxyAddress"))
```
</CodeGroup>
<Info>
See [Gasless Transactions](/trading/gasless) for full Relayer Client setup
including local and remote signing configurations.
</Info>
</Step>
<Step title="Approve Tokens">
Before trading, you must approve the exchange contracts to spend your tokens.
### Required Approvals
| Token | Spender | Purpose |
| -------------------- | --------------------- | -------------------------------- |
| USDC.e | CTF Contract | Split USDC.e into outcome tokens |
| CTF (outcome tokens) | CTF Exchange | Trade outcome tokens |
| CTF (outcome tokens) | Neg Risk CTF Exchange | Trade neg-risk market tokens |
### Contract Addresses (Polygon Mainnet)
```typescript theme={null}
const ADDRESSES = {
USDCe: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
CTF: "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045",
CTF_EXCHANGE: "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E",
NEG_RISK_CTF_EXCHANGE: "0xC5d563A36AE78145C45a50134d48A1215220f80a",
NEG_RISK_ADAPTER: "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296",
};
```
### Approve via Relayer Client
<CodeGroup>
```typescript TypeScript theme={null}
import { ethers } from "ethers";
import { Interface } from "ethers/lib/utils";
const erc20Interface = new Interface([
"function approve(address spender, uint256 amount) returns (bool)",
]);
// Approve USDCe for CTF contract
const approveTx = {
to: ADDRESSES.USDCe,
data: erc20Interface.encodeFunctionData("approve", [
ADDRESSES.CTF,
ethers.constants.MaxUint256,
]),
value: "0",
};
const response = await client.execute([approveTx], "Approve USDCe for CTF");
await response.wait();
```
```python Python theme={null}
from web3 import Web3
USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"
MAX_UINT256 = 2**256 - 1
approve_tx = {
"to": USDC,
"data": Web3().eth.contract(
address=USDC,
abi=[{
"name": "approve",
"type": "function",
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"outputs": [{"type": "bool"}]
}]
).encode_abi(abi_element_identifier="approve", args=[CTF, MAX_UINT256]),
"value": "0"
}
response = client.execute([approve_tx], "Approve USDC for CTF")
response.wait()
```
</CodeGroup>
</Step>
<Step title="Generate API Credentials">
To place orders and access authenticated endpoints, you need L2 API credentials derived from your wallet.
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient } from "@polymarket/clob-client";
const client = new ClobClient("https://clob.polymarket.com", 137, signer);
// Derive API credentials from your wallet
const credentials = await client.createOrDeriveApiKey();
console.log("API Key:", credentials.key);
console.log("Secret:", credentials.secret);
console.log("Passphrase:", credentials.passphrase);
```
```python Python theme={null}
from py_clob_client.client import ClobClient
import os
private_key = os.getenv("PRIVATE_KEY")
temp_client = ClobClient("https://clob.polymarket.com", key=private_key, chain_id=137)
credentials = temp_client.create_or_derive_api_creds()
```
</CodeGroup>
Once you have credentials, initialize the client for authenticated operations:
<CodeGroup>
```typescript TypeScript theme={null}
const tradingClient = new ClobClient(
"https://clob.polymarket.com",
137,
wallet,
credentials,
);
```
```python Python theme={null}
client = ClobClient(
"https://clob.polymarket.com",
key=private_key,
chain_id=137,
creds=credentials,
)
```
</CodeGroup>
See [Authentication](/trading/overview#authentication) for full details on signature types and REST API headers.
</Step>
</Steps>
***
## Next Steps
<CardGroup cols={2}>
<Card title="Trading" icon="chart-line" href="/market-makers/trading">
Post limit orders and manage quotes
</Card>
<Card title="Market Data" icon="database" href="/market-data/overview">
Connect to real-time market data
</Card>
</CardGroup>
+339
View File
@@ -0,0 +1,339 @@
> ## 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.
# Inventory Management
> Managing outcome token inventory for market making
Market makers need outcome tokens on both sides to quote a market. The three core inventory operations are **splitting** USDC.e into YES/NO token pairs, **merging** pairs back into USDC.e, and **redeeming** winning tokens after resolution — all executed gaslessly through the Relayer Client.
<Info>
For a full breakdown of how the Conditional Token Framework works, see [CTF
Overview](/trading/ctf/overview). This page focuses on the MM workflow using
the Relayer Client.
</Info>
***
## Splitting USDC.e into Tokens
Split converts USDC.e into equal amounts of YES and NO tokens — creating the inventory you need to quote both sides of a market.
<CodeGroup>
```typescript TypeScript theme={null}
import { ethers } from "ethers";
import { Interface } from "ethers/lib/utils";
import { RelayClient, Transaction } from "@polymarket/builder-relayer-client";
const CTF_ADDRESS = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";
const USDCe_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const ctfInterface = new Interface([
"function splitPosition(address collateralToken, bytes32 parentCollectionId, bytes32 conditionId, uint[] partition, uint amount)",
]);
// Split $1000 USDCe into YES/NO tokens
const amount = ethers.utils.parseUnits("1000", 6); // USDCe has 6 decimals
const splitTx: Transaction = {
to: CTF_ADDRESS,
data: ctfInterface.encodeFunctionData("splitPosition", [
USDCe_ADDRESS, // collateralToken
ethers.constants.HashZero, // parentCollectionId (always zero for Polymarket)
conditionId, // conditionId from market
[1, 2], // partition: [YES, NO]
amount,
]),
value: "0",
};
const response = await client.execute([splitTx], "Split USDCe into tokens");
const result = await response.wait();
console.log("Split completed:", result?.transactionHash);
```
```python Python theme={null}
from web3 import Web3
CTF_ADDRESS = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"
USDCe_ADDRESS = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
ctf_abi = [{
"name": "splitPosition",
"type": "function",
"inputs": [
{"name": "collateralToken", "type": "address"},
{"name": "parentCollectionId", "type": "bytes32"},
{"name": "conditionId", "type": "bytes32"},
{"name": "partition", "type": "uint256[]"},
{"name": "amount", "type": "uint256"}
],
"outputs": []
}]
# Split $1000 USDCe into YES/NO tokens
amount = 1000 * 10**6 # USDCe has 6 decimals
split_tx = {
"to": CTF_ADDRESS,
"data": Web3().eth.contract(
address=CTF_ADDRESS, abi=ctf_abi
).encode_abi(
abi_element_identifier="splitPosition",
args=[
USDCe_ADDRESS,
bytes(32), # parentCollectionId (always zero)
condition_id, # conditionId from market
[1, 2], # partition: [YES, NO]
amount,
]
),
"value": "0"
}
response = client.execute([split_tx], "Split USDCe into tokens")
response.wait()
```
</CodeGroup>
After splitting 1000 USDC.e, you receive 1000 YES tokens and 1000 NO tokens. Your USDC.e balance decreases by 1000.
***
## Merging Tokens to USDC.e
Merge converts equal amounts of YES and NO tokens back into USDC.e — useful for reducing exposure, exiting a market, or freeing up capital.
<CodeGroup>
```typescript TypeScript theme={null}
const ctfInterface = new Interface([
"function mergePositions(address collateralToken, bytes32 parentCollectionId, bytes32 conditionId, uint[] partition, uint amount)",
]);
// Merge 500 YES + 500 NO back to 500 USDCe
const amount = ethers.utils.parseUnits("500", 6);
const mergeTx: Transaction = {
to: CTF_ADDRESS,
data: ctfInterface.encodeFunctionData("mergePositions", [
USDCe_ADDRESS,
ethers.constants.HashZero,
conditionId,
[1, 2],
amount,
]),
value: "0",
};
const response = await client.execute([mergeTx], "Merge tokens to USDCe");
await response.wait();
```
```python Python theme={null}
merge_abi = [{
"name": "mergePositions",
"type": "function",
"inputs": [
{"name": "collateralToken", "type": "address"},
{"name": "parentCollectionId", "type": "bytes32"},
{"name": "conditionId", "type": "bytes32"},
{"name": "partition", "type": "uint256[]"},
{"name": "amount", "type": "uint256"}
],
"outputs": []
}]
# Merge 500 YES + 500 NO back to 500 USDCe
amount = 500 * 10**6
merge_tx = {
"to": CTF_ADDRESS,
"data": Web3().eth.contract(
address=CTF_ADDRESS, abi=merge_abi
).encode_abi(
abi_element_identifier="mergePositions",
args=[USDCe_ADDRESS, bytes(32), condition_id, [1, 2], amount]
),
"value": "0"
}
response = client.execute([merge_tx], "Merge tokens to USDCe")
response.wait()
```
</CodeGroup>
After merging 500 of each, your YES and NO balances decrease by 500 and your USDC.e balance increases by 500.
***
## Redeeming After Resolution
Once a market resolves, redeem winning tokens for USDC.e. Each winning token is worth $1 — losing tokens redeem for $0.
### Check Resolution Status
<CodeGroup>
```typescript TypeScript theme={null}
const market = await clobClient.getMarket(conditionId);
if (market.closed) {
const winningToken = market.tokens.find((t) => t.winner);
console.log("Winning outcome:", winningToken?.outcome);
}
```
```python Python theme={null}
market = clob_client.get_market(condition_id)
if market.get("closed"):
winning = next(t for t in market["tokens"] if t.get("winner"))
print("Winning outcome:", winning["outcome"])
```
</CodeGroup>
### Redeem Winning Tokens
<CodeGroup>
```typescript TypeScript theme={null}
const ctfInterface = new Interface([
"function redeemPositions(address collateralToken, bytes32 parentCollectionId, bytes32 conditionId, uint[] indexSets)",
]);
const redeemTx: Transaction = {
to: CTF_ADDRESS,
data: ctfInterface.encodeFunctionData("redeemPositions", [
USDCe_ADDRESS,
ethers.constants.HashZero,
conditionId,
[1, 2], // Redeem both YES and NO (only winners pay out)
]),
value: "0",
};
const response = await client.execute([redeemTx], "Redeem winning tokens");
await response.wait();
```
```python Python theme={null}
redeem_abi = [{
"name": "redeemPositions",
"type": "function",
"inputs": [
{"name": "collateralToken", "type": "address"},
{"name": "parentCollectionId", "type": "bytes32"},
{"name": "conditionId", "type": "bytes32"},
{"name": "indexSets", "type": "uint256[]"}
],
"outputs": []
}]
redeem_tx = {
"to": CTF_ADDRESS,
"data": Web3().eth.contract(
address=CTF_ADDRESS, abi=redeem_abi
).encode_abi(
abi_element_identifier="redeemPositions",
args=[USDCe_ADDRESS, bytes(32), condition_id, [1, 2]]
),
"value": "0"
}
response = client.execute([redeem_tx], "Redeem winning tokens")
response.wait()
```
</CodeGroup>
***
## Negative Risk Markets
Multi-outcome markets use the Neg Risk CTF Exchange. Split and merge work the same way, but use different contract addresses:
```typescript theme={null}
const NEG_RISK_ADAPTER = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296";
const NEG_RISK_CTF_EXCHANGE = "0xC5d563A36AE78145C45a50134d48A1215220f80a";
```
See [Negative Risk Markets](/advanced/neg-risk) for details on how multi-outcome token mechanics differ.
***
## Inventory Strategies
### Before Quoting
1. Check market metadata via the [Gamma API](/market-data/fetching-markets)
2. Split sufficient USDC.e to cover your expected quoting size
3. Set token approvals if not already done (see [Getting Started](/market-makers/getting-started))
### During Trading
* **Skew quotes** when inventory becomes imbalanced on one side
* **Merge excess tokens** to free up capital for other markets
* **Split more** when inventory on either side runs low
### After Resolution
1. Cancel all open orders in the market
2. Wait for resolution to complete
3. Redeem winning tokens
4. Merge any remaining YES/NO pairs
***
## Batch Operations
Execute multiple inventory operations in a single relayer call for efficiency:
```typescript theme={null}
const transactions: Transaction[] = [
// Split on Market A
{
to: CTF_ADDRESS,
data: ctfInterface.encodeFunctionData("splitPosition", [
USDCe_ADDRESS,
ethers.constants.HashZero,
conditionIdA,
[1, 2],
ethers.utils.parseUnits("1000", 6),
]),
value: "0",
},
// Split on Market B
{
to: CTF_ADDRESS,
data: ctfInterface.encodeFunctionData("splitPosition", [
USDCe_ADDRESS,
ethers.constants.HashZero,
conditionIdB,
[1, 2],
ethers.utils.parseUnits("1000", 6),
]),
value: "0",
},
];
const response = await client.execute(transactions, "Batch inventory setup");
await response.wait();
```
***
## Next Steps
<CardGroup cols={2}>
<Card title="CTF Overview" icon="coins" href="/trading/ctf/overview">
How the Conditional Token Framework works under the hood
</Card>
<Card title="Split Tokens" icon="scissors" href="/trading/ctf/split">
Detailed split function parameters and prerequisites
</Card>
<Card title="Merge Tokens" icon="merge" href="/trading/ctf/merge">
Detailed merge function parameters
</Card>
<Card title="Gasless Transactions" icon="gas-pump" href="/trading/gasless">
Relayer Client setup and configuration
</Card>
</CardGroup>
+166
View File
@@ -0,0 +1,166 @@
> ## 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.
# Liquidity Rewards
> Earn rewards for providing liquidity on Polymarket
By posting resting limit orders, liquidity providers (makers) are automatically eligible for Polymarket's incentive program. Rewards are distributed directly to maker addresses daily at midnight UTC.
The program is designed to:
* Catalyze liquidity across all markets
* Encourage liquidity throughout a market's entire lifecycle
* Motivate passive, balanced quoting tight to a market's midpoint
* Encourage trading activity
* Discourage blatantly exploitative behaviors
<Info>
This program is heavily inspired by [dYdX's liquidity provider
rewards](https://www.dydx.foundation/blog/liquidity-provider-rewards). The
methodology is essentially a copy of dYdX's approach with adjustments for
binary contract markets — distinct books, no staking mechanic, a modified
order utility-relative depth function, and reward amounts isolated per market.
</Info>
***
## Methodology
Liquidity providers are rewarded based on a formula that rewards participation in markets, boosts two-sided depth (single-sided orders still score), and tighter spread vs the size-cutoff-adjusted midpoint. Each market configures a max spread and min size cutoff within which orders are considered. The average of rewards earned is determined by the relative share of each participant's Q<sub>n</sub> in market m.
### Variables
| Variable | Description |
| -------------- | ---------------------------------------------------------------- |
| S | Order position scoring function |
| v | Max spread from midpoint (in cents) |
| s | Spread from size-cutoff-adjusted midpoint |
| b | In-game multiplier |
| m | Market |
| m' | Market complement (i.e. NO if m = YES) |
| n | Trader index |
| u | Sample index |
| c | Scaling factor (currently 3.0 on all markets) |
| Q<sub>ne</sub> | Point total for book one for a sample |
| Q<sub>no</sub> | Point total for book two for a sample |
| Spread% | Distance from midpoint (bps or relative) for order n in market m |
| BidSize | Share-denominated quantity of bid |
| AskSize | Share-denominated quantity of ask |
***
## Equations
### 1. Order Scoring Function
Quadratic scoring rule for an order based on position between the adjusted midpoint and the minimum qualifying spread:
$S(v,s)= (\frac{v-s}{v})^2 \cdot b$
### 2. First Market Side Score (Q<sub>ne</sub>)
$Q_{one}= S(v,Spread_{m_1}) \cdot BidSize_{m_1} + S(v,Spread_{m_2}) \cdot BidSize_{m_2} + \dots $
$ + S(v, Spread_{m^\prime_1}) \cdot AskSize_{m^\prime_1} + S(v, Spread_{m^\prime_2}) \cdot AskSize_{m^\prime_2}$
### 3. Second Market Side Score (Q<sub>no</sub>)
$Q_{two}= S(v,Spread_{m_1}) \cdot AskSize_{m_1} + S(v,Spread_{m_2}) \cdot AskSize_{m_2} + \dots $
$ + S(v, Spread_{m^\prime_1}) \cdot BidSize_{m^\prime_1} + S(v, Spread_{m^\prime_2}) \cdot BidSize_{m^\prime_2}$
### 4. Minimum Score (Q<sub>min</sub>)
Boosts two-sided liquidity by taking the minimum of Q<sub>ne</sub> and Q<sub>no</sub>, while still rewarding single-sided liquidity at a reduced rate (divided by c).
**If midpoint is in range \[0.10, 0.90]** — single-sided liquidity can score:
$Q_{\min} = \max(\min({Q_{one}, Q_{two}}), \max(Q_{one}/c, Q_{two}/c))$
**If midpoint is in range \[0, 0.10) or (0.90, 1.0]** — liquidity must be double-sided to score:
$Q_{\min} = \min({Q_{one}, Q_{two}})$
### 5. Normalized Score (Q<sub>normal</sub>)
Q<sub>min</sub> of a market maker divided by the sum of all Q<sub>min</sub> across market makers in a given sample:
$Q_{normal} = \frac{Q_{min}}{\sum_{n=1}^{N}{(Q_{min})_n}}$
### 6. Epoch Score (Q<sub>epoch</sub>)
Sum of all Q<sub>normal</sub> for a trader across all samples in an epoch:
$Q_{epoch} = \sum_{u=1}^{10,080}{(Q_{normal})_u}$
### 7. Final Score (Q<sub>final</sub>)
Normalizes Q<sub>epoch</sub> by dividing by the sum of all market makers' Q<sub>epoch</sub> in a given epoch. This value is multiplied by the rewards available for the market to get a trader's reward:
$Q_{final}=\frac{Q_{epoch}}{\sum_{n=1}^{N}{(Q_{epoch})_n}}$
***
## Worked Example
Assume an adjusted market midpoint of 0.50 and a max spread config of 3 cents for both m and m'.
### Step 2 — First Side Score
A trader has the following open orders:
* 100Q bid on m @ 0.49 (spread = 1 cent)
* 200Q bid on m @ 0.48 (spread = 2 cents)
* 100Q ask on m' @ 0.51 (spread = 1 cent)
$$
Q_{ne} = \left( \frac{(3-1)}{3} \right)^2 \cdot 100 + \left( \frac{(3-2)}{3} \right)^2 \cdot 200 + \left( \frac{(3-1)}{3} \right)^2 \cdot 100
$$
Q<sub>ne</sub> is calculated every minute using random sampling.
### Step 3 — Second Side Score
The same trader also has:
* 100Q bid on m @ 0.485 (spread = 1.5 cents)
* 100Q bid on m' @ 0.48 (spread = 2 cents)
* 200Q ask on m' @ 0.505 (spread = 0.5 cents)
$$
Q_{no} = \left( \frac{(3-1.5)}{3} \right)^2 \cdot 100 + \left( \frac{(3-2)}{3} \right)^2 \cdot 100 + \left( \frac{(3-.5)}{3} \right)^2 \cdot 200
$$
Q<sub>no</sub> is calculated every minute using random sampling.
### Steps 47
4. Take the minimum of Q<sub>ne</sub> and Q<sub>no</sub> (with single-sided adjustment if midpoint is in \[0.10, 0.90])
5. Normalize against all other market makers in the sample
6. Sum across all 10,080 samples in the epoch
7. Normalize again to get final reward share
***
<Note>
The minimum reward payout is **\$1**; amounts below this will not be paid.
</Note>
<Tip>
Both `min_incentive_size` and `max_incentive_spread` can be fetched alongside
full market objects via the CLOB API and [Markets
API](/market-data/fetching-markets). Reward allocations for an epoch can also
be fetched via the Markets API.
</Tip>
## Next Steps
<CardGroup cols={2}>
<Card title="Trading" icon="chart-line" href="/market-makers/trading">
Order entry and quoting best practices
</Card>
<Card title="Maker Rebates" icon="receipt" href="/market-makers/maker-rebates">
Earn USDC rebates on 15-minute crypto markets
</Card>
</CardGroup>
+219
View File
@@ -0,0 +1,219 @@
> ## 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.
# Maker Rebates Program
> Earn daily USDC rebates by providing liquidity on Polymarket
Polymarket has enabled taker fees on **15-minute crypto markets**, **5-minute crypto markets**, **NCAAB (college basketball)**, and **Serie A** markets. These fees fund a **Maker Rebates** program that pays daily USDC rebates to liquidity providers.
***
## Why Maker Rebates?
Sports markets benefit from the same dynamics as crypto markets. When liquidity is deeper:
* Spreads tend to be tighter
* Price impact is lower
* Fills are more reliable
* Markets are more resilient during volatility
Maker Rebates incentivize **consistent, competitive quoting** so everyone gets a better trading experience.
***
## How Maker Rebates Work
* **Paid daily in USDC:** Rebates are calculated and distributed every day.
* **Performance-based:** You earn based on the share of liquidity you provided that actually got taken.
### Eligibility
Place orders that add liquidity to the book and get filled (i.e., your liquidity is taken by another trader).
### Payment
Rebates are paid daily in USDC, directly to your wallet.
***
## Funding
Maker Rebates are funded by taker fees collected in eligible markets. A percentage of these fees are redistributed to makers who keep the markets liquid. The rebate percentage differs by market type.
| Market Type | Period | Maker Rebate | Distribution Method |
| ----------------------- | ------------- | ------------ | ------------------- |
| 15-Min Crypto | Jan 19, 2026+ | 20% | Fee-curve weighted |
| 5-Min Crypto | Feb 12, 2026+ | 20% | Fee-curve weighted |
| Sports (NCAAB, Serie A) | Feb 18, 2026+ | 25% | Fee-curve weighted |
<Note>
Polymarket collects taker fees in eligible markets (15-minute crypto, 5-minute
crypto, NCAAB, and Serie A). The rebate percentage is at the sole discretion
of Polymarket and may change over time.
</Note>
***
## Fee-Curve Weighted Rebates
Rebates are distributed using the **same formula as taker fees**. This ensures makers are rewarded proportionally to the fee value their liquidity generates.
For each filled maker order:
```text theme={null}
fee_equivalent = C × p × feeRate × (p × (1 - p))^exponent
```
Where **C** = number of shares traded and **p** = price of the shares. The fee parameters differ by market type:
| Parameter | Sports (NCAAB, Serie A) | 5-Min & 15-Min Crypto |
| --------- | ----------------------- | --------------------- |
| Fee Rate | 0.0175 | 0.25 |
| Exponent | 1 | 2 |
Your daily rebate:
```text theme={null}
rebate = (your_fee_equivalent / total_fee_equivalent) * rebate_pool
```
Totals are calculated per market, so you only compete with other makers in the same market.
***
## Taker Fee Structure
Taker fees are calculated in USDC and vary based on the share price. However, fees are collected in shares on buy orders and USDC on sell orders. Fees are highest at 50% probability and lowest at the extremes (near 0% or 100%).
<Frame>
<div className="p-3 bg-white rounded-xl">
<iframe title="Fee Curves" aria-label="Line chart" id="datawrapper-chart-qTzMH" src="https://datawrapper.dwcdn.net/qTzMH/1/" scrolling="no" frameborder="0" width={700} style={{ width: "0", minWidth: "100% !important", border: "none" }} height="450" data-external="1" />
</div>
</Frame>
### Fee Table (100 shares)
<Tabs>
<Tab title="5-Min & 15-Min Crypto">
| Price | Trade Value | Fee (USDC) | Effective Rate |
| ------ | ----------- | ---------- | -------------- |
| \$0.01 | \$1 | \$0.00 | 0.00% |
| \$0.05 | \$5 | \$0.003 | 0.06% |
| \$0.10 | \$10 | \$0.02 | 0.20% |
| \$0.15 | \$15 | \$0.06 | 0.41% |
| \$0.20 | \$20 | \$0.13 | 0.64% |
| \$0.25 | \$25 | \$0.22 | 0.88% |
| \$0.30 | \$30 | \$0.33 | 1.10% |
| \$0.35 | \$35 | \$0.45 | 1.29% |
| \$0.40 | \$40 | \$0.58 | 1.44% |
| \$0.45 | \$45 | \$0.69 | 1.53% |
| \$0.50 | \$50 | \$0.78 | **1.56%** |
| \$0.55 | \$55 | \$0.84 | 1.53% |
| \$0.60 | \$60 | \$0.86 | 1.44% |
| \$0.65 | \$65 | \$0.84 | 1.29% |
| \$0.70 | \$70 | \$0.77 | 1.10% |
| \$0.75 | \$75 | \$0.66 | 0.88% |
| \$0.80 | \$80 | \$0.51 | 0.64% |
| \$0.85 | \$85 | \$0.35 | 0.41% |
| \$0.90 | \$90 | \$0.18 | 0.20% |
| \$0.95 | \$95 | \$0.05 | 0.06% |
| \$0.99 | \$99 | \$0.00 | 0.00% |
The maximum effective fee rate is **1.56%** at 50% probability. Fees decrease symmetrically toward both extremes.
</Tab>
<Tab title="Sports (NCAAB, Serie A)">
| Price | Trade Value | Fee (USDC) | Effective Rate |
| ------ | ----------- | ---------- | -------------- |
| \$0.01 | \$1 | \$0.00 | 0.02% |
| \$0.05 | \$5 | \$0.00 | 0.08% |
| \$0.10 | \$10 | \$0.02 | 0.16% |
| \$0.15 | \$15 | \$0.03 | 0.22% |
| \$0.20 | \$20 | \$0.06 | 0.28% |
| \$0.25 | \$25 | \$0.08 | 0.33% |
| \$0.30 | \$30 | \$0.11 | 0.37% |
| \$0.35 | \$35 | \$0.14 | 0.40% |
| \$0.40 | \$40 | \$0.17 | 0.42% |
| \$0.45 | \$45 | \$0.19 | 0.43% |
| \$0.50 | \$50 | \$0.22 | **0.44%** |
| \$0.55 | \$55 | \$0.24 | 0.43% |
| \$0.60 | \$60 | \$0.25 | 0.42% |
| \$0.65 | \$65 | \$0.26 | 0.40% |
| \$0.70 | \$70 | \$0.26 | 0.37% |
| \$0.75 | \$75 | \$0.25 | 0.33% |
| \$0.80 | \$80 | \$0.22 | 0.28% |
| \$0.85 | \$85 | \$0.19 | 0.22% |
| \$0.90 | \$90 | \$0.14 | 0.16% |
| \$0.95 | \$95 | \$0.08 | 0.08% |
| \$0.99 | \$99 | \$0.02 | 0.02% |
The maximum effective fee rate is **0.44%** at 50% probability. Fees decrease symmetrically toward both extremes.
</Tab>
</Tabs>
### Fee Precision
Fees are rounded to 4 decimal places. The smallest fee charged is 0.0001 USDC. Anything smaller rounds to zero, so very small trades near the extremes may incur no fee at all.
***
## Which Markets Are Eligible?
The following market types have taker fees enabled and are eligible for maker rebates:
* **15-minute crypto markets**
* **5-minute crypto markets**
* **NCAAB (college basketball) markets** (starting February 18, 2026 for new markets)
* **Serie A markets** (starting February 18, 2026 for new markets)
All other markets remain fee-free.
***
## FAQ
<AccordionGroup>
<Accordion title="How do I qualify for maker rebates?">
Place orders that add liquidity to the book and get filled (i.e., your
liquidity is taken by another trader).
</Accordion>
<Accordion title="When are rebates paid?">Daily, in USDC.</Accordion>
<Accordion title="How are rebates calculated?">
Rebates are proportional to your share of executed maker liquidity in each
eligible market. Totals are calculated per market, so you only compete with
other makers in the same market.
</Accordion>
<Accordion title="Where does the rebate pool come from?">
Taker fees collected in eligible markets are allocated to the maker rebate
pool and distributed daily.
</Accordion>
<Accordion title="Which markets have fees enabled?">
15-minute crypto markets, 5-minute crypto markets, and starting February 18,
2026, NCAAB and Serie A markets.
</Accordion>
<Accordion title="Is Polymarket charging fees on all markets?">
No. Fees apply only to 15-minute crypto, 5-minute crypto, NCAAB, and Serie A
markets. All other markets remain fee-free.
</Accordion>
</AccordionGroup>
***
## Next Steps
<CardGroup cols={2}>
<Card title="Fee Structure" icon="receipt" href="/trading/fees">
Full fee handling guide for SDK and REST API users.
</Card>
<Card title="Place Orders" icon="plus" href="/trading/quickstart">
Start placing orders on Polymarket.
</Card>
</CardGroup>
+83
View File
@@ -0,0 +1,83 @@
> ## 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
> Market making on Polymarket
A Market Maker (MM) on Polymarket is a trader who provides liquidity to prediction markets by continuously posting bid and ask orders. By laying the spread, market makers enable other users to trade efficiently while earning the spread as compensation for the risk they take.
Market makers are essential to Polymarket's ecosystem — they provide liquidity across markets, tighten spreads for better user experience, enable price discovery through continuous quoting, and absorb trading flow from retail and institutional users.
<Note>
**Not a Market Maker?** If you're building an application that routes orders
for your users, see the [Builder Program](/builders/overview) instead.
</Note>
***
## Getting Started
<Steps>
<Step title="Complete Setup">
Deploy wallets, fund with USDC.e, and set token approvals. See the [Getting
Started](/market-makers/getting-started) guide.
</Step>
<Step title="Connect to Data Feeds">
WebSocket for real-time orderbook updates, Gamma API for market metadata.
See [Market Data](/market-data/overview).
</Step>
<Step title="Start Quoting">
Post orders via the CLOB REST API. See [Trading ](/market-makers/trading).
</Step>
</Steps>
***
## Quick Reference
| Action | Tool | Documentation |
| ---------------------- | -------------- | ------------------------------------------------- |
| Deposit USDC.e | Bridge API | [Bridge](/trading/bridge/deposit) |
| Approve tokens | Relayer Client | [Getting Started](/market-makers/getting-started) |
| Post limit orders | CLOB REST API | [Create Orders](/trading/orders/create) |
| Monitor orderbook | WebSocket | [WebSocket](/market-data/websocket/overview) |
| Split USDC.e to tokens | CTF / Relayer | [Inventory](/market-makers/inventory) |
| Merge tokens to USDC.e | CTF / Relayer | [Inventory](/market-makers/inventory) |
***
## What's in This Section
<CardGroup cols={2}>
<Card title="Getting Started" icon="gear" href="/market-makers/getting-started">
Deposits, token approvals, wallet deployment, API keys
</Card>
<Card title="Trading" icon="chart-line" href="/market-makers/trading">
Quoting best practices, strategies, and risk controls
</Card>
<Card title="Inventory Management" icon="boxes-stacked" href="/market-makers/inventory">
Split, merge, and redeem outcome tokens
</Card>
<Card title="Liquidity Rewards" icon="gift" href="/market-makers/liquidity-rewards">
Earn rewards for providing liquidity
</Card>
</CardGroup>
## Risks
<Warning>
Be careful with spread management — if your bid price is higher than your ask
price (a "negative spread" or "crossed market"), you will lose money on every
fill. Always validate your quote prices before submission.
</Warning>
## Support
For market maker onboarding and support, contact [support@polymarket.com](mailto:support@polymarket.com).
+296
View File
@@ -0,0 +1,296 @@
> ## 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.
# Trading
> Order entry, management, and best practices for market makers
Market makers interact with Polymarket through the CLOB API — posting two-sided quotes, managing inventory across markets, and rebalancing positions. The SDK clients handle order signing and submission, so you can focus on strategy.
<Info>
This page covers MM-specific workflows and best practices. For full order
mechanics, see [Create Orders](/trading/orders/create) and [Cancel
Orders](/trading/orders/cancel).
</Info>
***
## Two-Sided Quoting
The core market making workflow is posting a bid and ask around your fair value. Use `createAndPostOrder` to place each side:
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient, Side, OrderType } from "@polymarket/clob-client";
const client = new ClobClient(
"https://clob.polymarket.com",
137,
wallet,
credentials,
signatureType,
funder,
);
// Bid at 0.48
const bid = await client.createAndPostOrder({
tokenID: "3409705850427531082723332342151729...",
side: Side.BUY,
price: 0.48,
size: 1000,
orderType: OrderType.GTC,
});
// Ask at 0.52
const ask = await client.createAndPostOrder({
tokenID: "3409705850427531082723332342151729...",
side: Side.SELL,
price: 0.52,
size: 1000,
orderType: OrderType.GTC,
});
```
```python Python theme={null}
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY, SELL
token_id = "3409705850427531082723332342151729..."
# Bid at 0.48
bid = client.create_and_post_order(
OrderArgs(token_id=token_id, side=BUY, price=0.48, size=1000),
order_type=OrderType.GTC,
)
# Ask at 0.52
ask = client.create_and_post_order(
OrderArgs(token_id=token_id, side=SELL, price=0.52, size=1000),
order_type=OrderType.GTC,
)
```
</CodeGroup>
### Batch Orders
For tighter spreads across multiple levels, use `postOrders` to submit up to 15 orders in a single request:
<CodeGroup>
```typescript TypeScript theme={null}
const orders = await Promise.all([
client.createOrder({ tokenID, side: Side.BUY, price: 0.48, size: 500 }),
client.createOrder({ tokenID, side: Side.BUY, price: 0.47, size: 500 }),
client.createOrder({ tokenID, side: Side.SELL, price: 0.52, size: 500 }),
client.createOrder({ tokenID, side: Side.SELL, price: 0.53, size: 500 }),
]);
const response = await client.postOrders(
orders.map((order) => ({ order, orderType: OrderType.GTC })),
);
```
```python Python theme={null}
from py_clob_client.clob_types import OrderArgs, OrderType, PostOrdersArgs
from py_clob_client.order_builder.constants import BUY, SELL
response = client.post_orders([
PostOrdersArgs(
order=client.create_order(OrderArgs(
price=0.48, size=500, side=BUY, token_id=token_id,
)),
order_type=OrderType.GTC,
),
PostOrdersArgs(
order=client.create_order(OrderArgs(
price=0.47, size=500, side=BUY, token_id=token_id,
)),
order_type=OrderType.GTC,
),
PostOrdersArgs(
order=client.create_order(OrderArgs(
price=0.52, size=500, side=SELL, token_id=token_id,
)),
order_type=OrderType.GTC,
),
PostOrdersArgs(
order=client.create_order(OrderArgs(
price=0.53, size=500, side=SELL, token_id=token_id,
)),
order_type=OrderType.GTC,
),
])
```
</CodeGroup>
<Tip>
Batching reduces latency by submitting multiple quotes in a single request.
Always prefer `postOrders()` over multiple individual `createAndPostOrder()`
calls.
</Tip>
***
## Choosing Order Types
| Type | Behavior | When to Use |
| ------- | ------------------------------------------------ | --------------------------------------- |
| **GTC** | Rests on the book until filled or cancelled | Default for passive quoting |
| **GTD** | Auto-expires at a specified time | Expire quotes before known events |
| **FOK** | Must fill entirely and immediately, or cancel | Aggressive rebalancing — all or nothing |
| **FAK** | Fills what's available immediately, cancels rest | Rebalancing where partial fills are OK |
**GTC** and **GTD** are your primary tools for passive market making — they rest on the book at your specified price. **FOK** and **FAK** are for rebalancing inventory against resting liquidity.
### Time-Limited Quotes with GTD
Auto-expire quotes before known events like market close or resolution:
<CodeGroup>
```typescript TypeScript theme={null}
// Expire in 1 hour
const expiringOrder = await client.createOrder({
tokenID,
side: Side.BUY,
price: 0.5,
size: 1000,
orderType: OrderType.GTD,
expiration: Math.floor(Date.now() / 1000) + 3600,
});
```
```python Python theme={null}
import time
# Expire in 1 hour
expiring_order = client.create_order(
OrderArgs(
token_id=token_id,
side=BUY,
price=0.50,
size=1000,
expiration=int(time.time()) + 3600,
),
order_type=OrderType.GTD,
)
```
</CodeGroup>
***
## Managing Orders
### Cancelling
Cancel individual orders, by market, or everything at once:
<CodeGroup>
```typescript TypeScript theme={null}
await client.cancelOrder(orderId); // Single order
await client.cancelOrders(orderIds); // Multiple orders
await client.cancelMarketOrders(conditionId); // All orders in a market
await client.cancelAll(); // Everything
```
```python Python theme={null}
client.cancel(order_id=order_id) # Single order
client.cancel_market_orders(market=condition_id) # All orders in a market
client.cancel_all() # Everything
```
</CodeGroup>
See [Cancel Orders](/trading/orders/cancel) for full details including onchain cancellation.
### Monitoring Open Orders
<CodeGroup>
```typescript TypeScript theme={null}
const order = await client.getOrder(orderId);
const orders = await client.getOpenOrders({
market: "0xbd31dc8a...",
asset_id: "52114319501245...",
});
```
```python Python theme={null}
from py_clob_client.clob_types import OpenOrderParams
order = client.get_order(order_id)
orders = client.get_orders(
OpenOrderParams(market="0xbd31dc8a...")
)
```
</CodeGroup>
***
## Tick Sizes
Your order price must conform to the market's tick size, or it will be rejected. Look it up with the SDK before quoting:
<CodeGroup>
```typescript TypeScript theme={null}
const tickSize = await client.getTickSize(tokenID);
// Returns: "0.1" | "0.01" | "0.001" | "0.0001"
```
```python Python theme={null}
tick_size = client.get_tick_size(token_id)
# Returns: "0.1" | "0.01" | "0.001" | "0.0001"
```
</CodeGroup>
***
## Fees
Most markets have **zero fees** for both makers and takers. However, the following market types have taker fees:
* **5-minute crypto markets**
* **15-minute crypto markets**
* **Select sports markets** (e.g., NCAAB, Serie A)
See [Fees](/trading/fees) for the full fee schedule and calculation details.
***
## Best Practices
### Quote Management
* **Quote both sides** — Post bids and asks to earn maximum [liquidity rewards](/market-makers/liquidity-rewards)
* **Skew on inventory** — Adjust quote prices based on your current position to manage exposure
* **Cancel stale quotes** — Pull orders immediately when market conditions change
* **Use GTD for events** — Auto-expire quotes before known catalysts to avoid stale exposure
### Latency
* **Batch orders** — Use `postOrders()` to submit multiple quotes in a single request
* **WebSocket for data** — Subscribe to real-time feeds instead of polling REST endpoints
### Risk Controls
* **Size limits** — Check token balances before quoting and don't exceed your available inventory
* **Price guards** — Validate prices against the book midpoint and reject outliers
* **Kill switch** — Call `cancelAll()` immediately on errors or position breaches
* **Monitor fills** — Subscribe to the WebSocket user channel for real-time fill notifications
***
## Next Steps
<CardGroup cols={2}>
<Card title="Inventory" icon="boxes-stacked" href="/market-makers/inventory">
Split, merge, and redeem outcome tokens
</Card>
<Card title="Liquidity Rewards" icon="gift" href="/market-makers/liquidity-rewards">
Earn rewards for providing two-sided liquidity
</Card>
<Card title="Create Orders" icon="plus" href="/trading/orders/create">
Full order creation reference with all options
</Card>
</CardGroup>