> ## Documentation Index
> Fetch the complete documentation index at: https://docs.calibri.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List events

> The catalogue of events, each with its child markets.

A generated or sub-daily series is COLLAPSED to a single entry — a
five-minute feed publishes 288 events a day and must not fill the feed.
Pass `series` to drill into one and get its individual windows; that is
the only way to see them.



## OpenAPI

````yaml /api-reference/openapi/calibri.yaml get /api/v2/pythia/public/events
openapi: 3.1.0
info:
  title: Calibri API
  version: 1.0.0
  description: >-
    The Calibri API. Discover markets, read live books, place signed orders, and
    manage positions and account data.

    Routed by path prefix to the service that answers it — which is an
    implementation detail, not something a caller has to reason about.
servers:
  - description: Production
    url: https://calibri.io
security: []
tags:
  - name: Health
    description: Service liveness.
    x-displayName: Health
  - name: Events
    description: Discover events and their metadata.
    x-displayName: Events
  - name: Markets
    description: List markets and load market detail for trading.
    x-displayName: Markets
  - name: Series
    description: Recurring event series.
    x-displayName: Series
  - name: Tags
    description: Editorial shelves used to browse the catalogue.
    x-displayName: Tags
  - name: Market Data
    description: Order book, depth, trade tape, tickers, and candles.
    x-displayName: Market Data
  - name: Assets
    description: Underlying asset price history for price-feed markets.
    x-displayName: Assets
  - name: Community
    description: Leaderboard and platform activity.
    x-displayName: Community
  - name: Currencies
    description: Currency registry.
    x-displayName: Currencies
  - name: Trade
    description: Place, list, and cancel orders.
    x-displayName: Trade
  - name: Positions
    description: Your matched contracts.
    x-displayName: Positions
  - name: Wallet
    description: Self-custody Safe, passkey, session keys, and relay.
    x-displayName: Wallet
  - name: Rewards
    description: Maker rebates and referral earnings.
    x-displayName: Rewards
  - name: Account
    description: Balances, ledger, PnL, limits, preferences, and profile.
    x-displayName: Account
  - name: Categories
    description: Categories
    x-displayName: Categories
  - name: Other
    description: Other
    x-displayName: Other
externalDocs:
  description: ''
  url: ''
paths:
  /api/v2/pythia/public/events:
    get:
      tags:
        - Events
      summary: List events
      description: |-
        The catalogue of events, each with its child markets.

        A generated or sub-daily series is COLLAPSED to a single entry — a
        five-minute feed publishes 288 events a day and must not fill the feed.
        Pass `series` to drill into one and get its individual windows; that is
        the only way to see them.
      parameters:
        - description: Filter by category
          in: query
          name: category
          schema:
            type: string
        - description: Filter by status. `resolved` covers determined and settled
          in: query
          name: status
          schema:
            type: string
        - description: Filter to one tag slug
          in: query
          name: tag
          schema:
            type: string
        - description: Filter to one series slug. Expands it rather than collapsing
          in: query
          name: series
          schema:
            type: string
        - description: Filter to one sub-category slug, e.g. tennis
          in: query
          name: subcategory
          schema:
            type: string
        - description: Filter by series cadence, e.g. daily / weekly / monthly
          in: query
          name: frequency
          schema:
            type: string
        - description: Sort order, e.g. newest
          in: query
          name: sort
          schema:
            type: string
        - description: Reverse the sort
          in: query
          name: reverse
          schema:
            type: boolean
        - description: Order of markets[] within each event
          in: query
          name: market_sort
          schema:
            type: string
        - description: Page size, applied after collapsing
          in: query
          name: limit
          schema:
            type: integer
        - description: >-
            `slim` reduces each event and market to the card fields (see
            api.SlimEvent); anything else returns the full object
          in: query
          name: fields
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Event'
                type: array
          description: OK
      security: []
components:
  schemas:
    Event:
      properties:
        category:
          example: crypto
          type: string
        created_at:
          description: >-
            CreatedAt (RFC3339, from events.created_at) backs the "newest" list
            sort.

            Before it was surfaced, "newest" fell back to id DESC.
          example: '2026-08-07T10:00:00Z'
          type: string
        description:
          example: >-
            Resolves from the final Coinbase BTC-USD trade price before the
            close date.
          type: string
        display_type:
          description: >-
            DisplayType (events.display_type) picks the chart SOURCE, not the
            market

            shape: "probability" (default) plots the markets' own YES
            probability,

            "price_feed" plots an underlying feed with a reference line.
          example: probability
          type: string
        effective_taker_fee_rate_bps:
          description: >-
            EffectiveTakerFeeRateBps is the resolved fee rate the matching
            engine

            will charge for trades in any of this event's markets. Computed at

            load time as: COALESCE(override, category default). NULL/nil means

            UNRESOLVED — no override and no fee_categories row for the category
            —

            which order placement rejects (distinct from a resolved 0 = free).

            Read-only — not persisted as its own column.
          example: 200
          type: integer
        featured:
          example: false
          type: boolean
        id:
          example: 12345
          type: integer
        image_url:
          example: https://cdn.calibri.io/events/btc-70k.png
          type: string
        markets:
          items:
            $ref: '#/components/schemas/MarketMeta'
          type: array
          uniqueItems: false
        outcome_structure:
          description: >-
            OutcomeStructure (events.outcome_structure) says how this event's
            markets

            relate to one another. It selects the frontend layout and is
            deliberately

            NOT derivable from len(Markets) — a contender race, a strike ladder
            and a

            fixture's derivative bundle can all carry a dozen markets and none
            of them

            renders like the others.

              independent — one question, or several unrelated ones (the default)
              one_winner  — at most one market resolves YES; ranked, sums to ~100%
              ladder      — nested thresholds over one variable ("above $100k",
                            "above $110k"). Several legs resolve YES together so it is
                            not one_winner, but the legs are nested so it is not
                            independent either: prices fall monotonically down the
                            ladder, ordered by markets.event_rank.

            Kalshi carries the same three as MECNET / DIRECNET / none.


            Display + validation only. Neither Kalshi's collateral netting nor

            Polymarket's NegRiskAdapter is implemented on our side.
          example: independent
          type: string
        price_feed:
          description: >-
            PriceFeed (events.price_feed) carries {source, symbol,
            reference_price}

            for the price_feed layout. Passed through opaquely — pythia never

            interprets it. nil when unset.
          items:
            type: integer
          type: array
          uniqueItems: false
        series:
          $ref: '#/components/schemas/SeriesRef'
        slug:
          example: btc-above-70k-december-2026
          type: string
        status:
          example: active
          type: string
        subcategory:
          $ref: '#/components/schemas/CategoryRef'
        tags:
          description: >-
            Tags are the editorial SHELVES this event sits on — what puts it on
            a hub

            page. Many-to-many and deliberately not taxonomic: "Wimbledon"
            collects the

            men's winner race, the women's winner race and every match, which
            share no

            series and no outcome structure. Always present (possibly empty) so
            the

            frontend need not nil-check.
          items:
            $ref: '#/components/schemas/TagRef'
          type: array
          uniqueItems: false
        taker_fee_rate_bps_override:
          description: >-
            TakerFeeRateBpsOverride mirrors events.taker_fee_rate_bps_override

            (NULL = inherit from category default, or global default if no
            category row).

            Persisted to the DB; included in JSON for admin consumers.
          example: 200
          type: integer
        title:
          example: Will BTC close above $70,000 on 31 Dec 2026?
          type: string
      type: object
    MarketMeta:
      properties:
        category:
          example: crypto
          type: string
        close_at:
          example: '2026-07-22T18:00:00Z'
          type: string
        ctf_no_token_id:
          example: '9876543210987654321098765432109876543210'
          type: string
        ctf_yes_token_id:
          description: >-
            CTFYesTokenID / CTFNoTokenID are the on-chain ERC-1155 position ids
            for this

            market's two legs, once atlas has registered the condition. nil (and
            omitted)

            until then, because a market that is not CTF-registered has no
            tokens — emitting

            "" would read as "registered with an empty id".


            Published because a token id IS the market-and-outcome identifier:
            it is derived

            from (resolver, questionId, collateral), so it names exactly one
            outcome of one

            market and never changes. A signed exchange order carries the token
            id and NO

            market field — the token id has already answered "which market,
            which outcome".


            Serving them here is what lets an API client build an order from the
            market it

            already fetched, rather than making a second authed per-market call
            for data that

            is public, immutable and identical for every member.
          example: '1234567890123456789012345678901234567890'
          type: string
        description:
          example: >-
            Resolves YES if the Coinbase BTC-USD close on 31 Dec 2026 is above
            $70,000.
          type: string
        determination_at:
          description: >-
            DeterminationAt is when the outcome is EXPECTED to become knowable —

            distinct from close, which is only when trading stops.


            Published so a member is told the gap in advance. Kalshi's
            daily-high

            temperature markets settle 6–7 hours after close because the
            authoritative

            report lands hours after the weather; without this field that reads
            as a

            stuck market rather than a documented wait.


            Omitted when the outcome is expected at close.
          example: '2026-07-23T10:00:00Z'
          type: string
        event_id:
          example: 12345
          type: integer
        event_rank:
          description: >-
            EventRank is the operator's manual ordering of this market WITHIN
            its

            event (`markets.event_rank`), ascending. nil = unranked. It exists
            because

            the natural order of a ladder is not derivable from price: a date
            ladder

            reads chronologically, a strike ladder by strike, and neither
            matches

            probability order. When no market in an event carries a rank, the
            default

            sort falls back to probability descending — the right answer for

            candidate-style events.
          example: 1
          type: integer
        event_slug:
          description: >-
            EventSlug / EventTitle are the market's event context, denormalised
            onto the

            market itself.


            A market is not addressable on its own — there is no markets.slug
            column, and the

            app routes /event/{slug}?market={id} — so without these a client
            holding a market

            from the flat /markets list cannot build a link or name what it
            belongs to, and

            has to go back for the event.


            Carried even when the market is already nested inside its event
            (where it is

            strictly redundant) so a market object means the same thing wherever
            it is found.

            A caller that pulls one out of an event payload and passes it on
            must not end up

            with something that has quietly lost its context.


            EventID is the durable key; the slug is editable and is for display
            and routing.
          example: btc-above-70k-december-2026
          type: string
        event_title:
          example: Will BTC close above $70,000 on 31 Dec 2026?
          type: string
        group_item_title:
          description: >-
            GroupItemTitle (markets.group_item_title) is this market's short
            label

            WITHIN its event — "Atlanta Hawks", "O/U 2.5". nil means the
            frontend

            derives one from the title, which is why an unlabelled contender
            list

            currently reads "Will Abiy Ahmed be the next Prime Min…".
          example: Above $70,000
          type: string
        id:
          example: 54321
          type: integer
        image_url:
          example: https://cdn.calibri.io/markets/btc-70k.png
          type: string
        market_id:
          description: the ID used in the markets/order book
          example: '54321'
          type: string
        open_at:
          example: '2026-07-21T10:00:00Z'
          type: string
        outcome_labels:
          description: >-
            OutcomeLabels are the display names of this market's two legs, index
            0 the

            YES leg and index 1 the NO leg, with the ["Yes","No"] default
            already

            applied — consumers never have to handle NULL. Naming them turns a

            proposition into a head-to-head, so the chart draws two labelled
            lines

            instead of one and the buy buttons carry the contestant's name.


            DISPLAY ONLY. The canonical resolution leg is still YES/NO:
            settlement,

            the CTF condition and every ledger row are untouched by a relabel.
          items:
            type: string
          type: array
          uniqueItems: false
        price_settlement:
          $ref: '#/components/schemas/PriceSettlement'
        price_target:
          $ref: '#/components/schemas/PriceTarget'
        quote_currency:
          example: usdc
          type: string
        resolution_source:
          example: Coinbase BTC-USD
          type: string
        result:
          example: 'yes'
          type: string
        rules:
          example: >-
            Settles on the final Coinbase BTC-USD trade price before 23:59:59
            UTC.
          type: string
        settlement_panel:
          $ref: '#/components/schemas/SettlementPanel'
        status:
          example: active
          type: string
        terms:
          $ref: '#/components/schemas/MarketTerms'
        title:
          example: Will BTC close above $70,000 on 31 Dec 2026?
          type: string
      type: object
    SeriesRef:
      description: >-
        Series is the FEED this event came from — Polymarket's `atp` /
        `mls-2025`,

        Kalshi's `series_ticker`. Usually absent: a one-off competition has no
        feed

        behind it, and Polymarket returns `series: []` on every Wimbledon event

        including the matches. Omitted from JSON when unset.
      properties:
        frequency:
          description: >-
            How often the feed produces events. Carried because the browse feed
            has

            to tell a rolling series from a one-off: a five-minute feed
            publishes 288

            events a day and must appear ONCE, not 288 times.
          example: daily
          type: string
        generated:
          description: >-
            Generated reports whether atlas's roller mints this series' events
            from a

            template (`series.roll_template` is set), rather than them being
            imported

            or hand-made.


            This is what says the events are the SAME QUESTION per window, and

            frequency cannot substitute for it. `seed-atp` and a daily crypto
            up/down

            feed are both `daily`; one publishes a different fixture each day
            and must

            be listed in full, the other asks "did BTC close up?" every day and
            must

            collapse to one card. Collapsing on frequency alone would bury the

            fixtures; not collapsing would show the same question six times.
          example: true
          type: boolean
        id:
          example: 789
          type: integer
        slug:
          example: daily-btc-close
          type: string
        title:
          example: Daily BTC Close
          type: string
      type: object
    CategoryRef:
      description: >-
        Subcategory is the browse SUBJECT — the leaf of the two-level category

        tree, carrying its parent for a breadcrumb. Exactly one per event and

        often absent, because an event may sit directly under its top-level

        category.


        Not a replacement for Category above: that stays the fee key. This is
        what

        the browse chips and the /categories drilldown are built from.
      properties:
        icon:
          description: >-
            Icon KEY the frontends map, not an icon. Replaces their hardcoded
            maps,

            which could not be extended without a deploy.
          example: SportsSoccer
          type: string
        id:
          example: 15
          type: integer
        label:
          example: Soccer
          type: string
        parent:
          $ref: '#/components/schemas/CategoryParentRef'
        slug:
          example: soccer
          type: string
      type: object
    TagRef:
      properties:
        id:
          example: 111
          type: integer
        label:
          example: Wimbledon
          type: string
        slug:
          example: wimbledon
          type: string
      type: object
    PriceSettlement:
      description: >-
        PriceSettlement is the pair of numbers that decided a price-feed market:

        the deciding candle's open and close.


        Published so a settled window can show what happened — price to beat,

        final price, the difference, and which way it went — WITHOUT reading the

        asset price history. That independence is the point: history is recorded

        best-effort over a websocket, so a gap in it must degrade the chart and

        not the answer. These numbers came from the exchange candle that
        actually

        settled the market.


        nil for anything not settled from a candle.
      properties:
        candle_start:
          description: >-
            The deciding candle's opening instant, ISO-8601 UTC. Reproducible:
            anyone

            can re-request this exact candle and get these exact numbers.
          example: '2026-07-22T18:00:00Z'
          type: string
        close:
          example: 69200.5
          type: number
        granularity_seconds:
          example: 300
          type: integer
        open:
          example: 68500.75
          type: number
        symbol:
          description: Coinbase product id, e.g. "BTC-USD".
          example: BTC-USD
          type: string
        tie:
          description: >-
            True when close == open exactly, which at five-minute granularity on
            a

            quiet market is a real outcome rather than a rounding artefact.
            Published

            because the rule that breaks it (ties resolve up) is otherwise
            invisible

            on the one market where it decided the answer.
          example: false
          type: boolean
      type: object
    PriceTarget:
      description: >-
        PriceTarget is the level this market is judged against, published BEFORE

        it settles.


        The sibling of PriceSettlement and deliberately not the same thing.

        PriceSettlement is what happened and exists only once a market is
        decided;

        this is the question, and it is known the moment the market is listed. A

        strike ladder needs it: every rung shares one underlying price chart and

        differs only in where its line sits, so without this the front end has a

        chart and no idea what to draw on it.


        nil for anything not judged against a fixed level — an up/down window's

        reference is its own opening price, which is PriceSettlement's business.
      properties:
        cap_strike:
          example: 77500
          type: number
        comparator:
          description: >-
            How the close is compared to it: gte, gt, lte or lt. Published
            because

            "above $77,000" and "at or above $77,000" are different markets on a
            tie,

            and the chart's own label should not have to guess which one this
            is.
          example: gte
          type: string
        floor_strike:
          description: >-
            Band form, half-open [floor, cap): inclusive floor, exclusive cap.
            That

            convention is not a detail — it is what lets a set of bands cover
            the

            price line exactly once, with no gap for a close to fall through and
            no

            overlap where two legs both pay.


            Either bound is absent on a wing: a bottom band has only a cap, a
            top

            band only a floor. Pointers rather than plain floats so "no floor"
            and "a

            floor of zero" stay distinguishable on the wire.
          example: 75000
          type: number
        threshold:
          description: >-
            Threshold form. The level the close is compared against, in the
            market's

            quote currency. Zero and absent are indistinguishable in Go, so a
            chart

            must branch on Comparator being set rather than on Threshold being

            non-zero — a strike genuinely at 0 is nonsense, but a FLOOR at 0 is
            not.
          example: 77000
          type: number
      type: object
    SettlementPanel:
      description: |-
        SettlementPanel is the PUBLISHED, ordered list of authorities this
        market's outcome may be determined from, resolved from the market's own
        override or inherited from its series.

        Carried on the public payload deliberately. The panel's whole value is
        that a member could read it BEFORE they traded — an unpublished rule is
        not the rule anyone agreed to, and a hierarchy that lives only in the
        admin tool cannot be quoted back at us in a dispute, which is the one
        situation it exists for.

        nil when no panel governs the market, which is the normal case for
        anything a machine settles.
      properties:
        description:
          description: |-
            How the panel is applied beyond the ordering — what happens when two
            sources disagree, and what happens when none has published.
          example: First consult these sources
          type: string
        entries:
          description: >-
            Already ordered: primaries first, then fallbacks, each by rank. The
            order

            IS the content — it is what decides the outcome when two sources
            disagree.
          items:
            $ref: '#/components/schemas/SettlementSource'
          type: array
          uniqueItems: false
        id:
          example: 456
          type: integer
        inherited_from_series:
          description: >-
            True when the panel came from the series rather than the market
            itself.
          example: false
          type: boolean
        name:
          example: Primary Sources
          type: string
        terms_url:
          description: The rules page it is published on.
          example: https://calibri.io/hub/terms-of-use
          type: string
      type: object
    MarketTerms:
      description: >-
        Terms is what this market resolves against, as structured fields — the

        conditions `rules` states in prose: kind, strike_type, floor_strike /

        cap_strike, underlying, measure (instant, granularity, basis) and
        settles_on.


        `rules` is for a person and free to change its wording; terms are what
        code

        reads, so an integrator never parses a title to learn the strike. Kalshi

        publishes the same thing as strike_type / floor_strike / cap_strike.


        Stored by atlas (`markets.terms`, derived from the resolution source and
        its

        params — atlas owns that derivation) and decoded here only so the
        published

        schema names every field. Omitted for a market with no automated source.
      properties:
        cap_strike:
          example: 77500
          type: number
        floor_strike:
          description: >-
            Null when not applicable. A band is half-open: inclusive floor,
            exclusive cap.
          example: 70000
          type: number
        kind:
          description: threshold | range | direction | categorical
          example: threshold
          type: string
        measure:
          $ref: '#/components/schemas/TermsMeasure'
        settles_on:
          description: The resolution provider that settles the market, e.g. coinbase_spot.
          example: coinbase_spot
          type: string
        strike_type:
          description: >-
            greater | greater_equal | less | less_equal | between | direction |
            none
          example: greater_equal
          type: string
        underlying:
          $ref: '#/components/schemas/TermsUnderlying'
      type: object
    CategoryParentRef:
      description: The top-level node this sits under. Absent on a top-level node itself.
      properties:
        icon:
          example: SportsSoccer
          type: string
        id:
          example: 10
          type: integer
        label:
          example: Sports
          type: string
        slug:
          example: sports
          type: string
      type: object
    SettlementSource:
      properties:
        name:
          example: Coinbase
          type: string
        tier:
          description: |-
            "primary" — consult first, a body that publishes the answer itself.
            "fallback" — only where no primary source has spoken.
          example: primary
          type: string
        url:
          example: https://www.coinbase.com/price/bitcoin
          type: string
      type: object
    TermsMeasure:
      properties:
        at:
          description: >-
            The instant that decides it: the deciding candle's close, ISO-8601
            UTC.
          example: '2026-09-17T00:00:00Z'
          type: string
        basis:
          description: >-
            close | close_vs_previous_close (this window's close against the
            previous

            window's close; a tie resolves up)
          example: close
          type: string
        granularity_seconds:
          example: 60
          type: integer
        window_start:
          description: A direction market's window opens here; `at` is when it closes.
          example: '2026-09-16T16:00:00Z'
          type: string
      type: object
    TermsUnderlying:
      properties:
        source:
          example: coinbase
          type: string
        symbol:
          example: BTC-USD
          type: string
      type: object

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.