Developers
Everything the site does, your code can do. Reads are public, orders are signed by your own wallet, and API keys cover the account endpoints.
Read the market
Markets, prices, books and the trade tape are public. No credential, no sign-up.
# The catalog. Public — no credential.
curl -s "https://api.predikon.com/markets?sort=most-active&limit=5" | jq '.markets[] | {id, title, quote, maker_yes_ppm}'
# One market's live state, its book and its recent prints.
curl -s "https://api.predikon.com/markets/btc-100k-2026"
curl -s "https://api.predikon.com/markets/btc-100k-2026/book"
curl -s "https://api.predikon.com/markets/btc-100k-2026/history?limit=100"Place an order
An order is a signature. The exchange recovers your address from the EIP-712 payload, so this endpoint needs your wallet key — not an API key — and nothing custodial happens in between. Testnet tokens — no cash value.
import { createWalletClient, http, type Address } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const API = "https://api.predikon.com";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// The exchange address and the collateral's decimals come from the venue itself.
const { exchange } = await (await fetch(`${API}/dex/config`)).json();
const order = {
trader: account.address as Address,
market: "0x…" as Address, // the market's on-chain address
outcome: 1, // 1 = YES, 0 = NO (contract convention)
shareAmount: 10_000_000n, // 10 shares, 6 decimals
collateralAmount: 6_200_000n, // $6.20 — your limit price for them
isBuy: true,
expiry: 0n, // 0 = good till cancelled
signedAt: BigInt(Math.floor(Date.now() / 1000)),
nonce: 0n,
salt: `0x${crypto.randomUUID().replaceAll("-", "").padEnd(64, "0")}` as `0x${string}`,
maxFeeBps: 200, // the contract's ceiling is 2%
};
// The ORDER is the credential: the exchange recovers the signer from this signature.
const signature = await createWalletClient({ account, transport: http() }).signTypedData({
domain: { name: "PredikonExchange", version: "1", chainId: 64327, verifyingContract: exchange },
types: {
Order: [
{ name: "trader", type: "address" },
{ name: "market", type: "address" },
{ name: "outcome", type: "uint8" },
{ name: "shareAmount", type: "uint256" },
{ name: "collateralAmount", type: "uint256" },
{ name: "isBuy", type: "bool" },
{ name: "expiry", type: "uint64" },
{ name: "signedAt", type: "uint64" },
{ name: "nonce", type: "uint64" },
{ name: "salt", type: "bytes32" },
{ name: "maxFeeBps", type: "uint16" },
],
},
primaryType: "Order",
message: order,
});
const res = await fetch(`${API}/dex/orders`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
order: { ...order, shareAmount: order.shareAmount.toString(),
collateralAmount: order.collateralAmount.toString(),
expiry: Number(order.expiry), signedAt: Number(order.signedAt),
nonce: Number(order.nonce) },
signature,
tif: "GTC",
}),
});
console.log(await res.json()); // { orderId, fills, prints }Use your account from code
The account-scoped endpoints take an API key in X-API-Key.
# An API key authenticates the ACCOUNT-scoped endpoints.
curl -s "https://api.predikon.com/me/watchlist" -H "X-API-Key: $PREDIKON_API_KEY"
# Watch a market: the id is in the path and the call carries no body.
curl -s -X PUT "https://api.predikon.com/me/watchlist/btc-100k-2026" -H "X-API-Key: $PREDIKON_API_KEY"Rate limits
- Standard120 req/min
- Pro600 req/min
Per key, per minute. Public reads are limited per IP. A limited request answers 429 — back off and retry rather than reissuing the key.
Live prices
GET /markets/{id}/stream is server-sent events: price ticks and trades as they happen, no polling.

