# Top Chicken — On-Network Data Guide (build your own)

You are reading the machine guide for building **third-party tools on Top
Chicken's public data**. Top Chicken is a *play-money* prediction market on
Bluesky's daily "Top Chicken" game, and its entire activity — every trade,
every settlement — is mirrored to the public AT Protocol. **All of it is
readable with no API key, no login, and no permission from us.** After reading
this you can build dashboards, position trackers, analytics, visualizations, or
bots over the live order flow.

This is the READ / BUILD guide. For the WRITE side — placing trades
programmatically — see the companion at `https://topchicken.cee.wtf/api/agent`.

**Two things to hold onto up front:**
- **No real money exists here.** Every balance is fake; there is no deposit and
  no cash-out. Nothing you compute is a financial position in anything real.
- **Trader identities ARE real Bluesky accounts.** The `trader` on every record
  is a real DID that resolves to a real handle. There's no pseudonymization —
  so treat the data with the respect you'd want for your own. It's a game.

Base URL: `https://topchicken.cee.wtf`

---

## 0. What you could build in an afternoon

- A live **trade tape** — every fill scrolling by ~1-2s after it happens.
- A **position + P&L tracker** for any account (or for everyone at once).
- A **whale watch** that pings when someone bets big or a price lurches.
- A market-wide **realized-P&L leaderboard**, rebuilt from raw records so it's
  independently verifiable against ours.
- **Historical exports** (CSV / Parquet) for backtesting the odds model.
- Odds-vs-outcome **calibration charts**, per-contender **flow heatmaps**,
  "smart money" follow bots, a Discord notifier… anything you can do with a
  public, real-time order feed keyed to real identities.

You do NOT need us for any of it. There are two independent surfaces.

---

## 1. Money units (read once, avoid all confusion)

All money is integer **subcents** (1/100 of a cent):

- `1 subcent = $0.0001`
- `10000 subcents = 1 dollar` = the payout of one winning share
- A share pays **10000 subcents ($1) if that contender wins the day, else 0**.
- New wallets start at **10,000,000 subcents ($1,000)**.

Every `*Subc` field below is in subcents. Divide by 10,000 for dollars.

---

## 2. The game in three sentences

Each UTC day, the `@topchicken` bot crowns the single most-liked eligible
Bluesky post and announces the winner the next morning (~13:00 UTC). A
**contender is a person** (keyed by Bluesky DID); a **share** in them pays $1 if
they win the day. Rounds are named by their UTC date (`"2026-07-13"`), are
tradable ("open") 06:00→06:00, then lock and settle on the announcement.

---

## SURFACE 1 — the JSON API (easiest)

Plain HTTP `GET`, no auth, CORS-open — point `fetch` straight at it. This is
the authoritative *current* state, and the fastest way to prototype.

- **`GET https://topchicken.cee.wtf/api/market`** — the live round + every contender with
  `did`, `handle`, `likes`, `p` (win-probability), `mid_subc`/`bid_subc`/
  `ask_subc`, `odds`. Also `forming` (tomorrow's field) and `finish` (the
  just-locked round still racing to its announcement), plus `season`.
- **`GET https://topchicken.cee.wtf/api/field/{round}`** — EVERY post's like trajectory on a
  **post-age** axis: `posts[]` with `{author_did, handle, created_at, likes,
  series: [[ageSeconds, likes]...], is_best}` and `race_end`. The data behind
  the Field overlay — ready-made for your own charts.
- **`GET https://topchicken.cee.wtf/api/chart/{round}/{did}`** — price + like history for one
  contender: `ticks` as `[ts, p_market, likes, velocity, p_model]`.
- **`GET https://topchicken.cee.wtf/api/holders/{round}/{did}`** — the current holder list for a
  contender (biggest first): `{count, total_shares, holders: [{did, handle,
  shares, avg_subc}]}`. This is the AUTHORITATIVE live position set (already
  net of refunds/voids — see the gaps in §6).
- **`GET https://topchicken.cee.wtf/api/volume/{round}/{did}`** — traded volume bucketed for a
  histogram: `bars: [[bucketTs, buyShares, sellShares]]`.
- **`GET https://topchicken.cee.wtf/api/book/{round}/{did}`** — the live order-book ladder
  (`bids`/`asks` rungs, `p_model` vs `p_mkt`, `skew`, `capped`).
- **`GET https://topchicken.cee.wtf/api/trader/{did}`** — any account's public profile: balance,
  positions, trades, net-worth series, trophies, best season. Keyed by DID.
- **`GET https://topchicken.cee.wtf/api/leaderboard`** — standings by P&L (net of injected money).
- **`GET https://topchicken.cee.wtf/api/results`** and **`/api/results/{round}`** — settled rounds
  and their winners.
- **`GET https://topchicken.cee.wtf/api/feed/global`** — the recent global trade tape (JSON).
- **`GET https://topchicken.cee.wtf/api/bulletins`** — site-wide notices (voids, season rollovers,
  commissioner rulings).
- **`GET https://topchicken.cee.wtf/api/scrap`** — the live/last "scrap" side-game race, if any.

If you just want *current* state, the API is all you need. Read on for the
decentralized, real-time, and historical-bulk paths.

---

## SURFACE 2 — the raw atproto records (decentralized, real-time, verifiable)

Every executed trade and every round outcome is written as a **public atproto
record**. You can read them without touching our servers at all — straight from
the PDS and the firehose. This is what makes an independent, tamper-evident
tracker possible.

### The house account

- Handle: **`topchicken.cee.wtf`**
- DID: **`did:plc:n3lv2b5ysipuq5pstwxhmyxa`**
- Its PDS can move, so resolve it first:

```bash
DID=did:plc:n3lv2b5ysipuq5pstwxhmyxa
PDS=$(curl -s https://plc.directory/$DID \
      | jq -r '.service[]|select(.id=="#atproto_pds").serviceEndpoint')
echo "$PDS"   # e.g. https://xxxx.host.bsky.network
```

### The three record types

**1. `wtf.cee.topchicken.execution`** — one per *fill*, in the HOUSE repo (rkey
`t<tradeId>`). Every human trade, whether placed on the website or via an order
record, lands here ~1-2s after it executes. Persona-bot fills are intentionally
NOT published.

```json
{
  "$type": "wtf.cee.topchicken.execution",
  "trader": "did:plc:...",          // the trader (a real Bluesky DID)
  "round": "2026-07-13",
  "contender": "did:plc:...",       // which bird
  "side": "buy",                    // "buy" | "sell"
  "shares": 2556,
  "priceSubc": 27,                  // per-share fill price
  "totalSubc": 69012,               // shares * priceSubc
  "source": "atproto",              // "web" | "atproto"
  "order": "at://did:plc:.../wtf.cee.topchicken.order/3m...",  // if via the lane
  "executedAt": "2026-07-13T16:24:13.593Z"
}
```

**2. `wtf.cee.topchicken.settlement`** — one per settled/void round, in the
HOUSE repo (rkey = round id).

```json
{
  "$type": "wtf.cee.topchicken.settlement",
  "round": "2026-07-12",
  "status": "settled",              // "settled" | "void"
  "winnerDid": "did:plc:...",
  "winnerHandle": "goose.art",
  "winnerLikes": 2720,
  "announceUri": "at://.../app.bsky.feed.post/...",  // @topchicken's call
  "settledAt": "2026-07-13T13:04:00Z"
}
```

**3. `wtf.cee.topchicken.order`** — the trade INSTRUCTIONS, in **each trader's
OWN repo** (not the house repo). Fields: `round`, `contender`, `side`,
`shares`, optional `priceSubc` (limit) / `capSubc` (slippage guard),
`createdAt`. Executions link back to these via their `order` field. To collect
them market-wide, subscribe to the collection on the firehose (below).

### Three ways to read them

**(a) `listRecords` — paginate a collection.** Great for backfills.

```bash
curl -s "$PDS/xrpc/com.atproto.repo.listRecords?repo=$DID\
&collection=wtf.cee.topchicken.execution&limit=100"
# → { records: [{uri, cid, value}], cursor }
# follow .cursor for the next page until it's absent.
```

**(b) `getRepo` — the whole ledger as one CAR file.** Fastest bulk export.

```bash
curl -s "$PDS/xrpc/com.atproto.sync.getRepo?did=$DID" -o house.car
# parse with @atproto/repo (JS) or any ipld-car reader; iterate the two
# wtf.cee.topchicken.* collections.
```

**(c) Jetstream — the live firehose.** Real-time, no polling.

```bash
# every execution, market-wide (only the house repo emits these):
websocat "wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=wtf.cee.topchicken.execution"

# every order, from every trader's repo:
websocat "wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=wtf.cee.topchicken.order"
```

Each frame is a commit; the record is at `commit.record`, the author at `did`,
the action at `commit.operation` (`create`/`delete`). Deletes of an order
cancel its unfilled remainder — executed fills stand.

---

## 6. Reconstructing state — what's exact, and the honest gaps

**Positions (exact, for active rounds).** Sum the execution stream:
`position(trader, round, contender) = Σ(buy.shares) − Σ(sell.shares)`. Shares
don't depend on cash, so this is exact from executions alone — with ONE caveat
below.

**Realized P&L / win history (exact).** Join executions to settlements: for a
settled round, each winning share (contender == `winnerDid`) pays 10,000
subcents; losing shares pay 0. Net a trader's cashflow as
`Σ(sell.totalSubc) − Σ(buy.totalSubc) + winningShares × 10000`.

**Now the gaps — be honest in anything you publish:**

- **Wallet balance / net worth is APPROXIMATE, not exact.** Two cash events are
  *not* mirrored on-network: the small **floor faucet** (a top-up if you're
  nearly broke) and voluntary **"new life" resets**. The **weekly season reset**
  (every wallet → $1,000 when Sunday's round settles, ~Mon 13:05 UTC) IS
  deterministic and public, so between resets `cash ≈ start + netCashflow` — but
  a faucet tap or a manual reset breaks the running total. Positions are
  unaffected; only cash is.
- **Refunds are NOT executions.** When a contender is removed mid-round (became
  ineligible), a round **voids**, or a season rollover refunds an overlap
  position, those positions close via internal ledger events that are *not*
  mirrored. So a position reconstructed purely from executions can **overstate**
  a holding after such an event, until the round settles. If you need it exact,
  cross-check `GET /api/holders/{round}/{did}` or `GET /api/trader/{did}` — those
  are already net of refunds.
- **Persona-bot trades are withheld** (`source` is never `"bot"` in the mirror).
  They're house furniture and off the leaderboard, so the on-network flow is
  human + atproto-lane only. That's usually what you want anyway.

Rule of thumb: **executions + settlements** give you an exact, verifiable *trade
tape and P&L*; for exact *live positions and balances*, trust `/api/holders` and
`/api/trader`, and use the records for history, real-time, and independent audit.

---

## 7. Recipes (copy-paste starters)

**Live tape → Discord/console.** Subscribe to the execution firehose (§5c);
for each frame, resolve `record.trader` to a handle
(`GET https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=<did>`,
cache it) and print `handle side shares @ priceSubc on contender`.

**One account's book.** `listRecords` the house `execution` collection (§5a),
keep records where `value.trader == <did>`, net shares per
`(round, contender)`. Cross-check against `GET /api/trader/<did>`.

**Market-wide realized P&L.** Pull all executions (CAR export, §5b) + all
settlements; compute each trader's netted cashflow (§6). Rank it. Compare to
`GET /api/leaderboard` to validate your pipeline.

**Odds calibration.** For each settled round, take each contender's `p` near
lock (from `GET /api/chart/{round}/{did}`) vs whether they won (settlements).
Bucket predicted-p and plot realized win-rate — is 30¢ really ~30%?

---

## 8. Be a good sport

It's play money and it's not that serious — but it's real people. Cache profile
lookups and don't hammer the PDS or `plc.directory` (public-good infra with rate
limits); prefer the CAR export for bulk and Jetstream for live instead of
tight polling loops. Publish aggregates freely; think twice before building
something whose only purpose is to single out and embarrass one player. Attribute
where it's kind to. Then go build something cool and show it off.

---

*Play money. No real value. Trader identities are real Bluesky accounts. Built
on Bluesky's daily Top Chicken game; settlement mirrors `@topchicken`'s
announcement. This guide is served live at `https://topchicken.cee.wtf/api/data` — hand the URL to
any agent.*
