docs: sync Polymarket docs updates 2026-07-10

Updated 21 files:
- trading/orders: overview, create
- developers/CLOB/orders: orders, create-order, create-order-batch, get-order, get-active-order, check-scoring, onchain-order-info
- developers/CLOB/status
- market-makers: trading, maker-rebates, combos
- trading/fees, market-makers maker-rebates-program, trading/fees
- dev-tooling: python, typescript
- api-reference/core: get-trades-for-a-user-or-markets, get-user-activity
- changelog/changelog
This commit is contained in:
GLaDOS
2026-07-10 14:08:00 +02:00
parent a1a79b8a72
commit 714c66e5b3
21 changed files with 675 additions and 156 deletions
+507 -63
View File
@@ -1623,8 +1623,8 @@ form](https://forms.gle/dk5A1DRw8EN5uP9z5).
<Warning>
Makers are expected to accept most selected quotes. We track acceptance rates,
and makers who reject more than 15% of selected quotes over a one-hour lookback
window may be paused from quoting for a few minutes.
and makers who reject more than 15% of selected quotes over a one-hour
lookback window may be paused from quoting for a few minutes.
</Warning>
Once access is enabled, your quoting system will immediately be asked to review
@@ -1886,11 +1886,14 @@ fresh outside the quote path.
<Tabs>
<Tab title="TypeScript">
Use `client.listComboPositions(...)` to page through Combo positions for the
authenticated account. Filter by status, Combo condition ID, or Combo position
ID when you only need a subset of positions.
authenticated account.
```ts theme={null}
import { ComboPositionStatus, type ComboPosition } from "@polymarket/client";
import {
ComboPositionSort,
ComboPositionStatus,
type ComboPosition,
} from "@polymarket/client";
const positions = client.listComboPositions({
status: ComboPositionStatus.Open,
@@ -1904,6 +1907,31 @@ fresh outside the quote path.
}
```
You can filter positions by the following criteria. `conditionId` accepts one
Combo condition ID or an array of Combo condition IDs.
<CodeGroup>
```ts Condition ID theme={null}
const positions = client.listComboPositions({
conditionId: ["<combo_condition_id_1>", "<combo_condition_id_2>"],
});
```
```ts Status theme={null}
const positions = client.listComboPositions({
status: ComboPositionStatus.Open,
});
```
```ts Incremental Sync theme={null}
const positions = client.listComboPositions({
updatedAfter: lastWatermarkSeconds,
sort: ComboPositionSort.UpdatedAsc,
pageSize: 1000,
});
```
</CodeGroup>
Each returned item is a `ComboPosition`.
<CodeGroup>
@@ -1911,14 +1939,19 @@ fresh outside the quote path.
type ComboPosition = {
conditionId: ComboConditionId;
positionId: PositionId;
outcome: ComboPositionOutcome;
moduleId: number;
userAddress: Address;
wallet: Address;
shares: DecimalString;
entryAvgPriceUsdc?: DecimalString | null;
entryCostUsdc?: DecimalString | null;
realizedPayoutUsdc?: DecimalString | null;
totalCostUsdc?: DecimalString | null;
status: ComboPositionStatus;
redeemable: boolean;
firstEntryAt: IsoDateTimeString;
resolvedAt?: IsoDateTimeString | null;
updatedAt?: IsoDateTimeString;
legsTotal: number;
legsResolved: number;
legsPending: number;
@@ -1966,27 +1999,10 @@ fresh outside the quote path.
```
</CodeGroup>
You can filter positions by the following criteria:
<CodeGroup>
```ts Condition ID theme={null}
const positions = client.listComboPositions({
conditionId: "<combo_condition_id>",
});
```
```ts Position ID theme={null}
const positions = client.listComboPositions({
positionId: "<yes_position_id|no_position_id>",
});
```
```ts Status theme={null}
const positions = client.listComboPositions({
status: ComboPositionStatus.Open,
});
```
</CodeGroup>
For redeemed positions, `shares` and `entryCostUsdc` track remaining inventory,
so both can read as zero after a winning Combo is redeemed. Use
`realizedPayoutUsdc` for gross redemption proceeds and `totalCostUsdc` for
original cost basis; net result is `realizedPayoutUsdc - totalCostUsdc`.
</Tab>
<Tab title="Python">
@@ -2003,6 +2019,31 @@ fresh outside the quote path.
...
```
You can filter positions by the following criteria. `condition_id` accepts one
Combo condition ID or a sequence of Combo condition IDs.
<CodeGroup>
```python Condition ID theme={null}
positions = client.list_combo_positions(
condition_id=["<combo_condition_id_1>", "<combo_condition_id_2>"],
)
```
```python Status theme={null}
positions = client.list_combo_positions(
status="OPEN",
)
```
```python Incremental Sync theme={null}
positions = client.list_combo_positions(
updated_after=last_watermark_seconds,
sort="updated_asc",
page_size=1000,
)
```
</CodeGroup>
The returned `ComboPosition` models include the following fields:
<CodeGroup>
@@ -2010,14 +2051,19 @@ fresh outside the quote path.
class ComboPosition:
condition_id: ComboConditionId
position_id: PositionId
outcome: ComboPositionOutcome
module_id: int
user_address: EvmAddress
wallet: EvmAddress
shares: Decimal
entry_avg_price_usdc: Decimal | None
entry_cost_usdc: Decimal | None
realized_payout_usdc: Decimal | None
total_cost_usdc: Decimal | None
status: ComboPositionStatus
redeemable: bool
first_entry_at: datetime
resolved_at: datetime | None
updated_at: datetime | None
legs_total: int
legs_resolved: int
legs_pending: int
@@ -2061,27 +2107,10 @@ fresh outside the quote path.
```
</CodeGroup>
You can filter positions by the following criteria:
<CodeGroup>
```python Condition ID theme={null}
positions = client.list_combo_positions(
condition_id="<combo_condition_id>",
)
```
```python Position ID theme={null}
positions = client.list_combo_positions(
position_id="<yes_position_id|no_position_id>",
)
```
```python Status theme={null}
positions = client.list_combo_positions(
status="OPEN",
)
```
</CodeGroup>
For redeemed positions, `shares` and `entry_cost_usdc` track remaining
inventory, so both can be zero after a winning Combo is redeemed. Use
`realized_payout_usdc` for gross redemption proceeds and `total_cost_usdc` for
original cost basis; net result is `realized_payout_usdc - total_cost_usdc`.
</Tab>
<Tab title="API">
@@ -2100,7 +2129,7 @@ fresh outside the quote path.
```bash Condition ID theme={null}
curl -G "https://data-api.polymarket.com/v1/positions/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "combo_condition_id=<combo_condition_id>"
--data-urlencode "market_id=<combo_condition_id>"
```
```bash Position ID theme={null}
@@ -2135,6 +2164,7 @@ fresh outside the quote path.
"status": "OPEN",
"first_entry_at": "2026-06-08T00:00:00Z",
"resolved_at": null,
"updated_at": "2026-06-08T00:00:00Z",
"legs_total": 2,
"legs_resolved": 0,
"legs_pending": 2,
@@ -2155,27 +2185,441 @@ fresh outside the quote path.
"pagination": {
"limit": 50,
"offset": 0,
"has_more": false,
"next_cursor": null
"has_more": true,
"next_cursor": "eyJsIjo1MCwibyI6NTB9"
}
}
```
Use `cursor` from `pagination.next_cursor` to fetch the next page. Keep the same
filters and `sort`; `cursor` supersedes `offset`. A `null` cursor means there
are no more pages.
```bash Cursor theme={null}
curl -G "https://data-api.polymarket.com/v1/positions/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "limit=100" \
--data-urlencode "sort=first_entry_desc" \
--data-urlencode "cursor=<pagination.next_cursor>"
```
Use `updatedAfter` with `sort=updated_asc` to incrementally sync changed
positions. Store the newest `updated_at` you process as your next watermark;
boundary rows may re-deliver, so upsert by `(combo_condition_id,
combo_position_id)`.
```bash Incremental sync theme={null}
curl -G "https://data-api.polymarket.com/v1/positions/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "updatedAfter=<last_watermark_epoch_seconds>" \
--data-urlencode "sort=updated_asc" \
--data-urlencode "limit=1000"
```
For redeemed positions, `shares_balance` and `entry_cost_usdc` track remaining
inventory, so both can read as zero after a winning Combo is redeemed. Use
`realized_payout_usdc` for gross redemption proceeds and `total_cost_usdc` for
original cost basis; net result is `realized_payout_usdc - total_cost_usdc`.
</Tab>
</Tabs>
<Note>
**Displaying closed (redeemed) positions.** `entry_cost_usdc` is the
*remaining* cost basis (`entry_avg_price × shares_balance`), so it reads `~0`
once a winning combo is redeemed — and `shares_balance` does too. Two fields
carry the closed-position economics instead:
### List Combo Activity
* `realized_payout_usdc` — gross redemption proceeds (winning shares redeem
1:1 at \$1; accumulates under `PARTIAL`)
* `total_cost_usdc` — original cost basis, reconstructed as
`entry_avg_price × (shares_balance + realized_payout)`
Use Combo activity when you need an audit trail for inventory-changing events,
including splits, merges, conversions, wraps, unwraps, and redeems. Use Combo
positions for current inventory state.
Net result of a finished combo = `realized_payout_usdc total_cost_usdc`.
</Note>
<Tabs>
<Tab title="TypeScript">
Use `client.listComboActivity(...)` to page through Combo lifecycle activity for
the authenticated account.
```ts theme={null}
import { ComboActivityType, type ComboActivity } from "@polymarket/client";
const activity = client.listComboActivity({ pageSize: 50 });
for await (const page of activity) {
for (const item of page.items) {
// item: ComboActivity
if (item.type === ComboActivityType.Redeem) {
console.log(item.positionId, item.payout);
}
}
}
```
Filter to one or more Combos with `conditionId`.
```ts theme={null}
const activity = client.listComboActivity({
conditionId: ["<combo_condition_id_1>", "<combo_condition_id_2>"],
});
```
Each returned item is a discriminated `ComboActivity` union. All lifecycle rows
share the base fields; redeem rows also include the redeemed position ID and
payout.
<CodeGroup>
```ts ComboActivity theme={null}
type ComboActivity =
| ComboSplitActivity
| ComboMergeActivity
| ComboConvertActivity
| ComboCompressActivity
| ComboWrapActivity
| ComboUnwrapActivity
| ComboRedeemActivity;
```
```ts Split / Merge theme={null}
type ComboSplitActivity = {
id: ComboActivityId;
type: ComboActivityType.Split;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
type ComboMergeActivity = {
id: ComboActivityId;
type: ComboActivityType.Merge;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
```
```ts Convert / Compress theme={null}
type ComboConvertActivity = {
id: ComboActivityId;
type: ComboActivityType.Convert;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
type ComboCompressActivity = {
id: ComboActivityId;
type: ComboActivityType.Compress;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
```
```ts Wrap / Unwrap theme={null}
type ComboWrapActivity = {
id: ComboActivityId;
type: ComboActivityType.Wrap;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
type ComboUnwrapActivity = {
id: ComboActivityId;
type: ComboActivityType.Unwrap;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
};
```
```ts ComboRedeemActivity theme={null}
type ComboRedeemActivity = {
id: ComboActivityId;
type: ComboActivityType.Redeem;
wallet: Address;
conditionId: ComboConditionId;
moduleId: number;
amount: DecimalString | null;
timestamp: EpochMilliseconds;
transactionAt: IsoDateTimeString;
transactionHash: TxHash;
logIndex: number;
blockNumber: number;
legs: ComboPositionLeg[];
positionId: PositionId;
payout: DecimalString | null;
};
```
</CodeGroup>
</Tab>
<Tab title="Python">
Use `client.list_combo_activity(...)` to page through Combo lifecycle activity
for a wallet.
```python theme={null}
activity = client.list_combo_activity(
user="<maker_address>",
page_size=50,
)
for page in activity:
for item in page.items:
# item: ComboActivity
if item.type == "REDEEM":
print(item.position_id, item.payout)
```
Filter to one or more Combos with `condition_id`.
```python theme={null}
activity = client.list_combo_activity(
user="<maker_address>",
condition_id=["<combo_condition_id_1>", "<combo_condition_id_2>"],
)
```
The returned `ComboActivity` models use a `type` discriminator. All lifecycle
rows share the base fields; redeem rows also include the redeemed position ID
and payout.
<CodeGroup>
```python ComboActivity theme={null}
ComboActivity = (
ComboSplitActivity
| ComboMergeActivity
| ComboConvertActivity
| ComboCompressActivity
| ComboWrapActivity
| ComboUnwrapActivity
| ComboRedeemActivity
)
```
```python Split / Merge theme={null}
class ComboSplitActivity:
id: ComboActivityId
type: Literal["SPLIT"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
class ComboMergeActivity:
id: ComboActivityId
type: Literal["MERGE"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
```
```python Convert / Compress theme={null}
class ComboConvertActivity:
id: ComboActivityId
type: Literal["CONVERT"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
class ComboCompressActivity:
id: ComboActivityId
type: Literal["COMPRESS"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
```
```python Wrap / Unwrap theme={null}
class ComboWrapActivity:
id: ComboActivityId
type: Literal["WRAP"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
class ComboUnwrapActivity:
id: ComboActivityId
type: Literal["UNWRAP"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
```
```python ComboRedeemActivity theme={null}
class ComboRedeemActivity:
id: ComboActivityId
type: Literal["REDEEM"]
wallet: EvmAddress
condition_id: ComboConditionId
module_id: int
amount: Decimal | None
timestamp: datetime
transaction_at: datetime
transaction_hash: TransactionHash
log_index: int
block_number: int
legs: tuple[ComboPositionLeg, ...]
position_id: PositionId
payout: Decimal | None
```
</CodeGroup>
</Tab>
<Tab title="API">
Use the Data API to list Combo lifecycle activity for a wallet.
```bash theme={null}
curl -G "https://data-api.polymarket.com/v1/activity/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "limit=50"
```
Filter to specific Combos with `market_id`, which accepts comma-separated
`combo_condition_id` values.
```bash Filter by Combo theme={null}
curl -G "https://data-api.polymarket.com/v1/activity/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "market_id=<combo_condition_id_1>,<combo_condition_id_2>"
```
The response returns lifecycle events in `activity` and pagination metadata in
`pagination`.
```json theme={null}
{
"activity": [
{
"id": "<tx_hash>-<log_index>",
"event_kind": "PositionsSplit",
"side": "Split",
"module_kind": "Combinatorial",
"user_address": "<maker_address>",
"combo_condition_id": "<combo_condition_id>",
"combo_position_id": "<combo_position_id>",
"module_id": 3,
"amount_usdc": 10.0,
"payout_usdc": null,
"timestamp": 1783379945,
"tx_dttm": "2026-07-06T23:19:05Z",
"tx_hash": "<tx_hash>",
"log_index": 2409,
"block_number": 89783300,
"legs": [
{
"leg_index": 0,
"leg_position_id": "<leg_position_id_1>",
"leg_condition_id": "<ctf_condition_id_1>",
"leg_outcome_index": 0,
"leg_outcome_label": "Yes",
"leg_status": "OPEN",
"leg_resolved_at": null,
"leg_current_price": "0.52"
}
]
}
],
"pagination": {
"limit": 50,
"offset": 0,
"has_more": true,
"next_cursor": "eyJsIjo1MCwibyI6NTB9"
}
}
```
Use `cursor` from `pagination.next_cursor` to fetch the next page. `cursor`
supersedes `offset`. A `null` cursor means there are no more pages.
```bash Cursor theme={null}
curl -G "https://data-api.polymarket.com/v1/activity/combos" \
--data-urlencode "user=<maker_address>" \
--data-urlencode "limit=50" \
--data-urlencode "cursor=<pagination.next_cursor>"
```
</Tab>
</Tabs>
### Inventory Management
+3 -3
View File
@@ -38,7 +38,7 @@ Maker Rebates are funded by taker fees collected in eligible markets. A percenta
| Category | Maker Rebate | Distribution Method |
| --------------- | ------------ | ------------------- |
| Crypto | 20% | Fee-curve weighted |
| Sports | 25% | Fee-curve weighted |
| Sports | 15% | Fee-curve weighted |
| Finance | 25% | Fee-curve weighted |
| Politics | 25% | Fee-curve weighted |
| Economics | 25% | Fee-curve weighted |
@@ -72,7 +72,7 @@ Where **C** = number of shares traded and **p** = price of the shares. The fee p
| Category | Taker Fee Rate | Maker Fee Rate |
| --------------- | -------------- | -------------- |
| Crypto | 0.07 | 0 |
| Sports | 0.03 | 0 |
| Sports | 0.05 | 0 |
| Finance | 0.04 | 0 |
| Politics | 0.04 | 0 |
| Economics | 0.05 | 0 |
@@ -99,7 +99,7 @@ Taker fees are calculated in pUSD and vary based on the share price. The fee amo
<Frame>
<div className="p-3 bg-white rounded-xl">
<iframe title="Fee Curves" aria-label="Line chart" id="datawrapper-chart-cY9H4" src="https://datawrapper.dwcdn.net/cY9H4/" scrolling="no" frameborder="0" width={700} style={{ width: "0", minWidth: "100% !important", border: "none" }} height="450" data-external="1" />
<iframe title="Fee Curves" aria-label="Line chart" id="datawrapper-chart-dJ74e" src="https://datawrapper.dwcdn.net/dJ74e/" scrolling="no" frameborder="0" width={700} style={{ width: "0", minWidth: "100% !important", border: "none" }} height="450" data-external="1" />
</div>
</Frame>
+6 -6
View File
@@ -181,14 +181,14 @@ Auto-expire quotes before known events like market close or resolution:
<CodeGroup>
```typescript TypeScript theme={null}
// Expire in 1 hour
// Expire in 1 hour (+ 60s security threshold buffer)
const expiringOrder = await client.createAndPostOrder(
{
tokenID,
side: Side.BUY,
price: 0.5,
size: 1000,
expiration: Math.floor(Date.now() / 1000) + 3600,
expiration: Math.floor(Date.now() / 1000) + 60 + 3600,
},
undefined,
OrderType.GTD,
@@ -200,14 +200,14 @@ Auto-expire quotes before known events like market close or resolution:
from py_clob_client_v2 import OrderArgs, OrderType
from py_clob_client_v2.order_builder.constants import BUY
# Expire in 1 hour
# Expire in 1 hour (+ 60s security threshold buffer)
expiring_order = client.create_and_post_order(
OrderArgs(
token_id=token_id,
side=BUY,
price=0.50,
size=1000,
expiration=int(time.time()) + 3600,
expiration=int(time.time()) + 60 + 3600,
),
order_type=OrderType.GTD,
)
@@ -217,14 +217,14 @@ Auto-expire quotes before known events like market close or resolution:
use chrono::{TimeDelta, Utc};
use polymarket_client_sdk_v2::clob::types::OrderType;
// Expire in 1 hour
// Expire in 1 hour (+ 60s security threshold buffer)
let order = client.limit_order()
.token_id(token_id)
.price(dec!(0.50))
.size(dec!(1000))
.side(Side::Buy)
.order_type(OrderType::GTD)
.expiration(Utc::now() + TimeDelta::hours(1))
.expiration(Utc::now() + TimeDelta::minutes(1) + TimeDelta::hours(1))
.build().await?;
let signed = client.sign(&signer, order).await?;
client.post_order(signed).await?;