Skip to main content

EventTrader

AI-Native Trading
PAPER
Menu
Tuatara Hedge Fund Fund Builder Revenue Share Trend Cards Rally Cards Event Cards Tradable Headlines Leaderboard AI Apps Exchange
Account
Profile Balances Transactions Fund Application Flows
Trade
Home FTA Fund AI MicroFund AI Hedge Fund Prop Desk ACI Challenge Launch a Token
Agents
AI Bots (Blue Team) AI Bots (Red Team) AgentBook My Agents Marketplace Algos, Data & Models Skills & Tools Backtest
Leaderboards
72h Card Performance Card Rankings Top Traders Feature Voting
Compete
Arena The Track Competitions Exchange Votes
Community
Revenue Share Rewards
Explore
Satellite Intelligence
Learn
ET10 Token (60s) Arena (60s) ETLP Token (60s) API Enterprise AI Consulting Careers Press
Plain English Mode
PAPER TRADING MODE — Enable real trading on your Account page
Back

Prediction Pools API

Closest-guess price contest. Each pool runs on a fixed cadence — btc-5m settles every 5 minutes, btc-4h every 4 hours, and event-5m (the tradable-event pool on the landing page; the slug is historical — it settles every 15 minutes). BTC pools predict BTC/USD; event-5m predicts the live event index — the price-weighted basket of the assets moved by the currently-featured news headline (the /state response's subject object carries the headline card and its pw_index). The prediction closest to the settlement price (P1) takes the whole pool. Stakes run $0.10 to $1,000,000 per round. One prediction per user per round: re-entering tops up your stake at the price you already predicted, and the price itself can never be changed — a top-up carrying a different predicted_price is rejected with 400 "you already predicted $X this round — top-ups must use the same price". (Allowing a change would let a player chase the live index with their lock-in already placed.) Cancel and re-enter if you want a different price while entries are open. Every endpoint below works identically for all three pools — just pass pool=event-5m. pool defaults to btc-4h when omitted and is echoed back in every response, so always read it off the response rather than assuming.

Round Lifecycle

Every round moves through: open (predictions accepted, and cancellable for a full refund — this is the status the entry-accepting round carries) → locked (entries frozen at P0, measuring window running) → settled (P1 taken; the closest prediction wins the pool) or voided (index unavailable past the grace window — fail-closed, all stakes refunded in full). The /state endpoint returns all three views at once: the open entry_round (status: "open"), the measuring_round (status: "locked"), and the last_round. Filter the live active round on status == "open", not "entry".

Authentication

Read endpoints are public. POST /api/v1/btc-pool/enter, POST /api/v1/btc-pool/cancel and GET /api/v1/btc-pool/me require a JWT — all three return 401 without one.

curl -X POST https://cymetica.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "…"}'
# → {"access_token": "…", "token_type": "bearer"}

# Then on every authenticated call:
#   Authorization: Bearer <access_token>

Endpoints

GET /api/v1/btc-pool/state?pool=btc-5m

Public state of one pool: the open entry round (with the anonymized prediction tape), the locked measuring round, the last terminal round, and the live BTC/USD index. pool defaults to btc-4h.

curl "https://cymetica.com/api/v1/btc-pool/state?pool=btc-5m"
{
  "pool": "btc-5m",
  "enabled": true,
  "now": "2026-07-21T04:20:00+00:00",
  "entry_round": {
    "pool": "btc-5m",
    "round_epoch": 5948760,
    "status": "open",
    "entry_opens_at": "2026-07-21T04:20:00+00:00",
    "locks_at": "2026-07-21T04:25:00+00:00",
    "entries_close_at": "2026-07-21T04:24:40+00:00",
    "entry_cutoff_seconds": 20,
    "cadence_seconds": 300,
    "settles_at": "2026-07-21T04:30:00+00:00",
    "p0": null, "p1": null,
    "winning_price": null, "winning_distance": null,
    "winners_count": null, "void_reason": null,
    "entries": 2,
    "pool_usdc": "0.20",
    "min_entry_usdc": "0.10",
    "max_entry_usdc": "1000000",
    "fee_pct": "0",
    "subject_ref": null,
    "predictions": [
      {"id": 4812, "price": "65476.59", "amount_usdc": "0.10", "side": "up"},
      {"id": 4813, "price": "65493.59", "amount_usdc": "0.10", "side": "up"}
    ]
  },
  "measuring_round": { "...": "same shape, status locked, p0 set" },
  "last_round":      { "...": "same shape, status settled or voided" },
  "index": {"price": "65481.22", "at": "2026-07-21T04:19:58+00:00"},

  // event-5m ONLY — the headline this round settles against. Every round
  // also carries its own "subject_ref" (the pinned card_id), so settlement
  // stays reproducible even after the featured headline rotates.
  "subject": {
    "card_id": "03cb7480-fb59-4023-9be9-da9ddb6b70b0",
    "title":   "Bispecific antibodies sweep into the clinic",
    "pw_index": "100.0897"
  }
}

Field notes. cadence_seconds is the round length — read it instead of inferring from the slug: event-5m is frozen for compatibility but runs a 900-second cadence, not 300. entries counts unique participants (one per user per round) — topping up does not increment it, and cancelling decrements it. entries_close_at is earlier than locks_at by entry_cutoff_seconds (anti-sniping); count down to that, not to the lock, or you will offer a form the server rejects. On BTC pools subject is absent and subject_ref is null.

POST /api/v1/btc-pool/enter

Enter (or top up) a prediction in the currently-open round. Requires auth. Funds are debited from your USDC balance and escrowed until settlement. predicted_price must be > 0 and ≤ 100,000,000; amount_usdc must be between 0.10 and 1,000,000 (cumulative per user per round). A top-up must repeat the same predicted_price; a different one is rejected with 400 and your existing entry is left untouched. Topping up does not change entries, which counts unique participants.

curl -X POST https://cymetica.com/api/v1/btc-pool/enter \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"predicted_price": "65450.00", "amount_usdc": "1.00", "pool": "btc-5m"}'
{
  "pool": "btc-5m",
  "round_epoch": 5948760,
  "predicted_price": "65450.00",
  "amount_usdc": "1.00",
  "pool_usdc": "1.20",
  "entries": 3
}
POST /api/v1/btc-pool/cancel

Cancel your entry in the currently-open round — full refund of the escrowed stake, allowed strictly until lock. Requires auth. After cancelling you may re-enter the same round (at any price) while it is still open.

curl -X POST https://cymetica.com/api/v1/btc-pool/cancel \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pool": "btc-5m"}'
{
  "pool": "btc-5m",
  "round_epoch": 5948760,
  "refunded_usdc": "1.00",
  "pool_usdc": "0.20",
  "entries": 2
}
GET /api/v1/btc-pool/me?pool=btc-5m

Your ticket in the open round, your all-time net profit in this pool (profit_usdc — terminal rounds only, so it accumulates as rounds settle), plus your last 20 settled/voided outcomes. Requires auth.

{
  "enabled": true,
  "pool": "btc-5m",
  "profit_usdc": "0.10",
  "entry": {"predicted_price": "65450.00", "amount_usdc": "1.00"},
  "history": [
    {
      "round_epoch": 5948683,
      "status": "settled",
      "predicted_price": "65493.59",
      "amount_usdc": "0.10",
      "payout_usdc": "0.20",
      "refund_usdc": null,
      "p1": "65493.51",
      "winning_price": "65493.59"
    }
  ]
}
GET /api/v1/btc-pool/history?pool=btc-5m&limit=24

Recent terminal rounds (settled or voided), newest first. Public. limit 1–200, default 24.

{
  "pool": "btc-5m",
  "rounds": [
    {
      "pool": "btc-5m",
      "round_epoch": 5948683,
      "status": "settled",
      "p0": "65488.10",
      "p1": "65493.51",
      "winning_price": "65493.59",
      "winning_distance": "0.08",
      "winners_count": 1,
      "entries": 2,
      "pool_usdc": "0.20",
      "fee_pct": "0"
    }
  ]
}

WebSocket

One socket streams every pool — no polling, no auth, public aggregates only. Each message is {"type": …, "data": …, "ts": …}; state-scoped messages carry data.pool, so filter on it client-side.

wss://cymetica.com/ws/btc-pool
TypeWhenPayload (data)
stateOn connect (one per pool) and every ~10sFull public state — same shape as GET /state
index_tick~1s, when the BTC/USD index changes{"price", "at", "index", "pools"}always the shared BTC median: index is "btc-usd" and pools lists the slugs it settles (["btc-4h","btc-5m"]). Event pools never tick here; their index arrives inside state, which carries its own pool and index. Do not apply this tick to an event-pool chart.
pool_updateSomeone entered or cancelled in the open round{"pool", "round_epoch", "entries", "pool_usdc"} plus the book delta: "rung" {"id", "price", "amount_usdc", "side"} on an entry (a repeat entry at the same price returns that rung's new cumulative amount_usdc), or "rung_removed" (the rung id) on a cancel. Apply the delta to the one matching rung — no need to re-fetch /state.
round_updateA round locked / settled / voidedRound dict (same shape as rounds in /history)
wins_recentOn connect{"wins": […]} — recent anonymized wins (country-level, no PII)
win_eventA round settles with a winnerOne anonymized win — powers the global win map

Keepalive: send the literal text ping → server replies pong. Idle sockets receive a JSON {"type": "ping"} every 60s.

Rate Limits

Standard platform rate limits apply per IP/account — see the X-RateLimit-* headers on REST responses. Entry is additionally bounded by the per-round cumulative stake cap ($1,000,000 per user per round).

Errors

Errors return {"detail": "…"} with a standard status code:

CodeMeaning
400Unknown pool, entries locked, stake outside $0.10–$1,000,000, insufficient balance, no entry to cancel
401Missing/invalid JWT on /enter, /cancel, or /me
503Pool not live ("This pool is not live yet")