We rebuilt our Polymarket CLOB API starter from its own prompt: 3 of the top 20 order books had only one side A developer rebuilt a Polymarket CLOB API starter prompt and stress-tested it against the top 20 markets by 24-hour volume, finding that 3 of the 20 order books were one-sided and crashed the generated code with empty max()/min() errors on every cycle. The failing markets—a Dota 2 match, a CS2 match, and a Russia–Ukraine diplomacy market—were still active and accepting orders, with bids at 0.999 and no asks or asks at 0.001 and no bids. The revised prompt makes best_bid, best_ask, mid and spread return None when a side is empty instead of calling max()/min() on an empty list. Originally published on BotCookery https://botcookery.com/recipes/polymarket-clob-api-starter/ , free build recipes for AI-built trading and prediction-market bots. Written with AI assistance. Every output below is from real runs on public Polymarket data on Oct 25, 2026. The code holds no private key and can't place an order, and nothing here is financial advice. Our Polymarket CLOB API starter is a prompt. Paste it into your AI coding tool in an empty folder and you get a small Python toolkit for the international Polymarket order book: Gamma market lookups, the CLOB /book read the right way round, per-market fees, an offline walk-through of L1 and L2 auth, and a paper broker that fills against the live book. No wallet, no API key, no order code. On Oct 25 we tested it the only way that counts. We pasted the published prompt into a clean folder, let it build, and ran book on each of the top 20 markets by 24-hour volume, every ~50 seconds for about 6 minutes, plus a paper round trip and the auth demo. A lot of it held. The sorted book's mid matched both the SDK's PublicClient .get midpoint and raw /midpoint on all 5 markets we checked. The fee formula matched Polymarket's fee docs. The L1 typed data and L2 HMAC matched the SDK's own helpers on throwaway keys. The paper ledger rebuilt correctly across separate processes. Then a Sunday morning of esports, tennis and elections broke the rest of it. Here's what went wrong and how the prompt changed. International Polymarket splits its public API across three hosts. Gamma https://gamma-api.polymarket.com has markets and events: questions, slugs, and clobTokenIds , which are JSON-encoded strings you have to json.loads . The CLOB https://clob.polymarket.com has order books, midpoints and, for authenticated users, orders. The Data API https://data-api.polymarket.com has trades, positions and price history. Reads need no key. The classic gotcha is still there: raw /book lists bids ascending and asks descending, so the best price on each side is the last element. Our original prompt already said to sort. That part was fine. book crashed on 3 of the top 20 markets, every cycle The original prompt said "best bid = max bid price, best ask = min ask price". Simple enough, until a side is empty. Here's the harness log from the original build, 8 cycles over the top 20 markets: 10:12:07 UTC cycle 1: book ok 17, crashed 3: dota2-liquid-og-2026-10-25-game1 will-russia-and-ukraine-hold-any-diplomatic-meeting-by-october-31-2026 cs2-fut-tl1-2026-10-25 10:12:57 UTC cycle 2: book ok 17, crashed 3: dota2-liquid-og-2026-10-25-game1 will-russia-and-ukraine-hold-any-diplomatic-meeting-by-october-31-2026 cs2-fut-tl1-2026-10-25 ... 10:17:53 UTC cycle 8: book ok 17, crashed 3: dota2-liquid-og-2026-10-25-game1 will-russia-and-ukraine-hold-any-diplomatic-meeting-by-october-31-2026 cs2-fut-tl1-2026-10-25 Same three markets, every time: == dota2-liquid-og-2026-10-25-game1 0 rc=1 File ".../polymarket-clob-starter/cli.py", line 41, in