OllinDocs
API reference

Overview & conventions

ollin-study-api — a stateless, read-only Fastify service serving pre-extracted solver artifacts.

ollin-study-api serves pre-extracted solver artifacts from GCS (or local fixtures). It computes nothing, stores nothing, and never links solver code — see the AGPL boundary.

  • Base path: /v1. All endpoints are GET.
  • Postflop responses are NodeDocument v1; preflop responses are Preflop Pack v1 slices.
  • Endpoint shapes are stable across serving tiers — only coverage grows.

Endpoints at a glance

RouteReturns
/v1/healthLiveness + campaign/stamp/tier/mode. Never cached.
/v1/familiesThe postflop family catalog.
/v1/families/:famFamily detail: config, preflop ranges, board index.
/v1/families/:fam/boards/:flopNodeDocument v1 for the flop root.
/v1/families/:fam/boards/:flop/node?path=…Typed 501 today — the tree/live contract slot.
/v1/preflopPreflop catalog: depths + settings.
/v1/preflop/:depthRoot node + full tree index for a depth.
/v1/preflop/:depth/node?path=…One preflop node document.
/v1/preflop/:depth/boundariesThe HU preflop→postflop bridge with coverage marks.

Health

GET /v1/health → 200 (cache-control: no-store)
{
  "status": "ok",
  "service": "ollin-study-api",
  "campaign": "berserk_v1",
  "stamp": "20260721T131354Z",
  "tier": "v0-roots",
  "mode": "gcs",
  "uptime_s": 14524
}

mode tells you whether the process reads fixtures (local) or the serving bucket (gcs) — the first thing to check when responses look wrong.

Error envelope

Every non-2xx body has one shape:

GET /v1/families/nope → 404
{
  "error": {
    "code": "FAMILY_NOT_FOUND",
    "message": "Unknown family \"nope\"",
    "details": {
      "known_families": [
        "100bb_3bet_call_p7v5_n13380",
        "100bb_4bet_call_p7v5_n13443"
      ]
    }
  }
}
CodeStatusWhen
FAMILY_NOT_FOUND404Unknown family id (details list known ids).
BOARD_NOT_FOUND404Board not in the family.
BAD_BOARD_ID400Unparseable board id.
TIER_NOT_AVAILABLE501The tree/live contract slot — see below.
NOT_FOUND404No such route.
PACK_INTEGRITY502A pack failed its sha256 verification.
GCS_READ_FAILED502GCS object read failed (auth expiry shows up here — see the runbook).
DATA_NOT_PUBLISHED503No manifest/packs at the configured prefix.
INTERNAL500Unexpected error.
BAD_DEPTH400Preflop depth not "30" / "30bb"-shaped.
DEPTH_NOT_FOUND404No preflop pack for that depth (details list available depths).
NODE_NOT_FOUND404No preflop node at that path.

Errors are sent with cache-control: no-store — they never stick in caches.

Input normalization

  • Board idsaskh2d, KH-2d-aSAsKh2d: rank-descending, suit s>h>d>c tie-break, rank uppercase / suit lowercase.
  • Depths30 or 30bb (case-insensitive).

On this page