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

# Get product prices

> Daily price history for a sealed product.

The same windowing as [card prices](/cards/prices): the last 90 days by default, `from` and `to`
as `YYYY-MM-DD` for anything else up to 366 days wide, and a `400` for a window that is
malformed, inverted, or wider than the maximum.

A product has no printings, so `tcgplayer` sits at the top of the response with one history per
condition, rather than nested one level down under a printing.

`range`, `interval` and `fill` behave exactly as they do on card prices, down to the same preset
windows and the same two `400`s. See
[charting a range](/cards/prices#charting-a-range) for the preset table, and
[telling a sighting from a carried value](/cards/prices#telling-a-sighting-from-a-carried-value)
for what `as_of` and `observations` mean on each point.


## OpenAPI

````yaml openapi.json GET /v1/products/{id}/prices
openapi: 3.0.0
info:
  title: Cromos API
  version: 1.0.0
servers:
  - url: https://api.cromos.so
security:
  - bearerAuth: []
paths:
  /v1/products/{id}/prices:
    get:
      tags:
        - Products
      summary: Get product prices
      description: >-
        Daily price history for one sealed product. Defaults to the last 90
        days; pass `from` and `to` as `YYYY-MM-DD` for a different window, up to
        366 days wide, or `range` for a chart-ready series ending today. Returns
        404 if no product carries the id, and 400 if the window is malformed,
        inverted, wider than the maximum, combined with `range`, or paired with
        `interval` while `fill` is `none`.
      operationId: getProductPrices
      parameters:
        - schema:
            type: integer
            description: The TCGplayer product id.
          required: true
          description: The TCGplayer product id.
          name: id
          in: path
        - schema:
            type: string
          required: false
          name: from
          in: query
        - schema:
            type: string
          required: false
          name: to
          in: query
        - schema:
            type: string
            description: >-
              A window ending today: `1W`, `1M`, `3M`, `6M` or `1Y`. An
              alternative to `from` and `to`, and sending both is a 400.
              Defaults `fill` to `locf` and picks an `interval` so that a wider
              window does not return proportionally more points.
          required: false
          description: >-
            A window ending today: `1W`, `1M`, `3M`, `6M` or `1Y`. An
            alternative to `from` and `to`, and sending both is a 400. Defaults
            `fill` to `locf` and picks an `interval` so that a wider window does
            not return proportionally more points.
          name: range
          in: query
        - schema:
            type: string
            description: >-
              Bucket width as a day count such as `3d`, or `auto` to derive it
              from the width of the window. Requires `fill=locf`.
          required: false
          description: >-
            Bucket width as a day count such as `3d`, or `auto` to derive it
            from the width of the window. Requires `fill=locf`.
          name: interval
          in: query
        - schema:
            type: string
            description: >-
              `locf` carries the last observed price forward across days with no
              movement. `none` returns only the days the price changed, and is
              the default when `range` is absent.
          required: false
          description: >-
            `locf` carries the last observed price forward across days with no
            movement. `none` returns only the days the price changed, and is the
            default when `range` is absent.
          name: fill
          in: query
      responses:
        '200':
          description: Product price history
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ProductPriceHistory'
                  error:
                    type: object
                    nullable: true
                required:
                  - data
                  - error
              example:
                data:
                  from: '2026-05-21'
                  to: '2026-08-19'
                  interval: 1d
                  fill: none
                  tcgplayer:
                    - condition: NM
                      currency: USD
                      history:
                        - observed_on: '2026-07-31'
                          bucket_start: '2026-07-31'
                          market: 8098
                          low: 6999
                          high: 8829
                          as_of: '2026-07-31'
                          observations: 1
                        - observed_on: '2026-08-02'
                          bucket_start: '2026-08-02'
                          market: 8171
                          low: 6999
                          high: 8829
                          as_of: '2026-08-02'
                          observations: 1
                        - observed_on: '2026-08-05'
                          bucket_start: '2026-08-05'
                          market: 8211
                          low: 6999
                          high: 8829
                          as_of: '2026-08-05'
                          observations: 1
                        - observed_on: '2026-08-10'
                          bucket_start: '2026-08-10'
                          market: 8055
                          low: 3949
                          high: 8829
                          as_of: '2026-08-10'
                          observations: 1
                        - observed_on: '2026-08-17'
                          bucket_start: '2026-08-17'
                          market: 8476
                          low: 7500
                          high: 8999
                          as_of: '2026-08-17'
                          observations: 1
                        - observed_on: '2026-08-18'
                          bucket_start: '2026-08-18'
                          market: 8486
                          low: 7500
                          high: 8999
                          as_of: '2026-08-18'
                          observations: 1
                error: null
        '304':
          description: >-
            Not modified. The `If-None-Match` you sent still matches, and there
            is no body.
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
        '400':
          description: Bad range
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limited
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal error
          headers:
            ETag:
              description: >-
                A strong validator over the response body. Send it back as
                `If-None-Match` to get a `304 Not Modified` when nothing has
                changed.
              schema:
                type: string
            RateLimit:
              description: >-
                Remaining budget in the current window, RFC 9239 draft-7 form:
                `limit=300, remaining=284, reset=41`. `reset` is seconds until
                the window rolls.
              schema:
                type: string
            RateLimit-Policy:
              description: >-
                The policy the budget above is drawn from. `300;w=60` is 300
                requests a minute.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ProductPriceHistory:
      type: object
      properties:
        from:
          type: string
        to:
          type: string
        interval:
          type: string
          description: >-
            The bucket width this response used, as a day count such as `1d` or
            `3d`. Each point covers `bucket_start` through `observed_on`
            inclusive.
        fill:
          type: string
          enum:
            - locf
            - none
          description: >-
            `locf` carries the last observed price forward across days with no
            movement, giving one point per bucket. `none` returns only the days
            the price actually changed.
        tcgplayer:
          type: array
          items:
            type: object
            properties:
              condition:
                type: string
              currency:
                type: string
                enum:
                  - USD
              history:
                type: array
                items:
                  type: object
                  properties:
                    observed_on:
                      type: string
                      description: >-
                        The date this point represents, as YYYY-MM-DD. Where
                        `interval` is wider than a day this is the last date the
                        point covers. See `as_of` for when the price was
                        actually observed.
                    bucket_start:
                      type: string
                      description: >-
                        The first date this point covers. Equal to `observed_on`
                        when `interval` is one day.
                    market:
                      type: integer
                      nullable: true
                      description: An integer amount in cents (minor units).
                    low:
                      type: integer
                      nullable: true
                      description: An integer amount in cents (minor units).
                    high:
                      type: integer
                      nullable: true
                      description: An integer amount in cents (minor units).
                    as_of:
                      type: string
                      description: >-
                        The date the price was actually observed. Earlier than
                        `observed_on` when the value was carried forward across
                        days with no movement.
                    observations:
                      type: integer
                      description: >-
                        How many real observations fall inside this point. `0`
                        means every day it covers was carried forward from an
                        earlier price.
                  required:
                    - observed_on
                    - bucket_start
                    - market
                    - low
                    - high
                    - as_of
                    - observations
            required:
              - condition
              - currency
              - history
      required:
        - from
        - to
        - interval
        - fill
        - tcgplayer
    ErrorResponse:
      type: object
      properties:
        data:
          type: object
          nullable: true
        error:
          $ref: '#/components/schemas/ApiError'
      required:
        - data
        - error
    ApiError:
      type: object
      properties:
        code:
          type: string
          description: A stable machine-readable token. Switch on this, not on `message`.
        message:
          type: string
          description: A human-readable sentence. Always present, never empty.
      required:
        - code
        - message
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````