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
@@ -98,6 +98,23 @@ paths:
enum:
- BUY
- SELL
- in: query
name: start
schema:
type: integer
minimum: 0
description: >-
Lower-bound timestamp (epoch seconds) for the trade window. Omit or
pass `0` for the default window (most recent ~3 years); pass a
positive epoch (e.g. `1`) to retrieve full history.
- in: query
name: end
schema:
type: integer
minimum: 0
description: >-
Upper-bound timestamp (epoch seconds) for the trade window. Omit for
the default (current time); rows newer than `end` are excluded.
responses:
'200':
description: Success
@@ -108,6 +108,9 @@ paths:
schema:
type: integer
minimum: 0
description: >-
Upper-bound timestamp (epoch seconds) for the activity window. Omit
for the default (current time); rows newer than `end` are excluded.
- in: query
name: sortBy
schema:
+6
View File
@@ -6,6 +6,12 @@
> Welcome to the Polymarket Changelog. Here you will find any important changes to Polymarket, including but not limited to CLOB, API, UI and Mobile Applications.
<Update label="Jul 10, 2026" description="Sports taker fee and maker rebate update">
* **Sports fee coefficient**: The sports taker fee rate increases from `0.03` to `0.05` at midnight UTC.
* **Sports maker rebate**: The sports maker rebate decreases from 25% to 15% of collected taker fees.
* **Updated documentation**: [Fees](/trading/fees) and [Maker Rebates Program](/market-makers/maker-rebates).
</Update>
<Update label="Jul 2, 2026" description="World Cup markets decimalized to a 0.0025 (0.25¢) tick size">
* **Finer tick size for World Cup markets**: All World Cup *to advance*, *moneyline*, *spreads*, and *totals* markets are now decimalized to a **0.0025 (0.25¢)** tick size. This lets you execute at smaller ticks and tighter spreads for the most competitive prices. Applies only to those World Cup markets — see [Tick Sizes](/trading/orders/overview#tick-sizes).
</Update>
+19
View File
@@ -1102,6 +1102,25 @@ Secure clients expose the API credentials created for the authenticated session.
## Changelog
### `0.1.0b17`
* Added SDK pagination for Combo lifecycle activity and server-cursor pagination for Combo positions.
* Added typed overloads for market, event, and tag lookups, mutually-exclusive lookup arguments, and `redeem_positions`.
* Added trade time filters.
* Hardened Combo pagination filters and branded Combo activity IDs.
* Breaking beta change: Combo activity and position fields now use `wallet`, `amount`, and `payout`; Combo activity rows no longer expose `module_kind`.
```diff theme={null}
-activity.user_address
-activity.amount_usdc
-redeem_activity.payout_usdc
-position.user_address
+activity.wallet
+activity.amount
+redeem_activity.payout
+position.wallet
```
### `0.1.0b16`
* Fixed Deposit Wallet trading setup approvals to use the current Protocol V2 auto-redeem operator.
+18
View File
@@ -1103,6 +1103,24 @@ Secure clients expose the API credentials created for the authenticated session.
## Changelog
### `0.1.0-beta.14`
* Added SDK pagination for Combo lifecycle activity and server-cursor pagination for Combo positions.
* Added Combo position sync request fields and exposed `outcome` and `redeemable` on Combo positions.
* Branded Combo activity row IDs.
* Breaking beta change: Combo activity and position fields now use `wallet`, `amount`, and `payout`; Combo activity rows no longer expose `moduleKind`.
```diff theme={null}
-activity.userAddress
-activity.amountUsdc
-redeemActivity.payoutUsdc
-position.userAddress
+activity.wallet
+activity.amount
+redeemActivity.payout
+position.wallet
```
### `0.1.0-beta.13`
* Added `listMarketClarifications` for reading market clarification text with SDK-owned pagination and market, event, state, question, and transaction filters.
+4 -3
View File
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders
@@ -208,7 +208,7 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
.size(dec!(10))
.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?;
@@ -217,9 +217,11 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
</CodeGroup>
<Note>
There is a security threshold of one minute on GTD expiration. To set an
effective lifetime of N seconds, use `now + 60 + N`. For example, for a
30-second effective lifetime, set the expiration to `now + 60 + 30`.
GTD orders expire one minute before their stated expiration as a security
threshold. To set an effective lifetime of N seconds, use `now + 60 + N`.
In addition, the expiration must be at least three minutes in the future —
orders expiring sooner are rejected — so the minimum effective lifetime is
about two minutes.
</Note>
***
+6 -4
View File
@@ -208,7 +208,7 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
.size(dec!(10))
.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?;
@@ -217,9 +217,11 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
</CodeGroup>
<Note>
There is a security threshold of one minute on GTD expiration. To set an
effective lifetime of N seconds, use `now + 60 + N`. For example, for a
30-second effective lifetime, set the expiration to `now + 60 + 30`.
GTD orders expire one minute before their stated expiration as a security
threshold. To set an effective lifetime of N seconds, use `now + 60 + N`.
In addition, the expiration must be at least three minutes in the future —
orders expiring sooner are rejected — so the minimum effective lifetime is
about two minutes.
</Note>
***
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders
+4 -3
View File
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders
+4 -3
View File
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders
File diff suppressed because one or more lines are too long
+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?;
+24 -24
View File
@@ -33,7 +33,7 @@ Where **C** = number of shares traded and **p** = price of the shares.
| Category | Taker Fee Rate | Maker Fee Rate | Maker Rebate |
| --------------- | -------------- | -------------- | ------------ |
| Crypto | 0.07 | 0 | 20% |
| Sports | 0.03 | 0 | 25% |
| Sports | 0.05 | 0 | 15% |
| Finance | 0.04 | 0 | 25% |
| Politics | 0.04 | 0 | 25% |
| Economics | 0.05 | 0 | 25% |
@@ -48,7 +48,7 @@ Taker fees are calculated in USDC 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>
@@ -86,29 +86,29 @@ Taker fees are calculated in USDC and vary based on the share price. The fee amo
<Tab title="Sports">
| Price | Trade Value | Taker Fee (USDC) |
| ------ | ----------- | ---------------- |
| \$0.01 | \$1 | \$0.03 |
| \$0.05 | \$5 | \$0.14 |
| \$0.10 | \$10 | \$0.27 |
| \$0.15 | \$15 | \$0.38 |
| \$0.20 | \$20 | \$0.48 |
| \$0.25 | \$25 | \$0.56 |
| \$0.30 | \$30 | \$0.63 |
| \$0.35 | \$35 | \$0.68 |
| \$0.40 | \$40 | \$0.72 |
| \$0.45 | \$45 | \$0.74 |
| \$0.50 | \$50 | \$0.75 |
| \$0.55 | \$55 | \$0.74 |
| \$0.60 | \$60 | \$0.72 |
| \$0.65 | \$65 | \$0.68 |
| \$0.70 | \$70 | \$0.63 |
| \$0.75 | \$75 | \$0.56 |
| \$0.80 | \$80 | \$0.48 |
| \$0.85 | \$85 | \$0.38 |
| \$0.90 | \$90 | \$0.27 |
| \$0.95 | \$95 | \$0.14 |
| \$0.99 | \$99 | \$0.03 |
| \$0.01 | \$1 | \$0.05 |
| \$0.05 | \$5 | \$0.24 |
| \$0.10 | \$10 | \$0.45 |
| \$0.15 | \$15 | \$0.64 |
| \$0.20 | \$20 | \$0.80 |
| \$0.25 | \$25 | \$0.94 |
| \$0.30 | \$30 | \$1.05 |
| \$0.35 | \$35 | \$1.14 |
| \$0.40 | \$40 | \$1.20 |
| \$0.45 | \$45 | \$1.24 |
| \$0.50 | \$50 | \$1.25 |
| \$0.55 | \$55 | \$1.24 |
| \$0.60 | \$60 | \$1.20 |
| \$0.65 | \$65 | \$1.14 |
| \$0.70 | \$70 | \$1.05 |
| \$0.75 | \$75 | \$0.94 |
| \$0.80 | \$80 | \$0.80 |
| \$0.85 | \$85 | \$0.64 |
| \$0.90 | \$90 | \$0.45 |
| \$0.95 | \$95 | \$0.24 |
| \$0.99 | \$99 | \$0.05 |
The fee in USDC **peaks at 50%** probability (\$0.75) and decreases symmetrically toward both extremes.
The fee in USDC **peaks at 50%** probability (\$1.25) and decreases symmetrically toward both extremes.
</Tab>
<Tab title="Finance / Politics / Mentions / Tech">
@@ -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>
+24 -24
View File
@@ -33,7 +33,7 @@ Where **C** = number of shares traded and **p** = price of the shares.
| Category | Taker Fee Rate | Maker Fee Rate | Maker Rebate |
| --------------- | -------------- | -------------- | ------------ |
| Crypto | 0.07 | 0 | 20% |
| Sports | 0.03 | 0 | 25% |
| Sports | 0.05 | 0 | 15% |
| Finance | 0.04 | 0 | 25% |
| Politics | 0.04 | 0 | 25% |
| Economics | 0.05 | 0 | 25% |
@@ -48,7 +48,7 @@ Taker fees are calculated in USDC 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>
@@ -86,29 +86,29 @@ Taker fees are calculated in USDC and vary based on the share price. The fee amo
<Tab title="Sports">
| Price | Trade Value | Taker Fee (USDC) |
| ------ | ----------- | ---------------- |
| \$0.01 | \$1 | \$0.03 |
| \$0.05 | \$5 | \$0.14 |
| \$0.10 | \$10 | \$0.27 |
| \$0.15 | \$15 | \$0.38 |
| \$0.20 | \$20 | \$0.48 |
| \$0.25 | \$25 | \$0.56 |
| \$0.30 | \$30 | \$0.63 |
| \$0.35 | \$35 | \$0.68 |
| \$0.40 | \$40 | \$0.72 |
| \$0.45 | \$45 | \$0.74 |
| \$0.50 | \$50 | \$0.75 |
| \$0.55 | \$55 | \$0.74 |
| \$0.60 | \$60 | \$0.72 |
| \$0.65 | \$65 | \$0.68 |
| \$0.70 | \$70 | \$0.63 |
| \$0.75 | \$75 | \$0.56 |
| \$0.80 | \$80 | \$0.48 |
| \$0.85 | \$85 | \$0.38 |
| \$0.90 | \$90 | \$0.27 |
| \$0.95 | \$95 | \$0.14 |
| \$0.99 | \$99 | \$0.03 |
| \$0.01 | \$1 | \$0.05 |
| \$0.05 | \$5 | \$0.24 |
| \$0.10 | \$10 | \$0.45 |
| \$0.15 | \$15 | \$0.64 |
| \$0.20 | \$20 | \$0.80 |
| \$0.25 | \$25 | \$0.94 |
| \$0.30 | \$30 | \$1.05 |
| \$0.35 | \$35 | \$1.14 |
| \$0.40 | \$40 | \$1.20 |
| \$0.45 | \$45 | \$1.24 |
| \$0.50 | \$50 | \$1.25 |
| \$0.55 | \$55 | \$1.24 |
| \$0.60 | \$60 | \$1.20 |
| \$0.65 | \$65 | \$1.14 |
| \$0.70 | \$70 | \$1.05 |
| \$0.75 | \$75 | \$0.94 |
| \$0.80 | \$80 | \$0.80 |
| \$0.85 | \$85 | \$0.64 |
| \$0.90 | \$90 | \$0.45 |
| \$0.95 | \$95 | \$0.24 |
| \$0.99 | \$99 | \$0.05 |
The fee in USDC **peaks at 50%** probability (\$0.75) and decreases symmetrically toward both extremes.
The fee in USDC **peaks at 50%** probability (\$1.25) and decreases symmetrically toward both extremes.
</Tab>
<Tab title="Finance / Politics / Mentions / Tech">
+6 -4
View File
@@ -208,7 +208,7 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
.size(dec!(10))
.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?;
@@ -217,9 +217,11 @@ GTD orders auto-expire at a specified time. Useful for quoting around known even
</CodeGroup>
<Note>
There is a security threshold of one minute on GTD expiration. To set an
effective lifetime of N seconds, use `now + 60 + N`. For example, for a
30-second effective lifetime, set the expiration to `now + 60 + 30`.
GTD orders expire one minute before their stated expiration as a security
threshold. To set an effective lifetime of N seconds, use `now + 60 + N`.
In addition, the expiration must be at least three minutes in the future —
orders expiring sooner are rejected — so the minimum effective lifetime is
about two minutes.
</Note>
***
+4 -3
View File
@@ -33,9 +33,10 @@ The underlying order primitive is structured, hashed, and signed using the [EIP-
* **GTC** and **GTD** are limit order types — they rest on the book at your specified price.
<Note>
**GTD expiration**: There is a security threshold of one minute. If you need
the order to expire in 90 seconds, the correct expiration value is `now + 1
minute + 30 seconds`.
**GTD expiration**: Orders expire one minute before their stated expiration
as a security threshold, and the expiration must be at least three minutes
in the future. For a 5-minute effective lifetime, the correct expiration
value is `now + 1 minute + 5 minutes`.
</Note>
### Post-Only Orders