Skip to content

Commit 2e75b36

Browse files
committed
Merge pull request #979 from pmxt-dev/docs/per-method-hosted-toggle
feat(docs): per-method hosted/self-hosted toggle on Group A reference pages (v2.49.2)
2 parents 0602bc0 + 0ae8367 commit 2e75b36

16 files changed

Lines changed: 2387 additions & 79 deletions

changelog.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [2.49.2] - 2026-06-09
6+
7+
Per-method docs follow-up to 2.49.1 — every Group A method (`createOrder`, `buildOrder`, `submitOrder`, `cancelOrder`, `fetchBalance`, `fetchPositions`, `fetchOpenOrders`, `fetchMyTrades`, `fetchOrder`, `fetchClosedOrders`, `fetchAllOrders`) now has a synchronized `Hosted (recommended)` / `Self-hosted` tab toggle on its reference page, so customers see the hosted endpoint and the v2.49 SDK constructor shape by default and can flip to the local-sidecar variant in place. Mintlify synchronizes tab selection across pages via shared label keys, so the choice persists as the user navigates the API Reference.
8+
9+
### Added
10+
11+
- **Docs (`docs/api-reference/`)**: 11 new shadow MDX files — one per Group A method — wrapping the existing OpenAPI auto-render in a `<Tabs>` toggle. `Hosted (recommended)` tab listed first on every page so it's the default; `Self-hosted` second. Tab labels are byte-identical across all 11 files for cross-page sync.
12+
- **Core (`openapi-hosted.json`)**: 9 new operations documenting the `trade.pmxt.dev/v0/*` trading surface — `buildOrderHosted` (POST `/v0/trade/build-order`), `submitOrderHosted` (POST `/v0/trade/submit-order`), `createOrderHosted` (SDK-convenience POST `/v0/trade/create-order` documentation entry), `cancelOrderHosted` (POST `/v0/orders/cancel/build`), `fetchBalanceHosted` (GET `/v0/user/{address}/balances`), `fetchPositionsHosted` (GET `/v0/user/{address}/positions`), `fetchOpenOrdersHosted` (GET `/v0/orders/open`), `fetchMyTradesHosted` (GET `/v0/user/{address}/trades`), `fetchOrderHosted` (GET `/v0/orders/{order_id}`). Each carries Python + TypeScript `x-codeSamples` using the v2.49 hosted constructor (`pmxtApiKey`, `walletAddress`, `privateKey`), error responses covering 401/403/404/410/422/503, and bearer auth via the existing `bearerAuth` security scheme. Plus 10 new component schemas for the v0 request/response shapes, all referencing existing components (`Order`, `Balance`, etc.) from 2.49.1.
13+
- **Docs (`docs.json`)**: Trading and "Orders & Positions" sidebar groups now reference the 11 shadow MDX slugs directly, so Mintlify renders the toggle pages instead of auto-generating from `openapi.json`.
14+
15+
### Fixed
16+
17+
- **Core (`createOrder` / `buildOrder` code samples)**: Pre-existing JSDoc rot — the auto-generated reference pages showed `type="market"` combined with `price=0.55`, an incoherent combination since price is only meaningful for limit orders. Replaced with coherent limit-order samples across all 16 venues (32 createOrder + 32 buildOrder samples, 64 line changes total). The fix lives in `core/scripts/generate-openapi.js`'s `PARAM_OVERRIDES` map so future regeneration emits the correct shape.
18+
19+
### Not addressed (out of scope, flagged for follow-up)
20+
21+
- **`fetchClosedOrdersHosted` / `fetchAllOrdersHosted`**: no underlying hosted endpoint exists — both methods raise `NotSupported` in hosted mode (closed orders are modeled as trades; use `fetchMyTrades` for historical fills). The shadow MDX files surface this via a `<Warning>` on the Hosted tab linking to `fetchMyTrades`.
22+
- **Escrow methods**: `client.escrow.{approve, deposit, withdraw, withdrawals}` aren't in Group A and so don't have toggle pages yet. They're hosted-only (no self-hosted variant exists), so a follow-up could add single-tab reference pages.
23+
- **Generator capability map gap**: `buildCapabilityMap()` in `core/scripts/generate-openapi.js` only instantiates 13 of the 16 exported exchange classes, omitting `Hyperliquid`, `GeminiTitan`, and `Mock`. Re-running the generator drops their `x-codeSamples`. The merged main spec retains the missing samples from a prior generator run; the surgical fix here didn't disturb them. Worth a real fix in a follow-up.
24+
525
## [2.49.1] - 2026-06-08
626

727
Positioning-shift patch on top of 2.49.0 — the hosted trading mode shipped in 2.49.0 but the docs, READMEs, and OpenAPI schemas still defaulted to the self-hosted sidecar path. This release flips the default everywhere the SDK + docs surface a customer hits: hosted PMXT is the primary experience; self-hosting becomes the advanced escape hatch. No SDK runtime behavior changes — pure documentation, schema, and copy work. Marketing-site changes ship separately in a sibling pmxt-website PR.

core/scripts/generate-openapi.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,28 @@ const PARAM_OVERRIDES = {
461461
fetchRelatedMarkets: [{ name: 'marketId', value: '12345' }],
462462
fetchMatchedMarkets: [{ name: 'minDifference', value: 0.05 }],
463463
fetchMatchedPrices: [{ name: 'minDifference', value: 0.05 }],
464+
// Self-hosted createOrder / buildOrder samples: limit order shape only.
465+
// The auto-extracted shape mixed `type: "market"` with `price: 0.55`,
466+
// which is incoherent (price is only meaningful for limit orders) and
467+
// tacked on internal-only fields (fee, tickSize, negRisk, onBehalfOf)
468+
// that the average reader shouldn't see. A clean limit-order example
469+
// is the simplest correct shape.
470+
createOrder: [
471+
{ name: 'marketId', value: '12345' },
472+
{ name: 'outcomeId', value: '67890' },
473+
{ name: 'side', value: 'buy' },
474+
{ name: 'type', value: 'limit' },
475+
{ name: 'amount', value: 10 },
476+
{ name: 'price', value: 0.55 },
477+
],
478+
buildOrder: [
479+
{ name: 'marketId', value: '12345' },
480+
{ name: 'outcomeId', value: '67890' },
481+
{ name: 'side', value: 'buy' },
482+
{ name: 'type', value: 'limit' },
483+
{ name: 'amount', value: 10 },
484+
{ name: 'price', value: 0.55 },
485+
],
464486
};
465487

466488
const FULL_OVERRIDES = {

docs/api-reference/buildOrder.mdx

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: buildOrder
3+
description: Build an order payload without submitting it. Hosted returns EIP-712 typed data to sign locally.
4+
---
5+
6+
<Tabs>
7+
<Tab title="Hosted (recommended)">
8+
<Note>
9+
The hosted path routes to `POST trade.pmxt.dev/v0/trade/build-order` and is
10+
the default when `pmxt_api_key` is set. Returns a `built_order_id` plus EIP-712
11+
typed data the wallet must sign before calling
12+
[`submitOrder`](/api-reference/submitOrder). Pass catalog UUIDs
13+
(`market_id`, `outcome_id`), not venue-native ids. See
14+
[hosted trading](/concepts/hosted-trading) for the end-to-end flow.
15+
Get a key at [pmxt.dev/dashboard](https://pmxt.dev/dashboard).
16+
</Note>
17+
18+
<CodeGroup>
19+
```python Python
20+
import pmxt
21+
22+
client = pmxt.Polymarket(
23+
pmxt_api_key="YOUR_PMXT_API_KEY",
24+
wallet_address="0xYourWallet",
25+
private_key="0x...",
26+
)
27+
built = client.build_order(
28+
market_id="12345678-1234-1234-1234-123456789abc",
29+
outcome_id="abcdef01-2345-6789-abcd-ef0123456789",
30+
side="buy",
31+
type="limit",
32+
amount=10,
33+
price=0.55,
34+
)
35+
print(built.expiry, built.raw)
36+
# Sign + submit later with client.submit_order(built).
37+
```
38+
39+
```javascript TypeScript
40+
import { Polymarket } from "pmxtjs";
41+
42+
const client = new Polymarket({
43+
pmxtApiKey: "YOUR_PMXT_API_KEY",
44+
walletAddress: "0xYourWallet",
45+
privateKey: "0x...",
46+
});
47+
48+
const built = await client.buildOrder({
49+
marketId: "12345678-1234-1234-1234-123456789abc",
50+
outcomeId: "abcdef01-2345-6789-abcd-ef0123456789",
51+
side: "buy",
52+
type: "limit",
53+
amount: 10,
54+
price: 0.55,
55+
});
56+
console.log(built.expiry, built.raw);
57+
// Sign + submit later with client.submitOrder(built).
58+
```
59+
60+
```bash curl
61+
curl -X POST "https://trade.pmxt.dev/v0/trade/build-order" \
62+
-H "Authorization: Bearer $PMXT_API_KEY" \
63+
-H "Content-Type: application/json" \
64+
-d '{
65+
"market_id": "12345678-1234-1234-1234-123456789abc",
66+
"outcome_id": "abcdef01-2345-6789-abcd-ef0123456789",
67+
"side": "buy",
68+
"order_type": "limit",
69+
"amount": 10,
70+
"denom": "shares",
71+
"price": 0.55,
72+
"user_address": "0xYourWallet"
73+
}'
74+
```
75+
</CodeGroup>
76+
</Tab>
77+
78+
<Tab title="Self-hosted">
79+
<Note>
80+
The self-hosted path uses the local sidecar at
81+
`POST localhost:3847/api/{exchange}/buildOrder`. Returns the venue-native
82+
signed order or request body for inspection or deferred submission via
83+
[`submitOrder`](/api-reference/submitOrder). See
84+
[Self-hosted](/guides/self-hosted) for setup.
85+
</Note>
86+
87+
<CodeGroup>
88+
```python Python
89+
import pmxt
90+
91+
client = pmxt.Polymarket(
92+
api_key="YOUR_VENUE_API_KEY",
93+
api_secret="YOUR_VENUE_API_SECRET",
94+
passphrase="YOUR_PASSPHRASE",
95+
private_key="YOUR_PRIVATE_KEY",
96+
proxy_address="YOUR_PROXY_ADDRESS",
97+
)
98+
built = client.build_order(
99+
market_id="12345",
100+
outcome_id="67890",
101+
side="buy",
102+
type="limit",
103+
amount=10,
104+
price=0.55,
105+
)
106+
print(built.exchange, built.raw)
107+
```
108+
109+
```javascript TypeScript
110+
import { Polymarket } from "pmxtjs";
111+
112+
const client = new Polymarket({
113+
apiKey: "YOUR_VENUE_API_KEY",
114+
apiSecret: "YOUR_VENUE_API_SECRET",
115+
passphrase: "YOUR_PASSPHRASE",
116+
privateKey: "YOUR_PRIVATE_KEY",
117+
proxyAddress: "YOUR_PROXY_ADDRESS",
118+
});
119+
120+
const built = await client.buildOrder({
121+
marketId: "12345",
122+
outcomeId: "67890",
123+
side: "buy",
124+
type: "limit",
125+
amount: 10,
126+
price: 0.55,
127+
});
128+
console.log(built.exchange, built.raw);
129+
```
130+
131+
```bash curl
132+
curl -X POST "http://localhost:3847/api/polymarket/buildOrder" \
133+
-H "Content-Type: application/json" \
134+
-d '{"args":[{"marketId":"12345","outcomeId":"67890","side":"buy","type":"limit","amount":10,"price":0.55}]}'
135+
```
136+
</CodeGroup>
137+
</Tab>
138+
</Tabs>

docs/api-reference/cancelOrder.mdx

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
title: cancelOrder
3+
description: Cancel an open order. Hosted uses a two-call build -> sign -> cancel chain.
4+
---
5+
6+
<Tabs>
7+
<Tab title="Hosted (recommended)">
8+
<Note>
9+
The hosted path is a two-call chain: `POST trade.pmxt.dev/v0/orders/cancel/build`
10+
returns EIP-712 typed data for the wallet to sign, then
11+
`POST trade.pmxt.dev/v0/orders/cancel` submits the signature. The SDK's
12+
`cancel_order()` chains both calls. Get a key at
13+
[pmxt.dev/dashboard](https://pmxt.dev/dashboard).
14+
</Note>
15+
16+
<CodeGroup>
17+
```python Python
18+
import pmxt
19+
20+
client = pmxt.Polymarket(
21+
pmxt_api_key="YOUR_PMXT_API_KEY",
22+
wallet_address="0xYourWallet",
23+
private_key="0x...",
24+
)
25+
cancelled = client.cancel_order("order_abc123")
26+
print(cancelled.id, cancelled.status)
27+
```
28+
29+
```javascript TypeScript
30+
import { Polymarket } from "pmxtjs";
31+
32+
const client = new Polymarket({
33+
pmxtApiKey: "YOUR_PMXT_API_KEY",
34+
walletAddress: "0xYourWallet",
35+
privateKey: "0x...",
36+
});
37+
38+
const cancelled = await client.cancelOrder("order_abc123");
39+
console.log(cancelled.id, cancelled.status);
40+
```
41+
42+
```bash curl
43+
# Step 1: build
44+
curl -X POST "https://trade.pmxt.dev/v0/orders/cancel/build" \
45+
-H "Authorization: Bearer $PMXT_API_KEY" \
46+
-H "Content-Type: application/json" \
47+
-d '{"order_id":"order_abc123","user_address":"0xYourWallet"}'
48+
49+
# Step 2: sign the typed_data locally, then submit
50+
curl -X POST "https://trade.pmxt.dev/v0/orders/cancel" \
51+
-H "Authorization: Bearer $PMXT_API_KEY" \
52+
-H "Content-Type: application/json" \
53+
-d '{"cancel_id":"cnl_abc...","signature":"0x..."}'
54+
```
55+
</CodeGroup>
56+
</Tab>
57+
58+
<Tab title="Self-hosted">
59+
<Note>
60+
The self-hosted path uses the local sidecar at
61+
`POST localhost:3847/api/{exchange}/cancelOrder` with the venue-native order id.
62+
The sidecar signs and submits the cancel directly to the venue. See
63+
[Self-hosted](/guides/self-hosted) for setup.
64+
</Note>
65+
66+
<CodeGroup>
67+
```python Python
68+
import pmxt
69+
70+
client = pmxt.Polymarket(
71+
api_key="YOUR_VENUE_API_KEY",
72+
private_key="YOUR_PRIVATE_KEY",
73+
proxy_address="YOUR_PROXY_ADDRESS",
74+
)
75+
cancelled = client.cancel_order("0xVenueOrderId")
76+
print(cancelled.id, cancelled.status)
77+
```
78+
79+
```javascript TypeScript
80+
import { Polymarket } from "pmxtjs";
81+
82+
const client = new Polymarket({
83+
apiKey: "YOUR_VENUE_API_KEY",
84+
privateKey: "YOUR_PRIVATE_KEY",
85+
proxyAddress: "YOUR_PROXY_ADDRESS",
86+
});
87+
88+
const cancelled = await client.cancelOrder("0xVenueOrderId");
89+
console.log(cancelled.id, cancelled.status);
90+
```
91+
92+
```bash curl
93+
curl -X POST "http://localhost:3847/api/polymarket/cancelOrder" \
94+
-H "Content-Type: application/json" \
95+
-d '{"args":["0xVenueOrderId"]}'
96+
```
97+
</CodeGroup>
98+
</Tab>
99+
</Tabs>

0 commit comments

Comments
 (0)