Versioned change history for PAX Trader Track API. Follow the Changelog for release announcements.
PAX follows Semantic Versioning for the public API surface:
| Change type | Version bump | Advance notice |
|---|---|---|
| Breaking — endpoint removed, field renamed/removed, type changed, auth changed | MAJOR (v1 → v2) | 90 days min; deprecated endpoint returns Deprecation header |
| Additive — new endpoint, new optional field, new enum value | MINOR (v1.0 → v1.1) | None (safe to deploy anytime) |
| Fix — bug fix, spec doc update, non-behavior-changing | PATCH (v1.0.0 → v1.0.1) | None |
PAX Adaptive Fee Curve (PAF) + Liquidity Quality Framework (LQF) — full replacement of the flat-fee + weekly-rollup model. Root-cause ship of the MM incentive redesign — snapshots become autonomous, payouts become daily, fees become price-adaptive.
taker_bps = clamp(PAF_BASE × 4 × price × (1-price), PAF_FLOOR, PAF_CEILING). Defaults: BASE=20 · FLOOR=8 · CEILING=25. Extreme prices (<0.10 or >0.90) hit the 8 bps floor — competitive with volume-cashback venues without giving away free trades.rebate_bps = 3 + 5 × lqf_score. Old flat 2 bps rebate retired.mm_stipend_pool bucket (5 bps at auto tier, 4 bps at genesis). Bucket funds daily LQF payouts; no longer routes through the LP holder cron.lib/adaptiveFeeCurve.js (replaces lib/clobFees.js — old kept as legacy shim for 1 release), lib/adaptiveFeeAttribution.js (replaces lib/fiveActorFees.js).PAF_ENABLED=on (default on after v2.5.0), PAF_BASE_BPS=20, PAF_FLOOR_BPS=8, PAF_CEILING_BPS=25, PAF_MAKER_REBATE_BPS=3, PAF_MAKER_REBATE_MAX_BPS=8.services/liquidityQualitySnapshotCron.js) — autonomous, leader-only, Redis SET NX EX 45. Independent of quote-post events — MMs cannot game score by posting-and-cancelling.services/marketStipendDistributionCron.js) — computes user_share × market_liquidity_stipend, writes mm_stipend_payouts + balanceManager.credit. Idempotent via UNIQUE(user_id, market_id, epoch_start_at).services/mmStipendPoolAccumulatorCron.js) — sweeps FEE_MM_STIPEND events into per-market mm_stipend_pool_ledger.accumulated_usdt.market_lqf_config (per-market max_qualifying_spread_bps, depth_floor_usdt, daily_stipend_usdt), mm_quality_snapshots, mm_stipend_payouts, mm_stipend_pool_ledger.GET /v1/mm/stipend/estimate (real-time forecast), GET /v1/mm/stipend/history, GET /v1/liquidity/leaderboard now returns lqf_score + continuity_pct + estimated_stipend_next_epoch.lib/lpPositionsRollup.js weekly rollup — replaced by daily LQF payout. Old mm_lp_positions data preserved 90 days for audit.TAKER_FEE_BPS_BASE constant — replaced by PAF_BASE_BPS = 20.MAKER_REBATE_BPS — replaced by quality-scaled 3-8 bps.Existing fee_ledger and financial_event rows preserved unchanged. New PAF/LQF entries carry fee_bps = effective PAF value (not flat 30). CF Worker apps/api/src/index.ts DEFAULT_FEE_BPS aligned from 400 (simulation) to 20 (mirrors VM PAF_BASE). Docs, SEO, and 14 locales updated in the same release.
100% top-tier polish — 8 remaining gaps closed after v2.4.0 fee-ledger ship.
_executeTradeInternalRaw now looks up builder_registry for the trading user (cached per-request via user.__pax_builder_id_cache); if registered, _executionBuilderId is set on the position row. Both v1 settle-time and v2 buy-time FEE_AMM_HOUSE events now populate execution_builder_id — AMM fills earn builder attribution just like CLOB.FEE_AMM_HOUSE hook — v2 pricing model captures edge at buy via inflated displayPrice. New hook writes ledger event at trade placement (notional × houseEdge). Completes accounting parity between v1 and v2 models._priceModelV2 marker — addPosition() now forwards the flag from payload into the persisted row, so settle-time hook correctly distinguishes v1 vs v2.@predictasiax/[email protected] ships new pax.settle.me() / pax.settle.adminBuilder() / pax.settle.adminCreator().pax-api==2.4.0 ships new pax.settle_self() / pax.admin_settle_builder() / pax.admin_settle_creator(). Also auto-injects Idempotency-Key on POST/PUT/PATCH/DELETE and supports extra_headers./v1/builders/me/settle, /v1/admin/builders/{userId}/settle, /v1/admin/creators/{userId}/settle.components/LimitOrderForm.js feeEstimate 50 bps → 30 bps; three /learn pages (builder-tiers-comparison, attribution-and-builder-programs, prediction-market-vs-futures) updated in both English and Chinese to reflect 30 bps + progressive tier.Complete fee accounting — AMM + parlay ledger writes, LP fee distribution, dynamic fee (env-gated). Closes 4 architectural gaps found in the fee-flow audit.
FEE_AMM_HOUSE ledger events — fast-round settle now writes per-position house-edge capture to financial_event on Neon (v1 model: lots × houseEdge on winners; v2 already captured at buy time). Idempotency key fee_amm:<marketId>:<roundId>:<userId>:<side>. Attribution field populated from position's _executionBuilderId when wired at place-time. Enables unified fee reporting + builder attribution across CLOB + AMM.FEE_PARLAY_HOUSE ledger events — parlay settle now writes house-margin capture on WON bets (effective_payout × parlay_margin). LOST bets: no fee event (stake retention is game outcome, not fee — industry standard). Idempotency key fee_parlay:<bet_id>. Attribution: parlay_bets.execution_builder_id populated at place-time if user is registered in builder_registry.parlay_bets.execution_builder_id — new nullable text column on supabase2 (pax_local). Populated at parlay place time via builder_registry lookup. Historical bets remain null (backfill separate).services/lpFeeDistributionCron.js — hourly cron aggregates unsettled FEE_LP events (12 bps at auto tier, 5-7 bps at higher; from CLOB) and distributes pro-rata to active lp_positions by shares. Updates total_earned per position + writes lp_pnl_log audit rows (pseudo-round clob_lp_dist_<timestamp>) + marks Neon events settled with the distribution ID. Closes gap where CLOB LP share accumulated in pool:lp but never reached actual LP holder accounts. Env: LP_FEE_DISTRIBUTION_ENABLED=on (default off), LP_FEE_DISTRIBUTION_INTERVAL_MS=3600000, LP_FEE_DISTRIBUTION_MIN_USD=0.10. No active LP positions? Events settled to lp_dist_noholders_<ts> bucket, fees stay with platform_net.PAX_DYNAMIC_FEE_ENABLED=on, CLOB taker fee scales as rate × price × (1 - price) × 4 — industry-standard curve formula. Max fee (30 bps) at 50/50 markets; approaches 0 at extremes (near 0¢ / 100¢). Verified per-price at unit-test level: 50/50=30bps, 70/30=25.2bps, 90/10=10.8bps, 99/1=1.19bps effective. Applied identically in both lib/clobFees.js (charge path) and lib/fiveActorFees.js (split path) — fee-sync-guard boot check remains valid. Default OFF (flat 30 bps stays) — turn on after modeling revenue impact on live volume distribution.CLOB taker fee cut 50 → 30 bps + progressive tier for builder share. AMM fast-round house_edge + spread unchanged (risk buffer). Parlay margin unchanged (industry-standard 15%).
lib/fiveActorFees.js TAKER_FEE_BPS_BASE from 0.005 to 0.003. Cut to attract CLOB volume ahead of the intended long-term CLOB-primary venue. AMM fast-round markets keep their house_edge (0.5-8% dynamic) + spread (2-8% dynamic, 83% platform share) as market-making risk buffer during the volume ramp.lib/fiveActorFees.js now applies a builder-tier-aware split at trade time:
self_serve, read_live, trade_capped) — 6 acq + 6 exec = 12 bps combined builder share (40% of the 30 bps fee)trade_full — 7 acq + 7 exec = 14 bps (47% of fee)genesis, partner — 8 acq + 8 exec = 16 bps (53% of fee)operator + lp + market_creator, all splits still sum to 30. LP floor: 5 bps at genesis / partner (protects liquidity depth).
lib/feeSplitPoller.js now looks up execution_builder's current tier from builder_registry for every trade batch (per-tick cache dedups repeated lookups) and passes to computeFivePartyFees(). Tier changes flow through to financial_event automatically.GET /v1/fees/estimate accepts builder_tier — preview any tier's split from any key. Backward-compatible; omit for auto tier.fee block shape — just different numeric values. Clients that hard-coded taker_fee_bps: 50 will see 30 now.ACTOR_BPS_* env vars still work; defaults now sum to 30 not 50. Env validator throws at load time if custom values don't sum to TAKER_FEE_BPS_TOTAL.financial_event rows preserved — historical splits at 50 bps stay as-is; new fills use 30 bps.Application flow — email notifications + tier auto-graduation.
POST /v1/apply with track genesis or institutional now fires three side-effects on submission: (1) admin Telegram alert via the existing tgAlert channel, (2) admin email to ADMIN_EMAIL with application details + direct approve/reject curl commands, (3) if the applicant provided an email, a confirmation email with their application_code and status-polling URL.services/paxBuilderTierGraduationCron.js. Scans builder_registry every 15 minutes, computes 30-day attributed CLOB volume via clob_trades.execution_builder_id, and auto-graduates builders across two tier steps: self_serve → read_live at $100 30d volume, and read_live → trade_capped at $1,000 30d volume. Caps at trade_capped; higher tiers (trade_full, genesis, partner) require admin operator approval. 24-hour dedup window per builder. Every graduation writes to builder_attribution_log with event='tier_auto_graduate' and sends the builder a notification email (if their contact_email is set).TRACK_INITIAL_TIER map in routes/sandboxKeys.js — extension point for setting different initial tiers per track. All 18 auto-provisioning tracks currently start on self_serve (kept uniform for safety); the map makes future per-track differentiation a one-line change.BUILDER_AUTO_GRADUATION_ENABLED — on | off (default off). Kill switch for the graduation cron.BUILDER_AUTO_GRADUATION_MAX_TIER — tier ceiling for auto (default trade_capped).BUILDER_AUTO_GRADUATION_INTERVAL_MS — scan cadence in ms (default 900000 = 15 min).ADMIN_EMAIL — inbox for admin-notification emails on new reviewed-track applications.Discoverability + SDK metadata sync — no behavior changes.
/verify is now a top-level entry in the docs navigation on every page (previously only reachable from the migration page). Also cross-linked from the home hero grid and the authentication guide's server-side-verification section.pax-api==2.2.1 — README rewritten to reflect the v2.2 API surface (sandbox key minting, batch orders, fee estimator, audit verifier). Prior 2.2.0 release included the older v1.0.0 quickstart content, which caused the PyPI project page to display outdated install and usage examples. No client code changes; upgrade with pip install --upgrade pax-api.@predictasiax/[email protected] — unchanged (README already reflected current surface).Trust Layer — public Merkle verifier over the operational ledger.
GET /v1/audit/status — live counts of events + Merkle batches + anchored batches + anchor lag. Any third party can hit this to understand the shape of the operational audit chain in real time.GET /v1/audit/batches/latest — most recent Merkle batch metadata (batch_num, merkle_root, first_seq, last_seq, event_count, anchored_at, anchor_target, anchor_ref).GET /v1/audit/batches/{num} — inspect any historical batch by batch_num.GET /v1/audit/events/{seq} — inspect a single hash-chained event (event_hash + prev_event_hash + payload + batch linkage — the full hash-chain surface).GET /v1/audit/proof/{seq} — Merkle inclusion proof (sibling hashes) that proves the event is included in its batch's merkle_root. Algorithm: OpenZeppelin sorted-pair SHA-256 — Solidity MerkleProof.verify compatible for on-chain verification.GET /v1/audit/anchor/{num} — resolve a batch number to its external anchor URL (Cloudflare R2 signed payload) for out-of-band verification.@predictasiax/[email protected] ships pax.audit.* resource + static AuditResource.verifyProof() / .verifyProofAsync() helpers (Node crypto + WebCrypto). pax-api==2.2.0 ships pax.audit_*() methods + PaxClient.verify_merkle_proof() static.The event log has been hash-chained and Merkle-batched since v1 — this release exposes it publicly. See docs.predictasiax.com/verify for the full trust model: any auditor, investor, or third-party verifier can independently reconstruct the event chain, verify Merkle inclusion for any event, and check R2 anchor payloads out-of-band. Building on PAX means every fill your app routes carries a cryptographic receipt that outlives the PAX API itself.
Batch trading + pre-trade fee preview.
POST /v1/orders/batch — up to 25 orders per request (env-tunable BATCH_ORDERS_MAX). Sequential CLOB processing (single-writer per market). Per-item results[].ok + top-level summary — one bad order does not fail the whole batch. Returns 413 BATCH_TOO_LARGE when over cap.DELETE /v1/orders/batch — up to 50 cancels per request (env-tunable BATCH_CANCEL_MAX).GET /v1/fees/estimate — returns identical fee block shape as post-trade responses (5-actor splits + attribution + breakdown + ledger_preview). Powered by lib/fiveActorFees — env-tunable bps (ACTOR_BPS_*) flow through automatically, so pre-trade estimates and post-trade settlements can never diverge.@predictasiax/[email protected]: pax.orders.placeBatch(), pax.orders.cancelBatch(), new pax.fees.estimate() namespace.pax-api==2.1.0: pax.place_orders_batch(), pax.cancel_orders_batch(), pax.estimate_fees().Builder Program v2.0 — full ecosystem infrastructure SHIPPED
Base URL: https://api.predictasiax.com/v1. All endpoints below are live and returning real D1-backed data.
GET /v1/builders/me, GET /v1/apps, GET/POST /v1/apps/{id}/keys, DELETE /v1/apps/{id}/keys/{kid}, POST /v1/apps/{id}/keys/{kid}/rotate. Raw secret shown once.self_serve / verified / trade_capped / trade_full / genesis / partner. Per-order and daily notional caps enforced at fill time. Error code TIER_LIMIT_EXCEEDED (429) with breach details.POST /v1/sandbox-keys — public, anonymous, returns sk_live_* tagged tier=self_serve with $10 per-order / $100 daily caps and 30-day expiry. Same host as production — promote to verified by upgrading tier, no code changes.POST /v1/builders/me/password, GET /v1/builders/me/sessions, POST /v1/builders/me/sessions/revoke-others.GET /v1/attribution/fills, GET /v1/revenue, GET /v1/revenue/ledger. Every fill writes idempotent financial_event rows on the shared Neon ledger. Total taker fee 50 bps of notional, split five ways:
acquisition_builder — 10 bps (20% of taker fee; the builder who first onboarded the user)execution_builder — 10 bps (20%; the builder whose app the trade routed through)operator — 5 bps (10%; PAX operator running the venue)market_creator — 8 bps (16%; whoever composed the market)lp — 12 bps (24%; liquidity pool backstop)platform_net — 5 bps residual (10%; also absorbs any unfilled attribution role, protecting revenue)clob_trades.execution_builder_id/acquisition_builder_id at trade time, backed by the lib/fiveActorFees.js module. Idempotency key format: fee_split:<trade_id>:<event_type>.
POST /v1/apply — accepts track + optional org / url / email / description. IP-rate-limited 5/hr. Auto-provisions a live sk_live_* API key on submit for 18 tracks (app / agent / data / distribution / market / liquidity / oracle / reviewer / operator / self_serve / 8× rfb-*); routes genesis and institutional to human review. Status polling via GET /v1/apply/{code}.https://connect.predictasiax.com — browser HTML login/consent, refresh-token reuse detection revokes entire family (REFRESH_TOKEN_REUSED 401).https://mcp.predictasiax.com — 7 tools: market_search, probability_movers, resolution_evidence, portfolio_read, place_order, cancel_order, sandbox_agent_examples. Bearer token forwarded to REST.POST/GET/PATCH/DELETE /v1/webhooks + POST /v1/webhooks/{id}/rotate-secret + GET /v1/webhooks/{id}/deliveries. 5 event types: trade.filled, market.resolved, payout.available, payout.paid, auth.token.revoked. HMAC signature, retry with exponential backoff./v1/subaccounts full CRUD, /v1/subaccounts/{id}/grants for signed delegation.GET /v1/composer/templates, POST /v1/composer/proposals./v1/mm/quotes, /v1/rfq, /v1/rfq/{id}/quotes, /v1/rfq/{id}/accept./v1/admin/access-requests, /v1/admin/tiers/graduate, /v1/admin/builders, /v1/admin/audit, /v1/admin/abuse-flags. Gated by X-Admin-Key header, timing-safe compared.GET /v1/markets, GET /v1/markets/{id}, GET /v1/markets/templates, GET /v1/healthGET /v1/data/history, GET /v1/data/movers, orderbook, trades, candlesPOST /v1/orders, POST /v1/orders/{id}/cancel, template-driven market creation with deterministic ID (m_<sha256[0:16]>), idempotent under same (template, params, creator) tuple{ok, data, meta} on every canonical response; meta includes request_id, server_ts_ms, duration_ms, server_region; deep snake_case keys; money as decimal string; *_at_ms sibling for every timestamp; full JSON Schema param validation with actionable error details (details.field, details.allowed, details.got)wss://predictasiax.com/ws with 4 client methods (SUBSCRIBE / UNSUBSCRIBE / AUTH / LOCALE) and 48 server event types — Redis Stream sequence numbers on the book stream for client gap-detection resynccom.predictasiax/mcp, GitHub starter kits, Builder Directory with volume leaderboardchain_data JSONB envelope on core tables carries on-chain settlement metadata without breaking client integrations<predictasiax-market> Web Component, attribution baked inplatform_mm mode remains the default counterparty for markets without an LP poolWhen an endpoint or field is deprecated:
Deprecation: <date> and Sunset: <date> (RFC 8594)The canonical spec + AsyncAPI spec + Postman environment files at Downloads are versioned along with each release above.