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

# OHLCV candles

> Read one token's candle series at any timeframe, priced or by market cap.

Candles come oldest first, one per bucket that traded. A bucket with no trades is left out.

## Choosing the window

`countBack` asks for a bar count and supersedes `from`, while `to` and `timeframe` still apply. A request that names neither `countBack` nor `from` returns the most recent 500 buckets, and a window holding more than 5000 candles keeps the newest. This matches what TradingView's charting library expects.

## Paging through candles

The series has no cursor. `from` is inclusive and `to` is exclusive, both in milliseconds; leave `to` out to read up to now. To read further back, repeat the request with `to` set to the `time` of the oldest candle you received. Because `to` is exclusive, that candle is not repeated.

```bash theme={null}
curl "https://api.metastreams.io/v1/tokens/solana/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263/ohlcv?timeframe=1m&countBack=5000&to=1789545600000" \
  -H "Authorization: Bearer $API_KEY"
```

## Reading the response

Candle values are JSON numbers, not the decimal strings the token and trade objects carry. They feed charting libraries, which take numbers.

## Errors

| Code | When |
| - | - |
| `UNSUPPORTED_CHAIN` | `chain` is not a supported slug |
| `VALIDATION_ERROR` | A malformed address, an unknown `timeframe`, `from` greater than `to`, a `countBack` outside 1–5000, or an unknown parameter |

An unknown token answers an empty series, not a `404`.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.metastreams.io/v1/tokens/solana/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263/ohlcv?timeframe=1h&metric=price&countBack=24" \
    -H "Authorization: Bearer $API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const url = new URL(
    "https://api.metastreams.io/v1/tokens/solana/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263/ohlcv",
  );
  url.searchParams.set("timeframe", "1h");
  url.searchParams.set("metric", "price");
  url.searchParams.set("countBack", "24");

  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.API_KEY}` },
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const { candles } = await response.json();
  ```
</RequestExample>

<ResponseExample>
  ```json Series theme={null}
  {
    "candles": [
      { "time": 1789545600000, "open": 0.0000221, "high": 0.0000224, "low": 0.0000219, "close": 0.0000222, "volume": 2104410.5 },
      { "time": 1789549200000, "open": 0.0000222, "high": 0.0000223, "low": 0.0000215, "close": 0.0000216, "volume": 2981337.2 }
    ]
  }
  ```

  ```json Inverted window theme={null}
  {
    "error": {
      "code": "VALIDATION_ERROR",
      "message": "One or more parameters are invalid.",
      "details": [{ "field": "from", "message": "Must not be greater than `to`." }]
    }
  }
  ```
</ResponseExample>


## OpenAPI

````yaml specs/openapi.json GET /v1/tokens/{chain}/{address}/ohlcv
openapi: 3.1.0
info:
  title: Metastreams API
  description: >-
    Click's B2B market-data API. Amounts are decimal strings, timestamps are
    Unix milliseconds, and every field name is camelCase.
  license:
    name: Proprietary
    identifier: Proprietary
  version: 1.0.0
servers:
  - url: https://{host}
    variables:
      host:
        default: api.metastreams.io
        description: API host.
security:
  - bearerKey: []
paths:
  /v1/tokens/{chain}/{address}/ohlcv:
    get:
      tags:
        - ohlcv
      summary: OHLCV candles at one timeframe, oldest first.
      description: >-
        The series follows the `TradingView` contract: `countBack` asks for a
        bar

        count and supersedes `from`; `to` and `timeframe` still bind. A window
        with

        more candles than the cap keeps the newest. To read older candles,
        repeat

        the request with `to` set to the earliest `time` received.
      operationId: token_ohlcv
      parameters:
        - name: chain
          in: path
          description: Chain the resource lives on.
          required: true
          schema:
            $ref: '#/components/schemas/SpotChain'
        - name: address
          in: path
          description: Token mint or contract address.
          required: true
          schema:
            type: string
          example: So11111111111111111111111111111111111111112
        - name: timeframe
          in: query
          required: false
          schema:
            type: string
            description: Candle bucket size; defaults to `1m`.
            default: 1m
            enum:
              - 1s
              - 5s
              - 15s
              - 30s
              - 1m
              - 3m
              - 5m
              - 15m
              - 30m
              - 1h
              - 4h
              - 6h
              - 12h
              - 1d
              - 7d
        - name: metric
          in: query
          description: OHLC metric, `price` or `marketCap`; defaults to `marketCap`.
          required: false
          schema:
            type: string
            default: marketCap
        - name: denomination
          in: query
          description: OHLC denomination; defaults to `usd`.
          required: false
          schema:
            type: string
            default: usd
        - name: from
          in: query
          description: >-
            Window start, inclusive; ignored when `countBack` is set. A window
            holding

            more candles than the cap keeps the newest.
          required: false
          schema:
            $ref: '#/components/schemas/UnixMilliseconds'
        - name: to
          in: query
          description: Window end, exclusive.
          required: false
          schema:
            $ref: '#/components/schemas/UnixMilliseconds'
        - name: countBack
          in: query
          description: >-
            `TradingView` bar count: the most recent N buckets at or before
            `to`.

            Takes priority over `from`.
          required: false
          schema:
            type: integer
            format: int32
            maximum: 5000
            minimum: 1
      responses:
        '200':
          description: >-
            One candle per bucket that traded, oldest first. The most recent 500
            buckets when the request names neither `countBack` nor `from`.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UiCandlesResponse'
        '400':
          description: >-
            Unsupported chain, a malformed address, an unknown timeframe, an
            inverted range, a `countBack` outside 1-5000, or a malformed
            parameter.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Missing or invalid API key.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limit exceeded.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait before retrying.
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Unexpected server failure.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: Dependency down or maintenance.
          headers:
            X-Credits-Cost:
              schema:
                type: integer
              description: >-
                Credits charged for this request. Zero on any non-2xx. Sent on a
                metered tier only.
            X-Credits-Remaining:
              schema:
                type: integer
              description: Credit balance after this request. Sent on a metered tier only.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests left in the current rate-limit window.
            X-Request-ID:
              schema:
                type: string
              description: >-
                This request's trace ID. Echoed from the request, or generated
                when it sent none.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    SpotChain:
      type: string
      description: >-
        Chain slug. One spelling per chain, in paths and bodies alike. Only a
        chain with spot data is published.
      enum:
        - solana
        - base
        - bsc
        - robinhood
        - arc
    UnixMilliseconds:
      type: integer
      format: int64
      description: An instant, as milliseconds since the Unix epoch.
    UiCandlesResponse:
      type: object
      description: '`GET /v1/tokens/{chain}/{address}/ohlcv` response.'
      required:
        - candles
      properties:
        candles:
          type: array
          items:
            $ref: '#/components/schemas/UiCandle'
          description: Buckets, oldest first.
    ErrorEnvelope:
      type: object
      description: The complete error response body — every error is exactly this.
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
          description: The error.
    UiCandle:
      type: object
      description: >-
        One chart OHLC bucket. The request's metric decides whether the values
        are

        prices or market caps, and its denomination decides what they are
        denominated in.


        Values are JSON numbers, the one amount on this surface that is: a chart

        client consumes them as floats, and every OHLCV feed it already reads is

        shaped this way. A bucket with no trades in it is not emitted, so a
        series

        is sparse.
      required:
        - time
        - open
        - high
        - low
        - close
        - volume
      properties:
        close:
          type: number
          format: double
          description: Closing value.
          example: 0.7
        high:
          type: number
          format: double
          description: Highest value.
          example: 2
        low:
          type: number
          format: double
          description: Lowest value.
          example: 0.5
        open:
          type: number
          format: double
          description: Opening value.
          example: 1
        time:
          $ref: '#/components/schemas/UnixMilliseconds'
          description: Candle open time.
        volume:
          type: number
          format: double
          description: Traded volume, in the requested denomination.
          example: 1000
    ErrorDetail:
      type: object
      description: The `error` object inside the envelope.
      required:
        - code
        - message
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: >-
            Stable, machine-readable. Clients switch on this, never on
            `message`.
        details:
          description: Optional; shape is fixed per code.
        message:
          type: string
          description: |-
            Human-readable, written for the integrating developer:
            `[What happened]. [What to do next — if actionable].`
    ErrorCode:
      type: string
      description: |-
        Every wire error code the API can return.

        Append-only: a new code is non-breaking, since clients fall back on the
        HTTP status for one they do not recognize, and a published code is never
        renamed or removed.
      enum:
        - UNAUTHORIZED
        - FORBIDDEN
        - VALIDATION_ERROR
        - UNSUPPORTED_CHAIN
        - NOT_FOUND
        - RATE_LIMITED
        - CREDITS_EXHAUSTED
        - INTERNAL_ERROR
        - SERVICE_UNAVAILABLE
  securitySchemes:
    bearerKey:
      type: http
      scheme: bearer
      description: 'Send the API key as `Authorization: Bearer <key>`.'

````

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