Build with AI agents
Coding agents can build on VPX without you reading a line of these docs. Give one the CLAUDE.md below, or just a link to it, and it knows how VPX works and every endpoint. It can even get its own API key: it asks, you press Approve.
Connect your agent
Paste this into Claude Code, Codex, Cursor or any agent that can run commands. It gets a key with your approval, saves it to .env and checks it works.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then set me up with the VPX API: if VPX_API_KEY isn't in .env, get a key with the key request flow (open the approval page for me and wait for my approval), save it to .env as VPX_API_KEY (make sure .env is gitignored), and show me my balance and open positions.How an agent gets a key
The agent calls POST /keys/request and gets a link and a code. You open the link, sign in, check the code matches and press Approve. The agent's next call to POST /keys/claim gets the key, once. No key ever passes through a chat window. You can see and revoke every key on your Developer page.
curl -s -X POST https://www.vancouverpx.ca/api/v1/keys/request \
-H "Content-Type: application/json" -d '{"name": "Claude Code"}'
# → { "code": "K7QM-2XRP", "url": "…/developer/approve?code=K7QM-2XRP", "token": "…", … }
curl -s -X POST https://www.vancouverpx.ca/api/v1/keys/claim \
-H "Content-Type: application/json" -d '{"token": "<token>"}'
# → { "status": "pending" } … then { "status": "approved", "key": "vpx_live_…" }CLAUDE.md
Everything an agent needs about VPX and its API, in one file. Save it as CLAUDE.md (Claude Code) or AGENTS.md (Codex, Cursor and others) in your project, or point the agent at https://www.vancouverpx.ca/docs/api/claude.md. It's written from the API's own definitions, so it is always current. The full reference, every field of every endpoint, is in llms-full.txt.
# VPX: the Vancouver Prediction Exchange
You're building on VPX (https://www.vancouverpx.ca), a Canadian prediction exchange: people trade YES/NO shares on real-world events through a limit order book. Trading uses play money (T$). Every account starts with T$10,000, written 1,000,000 because the API counts cents. VPX is not a licensed or regulated exchange.
## The API
- Base URL: `https://www.vancouverpx.ca/api/v1`. JSON over HTTPS. Index of every endpoint: `GET https://www.vancouverpx.ca/api/v1`.
- Full reference: https://www.vancouverpx.ca/llms-full.txt (markdown). OpenAPI 3.1: https://www.vancouverpx.ca/docs/api/openapi.json. Human docs: https://www.vancouverpx.ca/docs/api.
- **Market data is public**: no key needed. **Your account and trading need a key**: `Authorization: Bearer $VPX_API_KEY`.
- Wherever the API takes a market id, the market's `slug` works too.
- Errors are `{"error": "...", "code": "..."}`. Branch on `code` (`INSUFFICIENT_FUNDS`, `MARKET_CLOSED`, …), never on the wording.
- Lists page with `limit` and `cursor`: pass `nextCursor` back as `cursor` until it is `null`.
- A parameter an endpoint doesn't take is refused (400, naming the ones it does), never ignored.
- There are no websockets. Poll, at most a few requests a second, and back off when you get a 429 or a 5xx.
- The market, account and trading endpoints are also MCP tools at https://www.vancouverpx.ca/api/mcp (Streamable HTTP, same key header).
## Getting an API key
Read the key from the environment (`VPX_API_KEY`). Never print it, log it or commit it: keep it in a gitignored `.env`. If there is no key, get one yourself. Your person only has to press Approve:
```bash
curl -s -X POST https://www.vancouverpx.ca/api/v1/keys/request -H "Content-Type: application/json" -d '{"name": "Claude Code"}'
```
The answer has a `url`, a `code` and a secret `token`. Open the `url` for your person (or show it), tell them the `code` to check, and ask them to sign in and press Approve. Meanwhile, every 3 seconds:
```bash
curl -s -X POST https://www.vancouverpx.ca/api/v1/keys/claim -H "Content-Type: application/json" -d '{"token": "<token>"}'
```
The answer is `pending` until they approve, then `approved` with `key`, once. Save it to `.env` as `VPX_API_KEY` straight away. Requests expire after 10 minutes. People can also make and revoke keys themselves at https://www.vancouverpx.ca/developer, and a key you no longer need can revoke itself: `DELETE /keys/current`.
## How VPX works
- **Markets.** Each market asks a YES/NO question. Its `status` goes OPEN → CLOSED → RESOLVED, or CANCELED. Only OPEN markets trade. A market can stay OPEN for up to 6 hours after `closesAt` before VPX closes it, so stop trading at `closesAt` yourself.
- **Prices and money are integer cents.** Prices run 1–99, and cash, `volume` and payouts are cents too. A YES and a NO share always pay 100¢ together, so buying NO at 40¢ is the same as selling YES at 60¢. Each market has one book, shown in YES terms: `bestBid`, `bestAsk`, `lastPrice`, `book` and the trade tape (`yesPrice`) are all YES prices. The NO price is 100 − YES.
- **Orders** are priced in their own outcome's cents. A LIMIT order rests until it fills or you cancel it. A MARKET order fills what it can now and cancels the rest. Buying locks `price × quantity` cents; selling locks the shares. There is no shorting: to bet against YES, buy NO. VPX charges no fees, and has no self-trade prevention.
- **Executions** come in three kinds. A `trade` is a buyer and a seller of the same outcome. A `marriage` is a YES buyer and a NO buyer whose prices add up to 100, creating a new pair of shares. A `divorce` is a YES seller and a NO seller handing a pair back for 100.
- **Positions.** `quantity` counts every share you hold, including the `lockedQuantity` that your open sell orders hold.
- **Resolution.** A winning share pays 100¢ and a losing one 0, automatically. See `GET /settlements`. Resolved shares stay in `/positions` with their `payout`.
- **Groups.** A question with several answers ("Who wins Vancouver-Quilchena?") has one market per answer. In a `negRisk` group exactly one answer wins, so the YES prices add up to about 100 and the books share liquidity (`implied` on the order book).
- **Unlisted** markets (`listed: false`) are left off the website's lists but trade like any other, and the API lists them with the rest. **Private** markets are for invited friends; each one gives its members a separate wallet of play money (`wallets` on `GET /account`).
- **VPX Bots** (https://www.vancouverpx.ca/bots) trade through this same API. A bot's orders and fills appear in yours, marked with its `botId`.
## Endpoints
| Method | Path | Key | What |
| --- | --- | --- | --- |
| GET | `/api/v1/markets` | — | Markets with their prices, newest first |
| GET | `/api/v1/markets/{marketId}` | — | One market by id or slug |
| GET | `/api/v1/markets/{marketId}/book` | — | Bids and offers, in YES terms |
| GET | `/api/v1/markets/{marketId}/history` | — | The market's price chart, oldest first |
| GET | `/api/v1/trades` | — | Executions on VPX, newest first |
| GET | `/api/v1/groups` | — | Questions with several answers, newest first |
| GET | `/api/v1/groups/{groupId}` | — | One group, with every market in it |
| GET | `/api/v1` | — | Every endpoint, and who you are signed in as |
| GET | `/api/v1/account` | key | Who you are and your cash |
| GET | `/api/v1/positions` | key | The shares you hold, with their prices |
| GET | `/api/v1/orders` | key | Your open orders, or your order history |
| GET | `/api/v1/orders/{orderId}` | key | One of your orders, with its fills |
| GET | `/api/v1/fills` | key | Every execution of your orders, newest first |
| GET | `/api/v1/settlements` | key | What resolved markets paid you, newest first |
| GET | `/api/v1/account/history` | key | Your main wallet's value, day by day |
| POST | `/api/v1/orders` | key | Buy or sell YES or NO shares |
| DELETE | `/api/v1/orders/{orderId}` | key | Take one of your orders off the book |
| DELETE | `/api/v1/orders` | key | Cancel the orders you name, a market's, or all of them |
| POST | `/api/v1/markets/{marketId}/split` | key | Pay 100¢ for one YES and one NO share |
| POST | `/api/v1/markets/{marketId}/redeem` | key | Hand back YES+NO pairs for 100¢ each |
| POST | `/api/v1/keys/request` | — | How an agent gets a key: its person approves it on the website |
| POST | `/api/v1/keys/claim` | — | Poll until your person approves; then you get the key, once |
| DELETE | `/api/v1/keys/current` | key | Stop the key you're calling with working, at once |
## Recipes
- **Every open book in one call**: `GET /markets?status=OPEN&include=book`.
- **Follow the tape**: call `GET /trades?since=<a few seconds before the previous answer's now>` and drop ids you've already seen: an execution can be written a moment after the time it carries, and the overlap catches it.
- **Your money adds up**: a wallet's `funded` + Σ fills (−price × quantity on a BUY, + on a SELL) + Σ settlement `payout` = its `balance`. Its value is `balance` + Σ positions × `bid`, and its profit is value − `funded`. Splits and redeems (YES+NO pairs for 100¢) leave no fill, so they are the only gap.
- **Quote safely**: keep your order ids, re-quote only when the price moves, and when you stop, cancel what you placed: `DELETE /orders` with `{"ids": [...]}` in the body. `{"marketId": ...}` or `{"all": true}` would cancel every open order in that market or the account, the person's own and their VPX bots' included. If a request times out, check `GET /orders` before you send it again.
- **Prices from elsewhere**: `venues` gives a market's Polymarket slug and Kalshi ticker, if VPX matched it (Polymarket quotes 0–1 and Kalshi dollars; VPX quotes cents).
This file is written from the API itself, so it is always current: https://www.vancouverpx.ca/docs/api/claude.md
Prompts
Each one starts by pointing the agent at the CLAUDE.md, so it works in a fresh project.
Market data collector
Every book and every trade, into SQLite, restartable.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then build a VPX market data collector in Python (standard library plus requests): every 60 seconds, save a snapshot of every open market and its order book (one call: GET /markets?status=OPEN&include=book) to SQLite, and follow the trade tape with GET /trades, asking each time for trades since a few seconds before the previous answer's `now` and skipping trade ids already stored. Use tables for markets, book snapshots (one row per price level) and trades. It must survive restarts without gaps or duplicates and back off on errors. No API key needed. Add a README with how to run it and example SQL queries (spread over time, volume by market).Rebuild your PnL
Your profit from first principles, reconciled to the cent.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then rebuild my VPX PnL from scratch with my API key. Page through all my fills (GET /fills) and settlements (GET /settlements). Starting from each wallet's `funded` (GET /account), replay them in time order to get each wallet's cash, and each market's position, average cost, realized PnL and settlement payout. Mark open positions at their `bid` from GET /positions for unrealized PnL. Reconcile with GET /account (cash) and GET /positions (quantities), and explain any difference: splits and redeems leave no fills. Print a per-market table, totals, and a daily equity curve that you compare with GET /account/history.Simple market maker
Two-sided quotes with inventory limits that clean up after themselves.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then write a small market maker for one VPX market, chosen by slug. Each cycle it reads the order book, quotes a YES bid and a YES offer (as a BUY of NO at 100 − price, unless it holds YES to sell) around the mid, with a configurable spread and size. It only re-quotes when its price would move by 1¢ or more, and it stops adding to a side once its position reaches a limit. It handles errors by `code`, polls at most once every 2 seconds, and when it exits, crashes or gets Ctrl-C it cancels the orders it placed (DELETE /orders with their ids in the body), and only those: never everything in the market, which would cancel my own orders and my VPX bots' too. Make dry-run the default: print the orders it would place until I pass --live.Cross-venue monitor
Where VPX's prices stray from Polymarket's and Kalshi's.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then build a monitor that lists every open VPX market with `venues` set, fetches the same market's prices from Polymarket (Gamma API, by slug) and Kalshi (public market endpoint, by ticker), converts everything to YES cents, and prints a live table of VPX bid/ask against the other venues' bid/ask. Flag rows where VPX is more than 5¢ off the tighter outside market. Refresh every 30 seconds and say which source is stale.Position alerts
Hear about it when your markets move or resolve.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then write a script that watches my VPX positions (GET /positions) and alerts me with a desktop notification when a market I hold moves 5¢ or more since the last alert, when one of my orders fills (GET /fills), and when a market I hold resolves (GET /settlements), including what it paid. Poll every minute and remember what it has already alerted about.Portfolio dashboard
One HTML file showing your positions, PnL, orders and fills.
Read https://www.vancouverpx.ca/docs/api/claude.md first: it explains VPX and its API. Then make a single-file HTML dashboard for my VPX account that calls the API from the browser (it allows any origin). It asks for my API key once and keeps it in localStorage. It shows cash, open positions with their value and unrealized PnL at the bid, open orders with a cancel button, my latest fills, and a chart of GET /account/history. Refresh every 15 seconds. Make it clean and minimal.MCP server
Every market, account and trading endpoint is also a tool on VPX's MCP server, so an agent can read markets and trade without writing code. It runs at https://www.vancouverpx.ca/api/mcp (Streamable HTTP) and takes the same key. Market data tools work without one.
claude mcp add --transport http vpx https://www.vancouverpx.ca/api/mcp --header "Authorization: Bearer $VPX_API_KEY"{
"mcpServers": {
"vpx": {
"url": "https://www.vancouverpx.ca/api/mcp",
"headers": {
"Authorization": "Bearer YOUR_VPX_API_KEY"
}
}
}
}| Tool | What it does |
|---|---|
get_markets | Markets with their prices, newest first |
get_market | One market by id or slug |
get_order_book | Bids and offers, in YES terms |
get_price_history | The market's price chart, oldest first |
get_trades | Executions on VPX, newest first |
get_groups | Questions with several answers, newest first |
get_group | One group, with every market in it |
get_account | Who you are and your cash · key |
get_positions | The shares you hold, with their prices · key |
get_orders | Your open orders, or your order history · key |
get_order | One of your orders, with its fills · key |
get_fills | Every execution of your orders, newest first · key |
get_settlements | What resolved markets paid you, newest first · key |
get_account_history | Your main wallet's value, day by day · key |
place_order | Buy or sell YES or NO shares · key |
cancel_order | Take one of your orders off the book · key |
cancel_all_orders | Cancel the orders you name, a market's, or all of them · key |
split_shares | Pay 100¢ for one YES and one NO share · key |
redeem_shares | Hand back YES+NO pairs for 100¢ each · key |
Want a bot VPX runs for you instead? VPX Bots builds and hosts one from a chat, and trades through this same API.