Skip to main content
The CSBoard API is designed for automation. Every endpoint is deterministic, cursor-paginated, and rate-limit-aware, which makes it straightforward to build price monitors, sniping bots, arbitrage tools, and full market data pipelines. This guide covers the key patterns you need to build reliable automated systems.

AI agent integration

If you are building an AI agent or LLM-powered tool, the fastest way to give it access to the full API surface is via the machine-readable spec at /llms.txt. That file contains the complete API in a single, compact document — no parsing required. For agents that support the Model Context Protocol (MCP), add the CSBoard server to your MCP config:
Once connected, the agent can call any CSBoard endpoint as a tool — browsing listings, checking prices, and placing orders — without you writing any glue code.

Tracking order state

Do not poll for it. Register a webhook and we POST the order to you the moment its state changes — the same object GET /v1/orders/:id returns, HMAC-signed, retried for 24 hours if your endpoint is down. A withdrawal flow that has to react to delivered, hold or returned is the case push exists for: polling every open order is a cost that grows with your order book rather than with the number of things that actually happened. Keep a periodic GET /v1/orders sweep as a reconciliation backstop, not as your primary signal.

Polling for new listings

To detect new listings as they appear without re-scanning the entire catalog, use sort=newest combined with cursor pagination. On each poll cycle, walk pages until you reach a listing ID you have already seen, then stop.
Seed SEEN_IDS on startup by running one full poll without acting on the results. That way, you only trigger actions on listings that appear after your bot starts — not on everything that was already live.

Price monitoring bot

Poll GET /v1/prices on a schedule, compare each item’s min_price_usd against your target threshold, and trigger an alert or automated buy when the price drops below it.
min_price_usd from /v1/prices is an indicative grouped snapshot — it can lag the live per-item price. Always fetch the specific listing from /v1/listings and use its price_usd as the authoritative price before placing an order.

Safe buying automation

Automated buying requires more defensive coding than manual purchasing. Follow these four rules unconditionally. 1. Always send max_price_usd Your ceiling is enforced atomically inside the balance debit. Without it, a price spike between your listing fetch and your order execution can result in an unexpected charge. Set max_price_usd to the price_usd you observed, plus a small buffer if you are willing to absorb minor slippage:
2. Always use an Idempotency-Key Generate one UUID v4 per order attempt. If your request times out or returns a network error, retry with the same key — the server replays the original result instead of executing a second purchase.
3. Handle 429 with Retry-After Rate-limited responses include a Retry-After header (seconds). Always read that value and sleep for exactly that duration — do not use a fixed backoff, as it may be shorter or longer than required. 4. Handle 409 price_moved gracefully A 409 price_moved means the price moved past your ceiling — nothing was charged. Decide whether to re-fetch the listing, update max_price_usd, and retry, or abandon the opportunity:

Bulk data pipeline

For comparison sites, analytics dashboards, or any system that needs the full catalog, use the snapshot endpoint instead of paginating through /v1/prices.
Use ETags to avoid re-downloading an unchanged snapshot. Store the ETag header value from each 200 response and send it back as If-None-Match on the next request. A 304 Not Modified response means your local copy is still current.
The snapshot endpoint is rate-limited to 1 request per minute. Structure your pipeline to use it as a base layer refreshed every few minutes, and overlay real-time updates from /v1/prices for items you are actively monitoring.

Best practices checklist

Before going to production, verify all of the following:
  • ✅ You send max_price_usd on every POST /v1/orders call
  • ✅ You generate a fresh UUID v4 Idempotency-Key for every order attempt
  • ✅ Your retry logic reuses the same Idempotency-Key on network-error retries
  • ✅ Your 429 handler reads and sleeps for Retry-After, not a hardcoded value
  • ✅ Your 409 price_moved handler decides explicitly whether to retry or abort
  • ✅ You read price_usd from /v1/listings (not /v1/prices) before placing an order
  • ✅ You use ETags with the snapshot endpoint to avoid redundant downloads
  • ✅ Your API key has trading enabled only if your bot is intended to buy
  • ✅ Order state comes from a webhook (or the SSE stream), with polling kept as a reconciliation sweep
  • ✅ Your webhook handler verifies the signature against the raw body and ACKs within 10s
  • ✅ Your webhook handler dedupes on the event id and ignores events older than what you have stored