Skip to main content
This guide uses the accounts path (/api/accounts/*).
Hyperliquid uses a separate funding path (Across) and a separate withdraw endpoint. See the Hyperliquid section below.

The deposit wallet

Every account has one deposit wallet - a USDC address on Base. Funds enter here and route to any enabled venue via POST /transfers. This replaces per-venue deposits for everything except Hyperliquid.
import requests
HEADERS = {"x-api-key": "YOUR_API_KEY"}
BASE = "https://trade.predexon.com"

info = requests.get(
    f"{BASE}/api/accounts/{account_id}/deposit-info",
    headers=HEADERS,
).json()
print(f"Send USDC on Base to: {info['address']}")
print(f"Current balance: {info['balance']} USDC")
The response includes a live balance field - use it to confirm an inbound deposit landed without checking a block explorer.

One endpoint for every direction

POST /transfers is the single verb for every fund movement. Identify the source with from and the destination with to - <venue> is one of polymarket, predict, opinion, limitless:
fromtoWhat it does
deposit<venue>Fund a venue from the deposit wallet
<venue>depositDrain a venue back to the deposit wallet
depositexternalWithdraw USDC to any supported chain
externaldepositInbound from another chain - see Inbound deposits (uses POST /transfers/quote, not /transfers)
Rejected routes return 400 synchronously with the unified error envelope ({ error, message, requestId } — see Error Handling). The error field carries the code below:
RouteerrorWhy
<venue><venue>unsupported_route_v1Drain to deposit first, then fund the other venue.
<venue>externalwithdraw_via_depositDrain to deposit first, then withdraw from there.
from === tosame_endpointSource and destination must differ.
hyperliquid on either sidehyperliquid_uses_acrossSee Hyperliquid below.
amount < $1 USDamount_below_minimumBridge fees dominate below $1 of notional.

Depositing from Base (no bridge)

Send native USDC on Base (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) directly to the deposit wallet address. No further API call needed - it lands on-chain immediately.

Inbound deposits from another chain

For Ethereum, Arbitrum, Polygon, BSC, or Optimism, get a quote first. The response carries a signed transactionRequest your end user submits from their own wallet:
quote = requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers/quote",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "from": "external",
        "to": "deposit",
        "amount": "100",
        "source": {
            "address": "0xUserExternalWallet",
            "chain": "ethereum",
            "token": "USDC",
        },
    },
).json()
# Hand quote.inbound.approvalTarget + quote.inbound.transactionRequest
# to the partner UI for signing. Track via quote.inbound.explorerLinkTemplate.
Supported source chains: ethereum, polygon, bsc, arbitrum, optimism. Tokens: USDC, USDT (and USDC.e on Polygon).

Funding a venue

Once the deposit wallet has USDC, route it to the venue you want to trade on:
transfer = requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "from": "deposit",
        "to": "polymarket",
        "amount": "50",
        "clientReferenceId": "fund-poly-2026-05-19-001",
    },
).json()
print(f"{transfer['transferId']} - {transfer['status']}")
VenueTrading collateralChain
PolymarketpUSDPolygon
PredictUSDT (BEP-20)BSC
OpinionUSDT (BEP-20)BSC
LimitlessUSDC (native)Base
clientReferenceId makes retries safe - the second request with the same key returns the existing transfer instead of starting a duplicate. Most transfers complete synchronously. Cross-token routes (e.g. deposit → predict, which involves a USDC → USDT swap) can return status: "pending" - poll Get Transfer until terminal. If a transient on-chain step fails, the transfer enters status: "pending" with substatus: "recoveryInProgress". Funds are not lost - automated recovery retries the failing step. The transfer reaches completed or, after exhausted recovery, failed with substatus: "escalated" (contact support).

Hyperliquid

Bridge USDC to your Hyperliquid wallet using Across.
  1. Open the Across app and select Hyperliquid (HyperCore) as the destination chain.
  2. Enter your Hyperliquid wallet address (from venues.hyperliquid.address on Get Account) as the recipient.
  3. Bridge any amount of USDC from Arbitrum (or any supported source chain). The funds arrive in your trading balance in ~1-2 minutes as USDH (HL’s USDC-pegged stablecoin).
Send to the Hyperliquid wallet address from venues.hyperliquid.address - sending to the same EOA on a different chain will not credit your trading balance.

Verifying

balance = requests.get(
    f"{BASE}/api/accounts/{account_id}/balance",
    headers=HEADERS,
).json()
for b in balance["balances"]:
    print(f"{b['venue']}: available={b['available']}, locked={b['locked']}")
Pass ?aggregated=true to collapse all per-venue balances into a single USD-equivalent row.

Withdrawing

The withdrawal source is the deposit wallet. If a venue holds funds you want to withdraw, drain it first:
# Step 1: drain a venue back to the deposit wallet
requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"from": "polymarket", "to": "deposit", "amount": "50"},
)

# Step 2: withdraw to any supported chain
requests.post(
    f"{BASE}/api/accounts/{account_id}/transfers",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "from": "deposit",
        "to": "external",
        "amount": "50",
        "destination": {
            "address": "0xYourExternalAddress",
            "chain": "ethereum",
            "token": "USDC",
        },
        "clientReferenceId": "withdraw-2026-05-19-001",
    },
)
Supported destination.chain / destination.token pairs:
ChainTokens
ethereumUSDC, USDT
polygonUSDC, USDC.e, USDT
baseUSDC
bscUSDC, USDT
arbitrumUSDC, USDT
optimismUSDC, USDT
Cancel resting limit orders before draining a venue - those venues lock collateral against open buys. If the deposit wallet alone is short for the requested amount, the second call returns 400.

Hyperliquid withdrawals

Hyperliquid uses the per-venue POST /withdraw:
requests.post(
    f"{BASE}/api/accounts/{account_id}/withdraw",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "venue": "hyperliquid",
        "amount": "20.00",
        "destinationAddress": "0xYourExternalAddress",
        "chain": "arbitrum",
    },
)
Delivers USDC on Arbitrum. 10minimum,10 minimum**, **1 USDC fee deducted before delivery, settles in ~3-4 minutes.

Auditing transfers

List Transfers returns every fund movement on the account in one paginated list. Filter with ?status=pending|completed|failed, ?from=<wallet>, ?to=<wallet>, or ?direction=in|out|internal.

Next Steps

Placing Trades

Start trading with your funded wallet

Fees & Monetization

Set up partner fees to monetize your app