Developers

Automate your bets. Read markets and live odds, place bets with an API key, and follow everything as it happens on the event stream.

API keys

Basics

Base URL
https://api.cucumarket.xyz
Auth
Authorization: Bearer ck_… on bet and account endpoints. Market data and the stream are public.
Limits
120 requests and 30 bets per minute per key. Over the limit you get 429 with a Retry-After header.
Errors
JSON { error } with 400 bad input, 401 bad key, 404 not found, 409 bet refused (closed, not enough SOL, odds moved), 429 rate limited.

Endpoints

MethodPathKeyWhat it does
GET/v1/markets–Markets with live odds and their token's live numbers (market cap, curve %, dev bag, launchpad, and stock: the ticker a coin is themed on, or null). Filters: status=open|settled|all, kind=bond|peak|dev_dump, mint, limit (≤500).
GET/v1/markets/{id}–One market plus its most recent bets.
POST/v1/betskeyPlace a bet: {marketId, side, amount, clientId?, maxOdds?}. Amount is in SOL. side is yes or no.
GET/v1/betskeyYour bets. Filter with status=open|settled.
GET/v1/mekeyYour wallet, SOL balance and SOL riding on open markets.
GET/v1/stream–Server-Sent Events: listed, bonded, bet, resolved, mcap. Optional ?mint= filter.

Placing bets safely

  • clientId: your own id for the bet. Send the same clientId again (say after a timeout) and you get the original bet back withduplicate: true. It is never placed twice.
  • maxOdds: the most you'll pay for your side, from 0 to 1. If the market's odds for that side are above it when the bet arrives, it's refused with 409 and nothing is spent.
  • odds on every market: yes and no are the live prices, model is what the on-chain model alone says before bets pull it. Payouts are parimutuel: winners split the pool.

Examples

curl

# List open bonding markets
curl https://api.cucumarket.xyz/v1/markets?kind=bond

# Bet 0.25 SOL on YES, only if YES costs at most 60%
curl -X POST https://api.cucumarket.xyz/v1/bets \
  -H "Authorization: Bearer $CUCU_KEY" \
  -H "Content-Type: application/json" \
  -d '{"marketId": 123, "side": "yes", "amount": 0.25, "clientId": "run-42", "maxOdds": 0.6}'

A small bot (Node 18+)

// A tiny bot: back YES on bonding markets the curve model likes more than the crowd
const API = "https://api.cucumarket.xyz";
const KEY = process.env.CUCU_KEY;
const headers = { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" };

const markets = await fetch(`${API}/v1/markets?kind=bond`).then((r) => r.json());
for (const m of markets) {
  if (!m.odds || m.odds.model - m.odds.yes < 0.1) continue; // model sees 10%+ more upside
  const res = await fetch(`${API}/v1/bets`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      marketId: m.id,
      side: "yes",
      amount: 0.1, // SOL
      clientId: `edge-${m.id}`, // safe to retry: same clientId never bets twice
      maxOdds: m.odds.model, // skip if the price moved past our fair value
    }),
  });
  console.log(m.symbol, m.question, res.status, await res.json());
}

Live events

const events = new EventSource("https://api.cucumarket.xyz/v1/stream");
events.addEventListener("listed", (e) => console.log("new token", JSON.parse(e.data)));
events.addEventListener("bet", (e) => console.log("bet", JSON.parse(e.data)));
events.addEventListener("resolved", (e) => console.log("settled", JSON.parse(e.data)));