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

# Get a market's price history bars

> Price history bars (open, high, low, close) for a window you choose, at 1m to 1d.

**The window**

- `start` and `end` are unix milliseconds, inclusive, and must span fewer than 1000 bars at the chosen `resolution`.

**The bars**

- Prices are 0..1. `volume_usd` is null where the venue has no trade tape. `basis` names the price each venue's bars are built from.
- Bars before 2026-10-05 23:42:28Z may pair one side's new quote with the other's old one.

**Freshness**

- `as_of_ms` and `cached`: when this answer was built, and whether it came from the cache.
- `last_bar_ts_ms` is information, not a freshness signal: a quiet market adds no bars.

**Errors**

| Status | Code | When |
|---|---|---|
| 422 | `invalid_request` | Missing, non-integer, seconds or after-9999-12-30 bounds; start >= end; a span of 1000 bars or more; an unknown resolution. |
| 422 | `venue_unsupported` | A venue whose price history is not served yet. Every venue has price history today. |
| 404 | `not_found` | Unknown market. |
| 404 | `venue_not_listed` | The market has no leg on that venue. |
| 503 | `upstream_unavailable` | History unavailable for a venue, the market or history lookup failing or timed out, or busy (with `Retry-After`). |
| 503 | `upstream_unavailable` | A bar failed our checks: a bar beyond the window's neighbouring grid points or not a finite number, a price outside 0..1, a malformed series or bar, a bar with no readable time, a bar with no price, a negative volume. |

Any route can also answer 401, 403, 429, 500 or 503 `dependency_unavailable`, described on the Errors page.

A failing venue is never dropped from a partial 200: the whole request is refused.



## OpenAPI

````yaml /openapi.json get /public/v1/markets/{universal_id}/candles
openapi: 3.1.0
info:
  description: >-
    Read-only prediction-market data across Polymarket, Kalshi, Limitless and
    predict.fun over REST. Every request sends your key as `Authorization:
    Bearer tl_live_…`; try any endpoint from its page.
  title: TrendlineLabs Public API
  version: '1'
servers:
  - description: Production
    url: https://systems.trendlinelabs.ai
security: []
tags:
  - description: 'Read back the key you are calling with: its scopes, tier and rate limit.'
    name: Your key
  - description: Events group markets across venues; each carries a `universal_id`.
    name: Events
  - description: One market's order book, price history and trades on one venue.
    name: Markets
  - description: Current prices for a set of markets in one call.
    name: Prices
  - description: Live cross-venue price gaps on the same market.
    name: Opportunities
paths:
  /public/v1/markets/{universal_id}/candles:
    get:
      tags:
        - Markets
      summary: Get a market's price history bars
      description: >-
        Price history bars (open, high, low, close) for a window you choose, at
        1m to 1d.


        **The window**


        - `start` and `end` are unix milliseconds, inclusive, and must span
        fewer than 1000 bars at the chosen `resolution`.


        **The bars**


        - Prices are 0..1. `volume_usd` is null where the venue has no trade
        tape. `basis` names the price each venue's bars are built from.

        - Bars before 2026-10-05 23:42:28Z may pair one side's new quote with
        the other's old one.


        **Freshness**


        - `as_of_ms` and `cached`: when this answer was built, and whether it
        came from the cache.

        - `last_bar_ts_ms` is information, not a freshness signal: a quiet
        market adds no bars.


        **Errors**


        | Status | Code | When |

        |---|---|---|

        | 422 | `invalid_request` | Missing, non-integer, seconds or
        after-9999-12-30 bounds; start >= end; a span of 1000 bars or more; an
        unknown resolution. |

        | 422 | `venue_unsupported` | A venue whose price history is not served
        yet. Every venue has price history today. |

        | 404 | `not_found` | Unknown market. |

        | 404 | `venue_not_listed` | The market has no leg on that venue. |

        | 503 | `upstream_unavailable` | History unavailable for a venue, the
        market or history lookup failing or timed out, or busy (with
        `Retry-After`). |

        | 503 | `upstream_unavailable` | A bar failed our checks: a bar beyond
        the window's neighbouring grid points or not a finite number, a price
        outside 0..1, a malformed series or bar, a bar with no readable time, a
        bar with no price, a negative volume. |


        Any route can also answer 401, 403, 429, 500 or 503
        `dependency_unavailable`, described on the Errors page.


        A failing venue is never dropped from a partial 200: the whole request
        is refused.
      operationId: getCandles
      parameters:
        - description: >-
            no control, format, private-use, unassigned, line or paragraph
            separator character
          in: path
          name: universal_id
          required: true
          schema:
            description: >-
              no control, format, private-use, unassigned, line or paragraph
              separator character
            maxLength: 256
            minLength: 1
            title: Universal Id
            type: string
        - description: the bar width
          in: query
          name: resolution
          required: true
          schema:
            description: the bar width
            enum:
              - 1m
              - 5m
              - 15m
              - 1h
              - 6h
              - 1d
            title: Resolution
            type: string
        - description: window start, unix milliseconds, inclusive
          in: query
          name: start
          required: true
          schema:
            description: window start, unix milliseconds, inclusive
            title: Start
            type: integer
        - description: window end, unix milliseconds, inclusive
          in: query
          name: end
          required: true
          schema:
            description: window end, unix milliseconds, inclusive
            title: End
            type: integer
        - description: one venue's series only; omit for every venue that lists the market
          in: query
          name: venue
          required: false
          schema:
            anyOf:
              - enum:
                  - kalshi
                  - polymarket
                  - limitless
                  - predictfun
                type: string
              - type: 'null'
            description: >-
              one venue's series only; omit for every venue that lists the
              market
            title: Venue
      responses:
        '200':
          content:
            application/json:
              example:
                as_of_ms: 1791270100000
                cached: false
                end_ms: 1791270000000
                resolution: 1h
                series:
                  kalshi:
                    bars:
                      - close: 0.42
                        high: 0.43
                        low: 0.4
                        open: 0.41
                        ts_ms: 1791266400000
                        volume_usd: 1250
                      - close: 0.41
                        high: 0.42
                        low: 0.41
                        open: 0.42
                        ts_ms: 1791270000000
                        volume_usd: 310
                    basis: yes_ask
                    exists: true
                    last_bar_ts_ms: 1791270000000
                    venue_market_id: KXBTC-26DEC31-B100000
                start_ms: 1791266400000
                universal_id: mk-btc-100k-2026
              schema:
                $ref: '#/components/schemas/PublicCandles'
          description: Successful Response
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: 'unauthorized: no key, or a key that is unknown, revoked or expired.'
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            WWW-Authenticate:
              description: Bearer realm="public-api"
              schema:
                type: string
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            insufficient_scope: the key lacks the scope this route needs;
            ip_not_allowed: the request came from an address outside the key's
            allowlist; tier_required: the key owner's plan does not include API
            access; access_not_granted: API access is free but granted on
            request; request it on https://trendlinelabs.ai/developer.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            not_found: no such event, market or key; venue_not_listed: the
            market has no leg on that venue.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            invalid_request: a parameter is missing, unknown, malformed or out
            of bounds, or a cursor does not match; venue_unsupported: the route
            does not serve that venue.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            rate_limited: too many requests, or too many failed authentications;
            wait Retry-After seconds.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            Retry-After:
              description: seconds to wait before retrying
              schema:
                type: integer
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            internal_error: an unexpected failure on our side; quote the request
            id. The body may instead be text/plain with no envelope and no
            X-RateLimit-* headers when a failure escapes the route's own
            handling.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicError'
          description: >-
            dependency_unavailable: one of our own stores could not be read;
            retry later; upstream_unavailable: the data source is unreadable,
            absent or older than its bound; never an empty 200.
          headers:
            Cache-Control:
              description: no-store on every answer
              schema:
                type: string
            Retry-After:
              description: seconds to wait before retrying
              schema:
                type: integer
            X-RateLimit-Limit:
              description: >-
                requests allowed per window for this key; present once the key
                passed the limiter
              schema:
                type: integer
            X-RateLimit-Remaining:
              description: >-
                requests left in this window; present once the key passed the
                limiter
              schema:
                type: integer
            X-RateLimit-Reset:
              description: >-
                seconds until the window resets; present once the key passed the
                limiter
              schema:
                type: integer
            X-Request-Id:
              description: >-
                this request's id (yours, when you sent X-Request-Id); equals
                the envelope's request_id
              schema:
                type: string
      security:
        - HTTPBearer: []
      x-codeSamples:
        - label: cURL
          lang: bash
          source: >
            #!/bin/sh

            # getCandles: Get a market's price history bars. Needs
            TRENDLINE_API_KEY; TRENDLINE_API_BASE overrides the base.

            curl -sS
            "${TRENDLINE_API_BASE:-https://systems.trendlinelabs.ai}/public/v1/markets/mk-btc-100k-2026/candles?resolution=1h&start=1791266400000&end=1791270000000&venue=kalshi"
            \
              -H "Authorization: Bearer $TRENDLINE_API_KEY"
        - label: Python
          lang: python
          source: >
            """getCandles: Get a market's price history bars. Needs
            TRENDLINE_API_KEY; TRENDLINE_API_BASE overrides the base."""

            import os


            import requests


            BASE = os.environ.get("TRENDLINE_API_BASE",
            "https://systems.trendlinelabs.ai")

            KEY = os.environ["TRENDLINE_API_KEY"]


            r =
            requests.get(f"{BASE}/public/v1/markets/mk-btc-100k-2026/candles",
            params={"resolution": "1h", "start": "1791266400000", "end":
            "1791270000000", "venue": "kalshi"},
                             headers={"Authorization": f"Bearer {KEY}"}, timeout=10)
            r.raise_for_status()

            print(r.json())
        - label: JavaScript
          lang: javascript
          source: >
            // getCandles: Get a market's price history bars. Needs
            TRENDLINE_API_KEY; TRENDLINE_API_BASE overrides the base.

            const BASE = process.env.TRENDLINE_API_BASE ??
            "https://systems.trendlinelabs.ai";

            const KEY = process.env.TRENDLINE_API_KEY;

            const r = await
            fetch(`${BASE}/public/v1/markets/mk-btc-100k-2026/candles?resolution=1h&start=1791266400000&end=1791270000000&venue=kalshi`,
            { headers: { Authorization: `Bearer ${KEY}` } });

            console.log(r.status, await r.json());
components:
  schemas:
    PublicCandles:
      properties:
        as_of_ms:
          description: when the history was read, unix milliseconds
          title: As Of Ms
          type: integer
        cached:
          description: true when served from a recent identical read
          title: Cached
          type: boolean
        end_ms:
          description: the window end, unix milliseconds
          title: End Ms
          type: integer
        resolution:
          description: the bar width
          enum:
            - 1m
            - 5m
            - 15m
            - 1h
            - 6h
            - 1d
          title: Resolution
          type: string
        series:
          additionalProperties:
            $ref: '#/components/schemas/PublicCandleSeries'
          description: one series per venue that lists the market
          propertyNames:
            enum:
              - kalshi
              - polymarket
              - limitless
              - predictfun
          title: Series
          type: object
        start_ms:
          description: the window start, unix milliseconds
          title: Start Ms
          type: integer
        universal_id:
          description: the market universal id
          title: Universal Id
          type: string
      required:
        - universal_id
        - resolution
        - start_ms
        - end_ms
        - as_of_ms
        - cached
        - series
      title: PublicCandles
      type: object
    PublicError:
      properties:
        error:
          $ref: '#/components/schemas/PublicErrorBody'
          description: the refusal
      required:
        - error
      title: PublicError
      type: object
    PublicCandleSeries:
      properties:
        bars:
          default: []
          description: the bars in the window, oldest first
          items:
            $ref: '#/components/schemas/PublicCandle'
          title: Bars
          type: array
        basis:
          description: 'which price the bars track: the YES ask, the YES bid, or their mid'
          enum:
            - yes_ask
            - yes_bid
            - mid
          title: Basis
          type: string
        exists:
          description: false when the venue has no history for this market
          title: Exists
          type: boolean
        last_bar_ts_ms:
          anyOf:
            - type: integer
            - type: 'null'
          description: information only, not a liveness signal
          title: Last Bar Ts Ms
        venue_market_id:
          description: the market's id on this venue
          title: Venue Market Id
          type: string
      required:
        - venue_market_id
        - exists
        - basis
      title: PublicCandleSeries
      type: object
    PublicErrorBody:
      properties:
        code:
          description: >-
            a machine-readable code from x-known-codes; a new code may be added,
            so handle an unknown one by its status
          title: Code
          type: string
          x-known-codes:
            - access_not_granted
            - dependency_unavailable
            - insufficient_scope
            - internal_error
            - invalid_request
            - ip_not_allowed
            - market_closed
            - not_found
            - rate_limited
            - tier_required
            - unauthorized
            - upstream_unavailable
            - venue_not_listed
            - venue_unsupported
        message:
          description: a human-readable explanation; never parse it
          title: Message
          type: string
        request_id:
          description: >-
            this request's id, also sent as the X-Request-Id header; quote it
            when asking for help
          title: Request Id
          type: string
      required:
        - code
        - message
        - request_id
      title: PublicErrorBody
      type: object
    PublicCandle:
      properties:
        close:
          description: the last price in the bar, 0..1
          title: Close
          type: number
        high:
          description: the highest price in the bar, 0..1
          title: High
          type: number
        low:
          description: the lowest price in the bar, 0..1
          title: Low
          type: number
        open:
          description: the first price in the bar, 0..1
          title: Open
          type: number
        ts_ms:
          description: the bar's start, unix milliseconds
          title: Ts Ms
          type: integer
        volume_usd:
          anyOf:
            - type: number
            - type: 'null'
          description: >-
            traded volume in USD in the bar; null where the venue has no trade
            tape
          title: Volume Usd
      required:
        - ts_ms
        - open
        - high
        - low
        - close
      title: PublicCandle
      type: object
  securitySchemes:
    HTTPBearer:
      description: 'Authorization: Bearer tl_live_…'
      scheme: bearer
      type: http

````

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