Skip to main content
Which quickstart should I use? New here? Start with Get Started in 5 minutes for the unified onboarding. This page is the Trading-API-focused quickstart. For market data, see Data API Quickstart.
This guide uses the accounts path (/api/accounts/*) — the canonical path for all integrations.
There is no sandbox or testnet. Predexon trades against the real venues. For testing, place very small orders ($1–5) on illiquid markets — the Trading API is free on every plan, so the only cost is your spread. Best Practices → Testing strategy for the recommended pattern.

Prerequisites

Get your free API key at dashboard.predexon.com before starting.

Step 1: Create an account

Accounts are created empty - no venues are provisioned automatically.
Python
import requests

HEADERS = {"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"}
BASE = "https://trade.predexon.com"

account = requests.post(f"{BASE}/api/accounts/create", headers=HEADERS).json()
account_id = account["accountId"]
print(f"Created account: {account_id}")
Save the accountId - you’ll need it for all subsequent calls.

Step 2: Enable a venue

Call POST /enable for each venue the account should trade on. Returns status: "provisioning" while the wallet is being set up; poll Get Account until the venue’s status becomes active.
Python
import time

# Enable Polymarket
requests.post(
    f"{BASE}/api/accounts/{account_id}/enable",
    headers=HEADERS,
    json={"venue": "polymarket"},
)

# Poll until ready (terminal states: "active" success, "failed" error)
for _ in range(60):
    info = requests.get(f"{BASE}/api/accounts/{account_id}", headers=HEADERS).json()
    status = info["venues"].get("polymarket", {}).get("status")
    if status == "active":
        wallet = info["venues"]["polymarket"]["address"]
        print(f"Polymarket wallet ready: {wallet}")
        break
    if status == "failed":
        raise RuntimeError(f"Provisioning failed: {info['venues']['polymarket'].get('error')}")
    time.sleep(2)
Repeat for predict, opinion, limitless, or hyperliquid as needed.

Step 3: Fund the account

Every account has one deposit wallet - a USDC address on Base. Send USDC to it, then move funds to any venue you’ve enabled with POST /transfers.
Python
# Get the deposit wallet
info = requests.get(
    f"{BASE}/api/accounts/{account_id}/deposit-info", headers=HEADERS,
).json()
deposit_address = info["address"]
print(f"Send USDC on Base to: {deposit_address}")
print(f"Current balance: {info['balance']} USDC")
To deposit from another chain (Ethereum, Arbitrum, Polygon, BSC, Optimism), call Quote Transfer with from: "external" to get a signed bridge transaction your end user submits from their own wallet. Once the deposit wallet has USDC, fund a venue:
Python
transfer = requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers=HEADERS,
    json={"from": "deposit", "to": "polymarket", "amount": "10"},
).json()
print(f"{transfer['transferId']} - {transfer['status']}")
See Funding & Withdrawals for per-venue details and the Hyperliquid funding path (via Across, not /transfers).

Step 4: Find a market

Get the venue-specific identifiers (tokenId, marketId, etc.) from the Data API.
Python
markets = requests.get(
    "https://api.predexon.com/v2/polymarket/markets",
    headers={"x-api-key": "YOUR_API_KEY"},
    params={"status": "open", "sort": "volume", "limit": 1},
).json()

market = markets["markets"][0]
token_id = market["outcomes"][0]["token_id"]  # "Yes" side
print(f"Trading: {market['title']}  token_id={token_id}")

Step 5: Place an order

Identify the market with a market bag. Required fields differ by venue - see Place Order for the per-venue matrix.
Python
order = requests.post(
    f"{BASE}/api/accounts/{account_id}/orders",
    headers=HEADERS,
    json={
        "venue": "polymarket",
        "market": {"tokenId": token_id},
        "side": "buy",
        "type": "limit",
        "size": "10",
        "price": "0.50",
    },
).json()
print(f"Order {order['orderId']} - status: {order['status']}")
The response uses the account shape: a market bag instead of a flat marketIdentifier, filled in place of sizeMatched, and a normalized status (open | filled | cancelled | expired | pending | failed).
To trade an outcome across venues without picking one, use the Order Router. Find the outcome with List Canonical Markets, inspect its equivalent venue listings with Get Canonical Outcome, then pass the predexon_id as predexonId to the router.

Step 6: Check positions

Python
positions = requests.get(
    f"{BASE}/api/accounts/{account_id}/positions", headers=HEADERS,
).json()
for p in positions["positions"]:
    print(f"{p['title']} - {p['outcome']}  size={p['size']}  pnl={p['pnl']}")
The response includes _meta.venues with per-venue status (ok / timeout / error). Use it to detect partial failures if one venue is temporarily unreachable. Pass ?aggregated=true to collapse equivalent positions across venues into single rows.

Step 7: Withdraw

When you’re done, consolidate venue balances back to the deposit wallet and send USDC to an external address - both directions use POST /transfers:
Python
# Drain a venue back to the deposit wallet
requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers=HEADERS,
    json={"from": "polymarket", "to": "deposit", "amount": "10"},
)

# Withdraw to any supported chain
requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers=HEADERS,
    json={
        "from": "deposit",
        "to": "external",
        "amount": "10",
        "destination": {
            "address": "0xYourExternalAddress",
            "chain": "base",
            "token": "USDC",
        },
    },
)

Next Steps

Placing Trades

Order types, venues, and the full trading workflow

Order Router

Trade an outcome across every venue holding it, fee-aware

Funding & Withdrawals

Deposit wallet, bridging, and external withdrawals

Fees & Monetization

Set up partner fees to earn revenue