> ## 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 card prices

> Daily price history for every printing of a card.

Every printing gets its own price history, and inside a printing you get one USD history **per
condition**. A holo Charizard priced in `NM`, `LP`, `MP`, `HP` and `DMG` returns five tcgplayer
histories for that one printing rather than one. See [the card object](/cards/object) for what
separates a printing from a condition.

The window defaults to the last 90 days. Pass `from` and `to` as `YYYY-MM-DD` for a different
one, up to 366 days wide. A window that is malformed, inverted, or wider than that is a `400`,
not an empty result. The full history stays reachable one bounded window at a time.

## Charting a range

Pass `range` instead of `from` and `to` to get a series ready to plot. Each preset ends today,
and the wider ones group days into buckets so a longer window does not return proportionally
more points.

| `range` | Window   | `interval` | Points at most |
| ------- | -------- | ---------- | -------------- |
| `1W`    | 7 days   | `1d`       | 7              |
| `1M`    | 30 days  | `1d`       | 30             |
| `3M`    | 90 days  | `3d`       | 30             |
| `6M`    | 180 days | `6d`       | 30             |
| `1Y`    | 365 days | `13d`      | 29             |

A series starts at its first observation, so a printing first priced part way through the window
returns fewer points than the table shows. Read the count off the response rather than assuming
it.

`range` and `from`/`to` are alternatives. Sending both is a `400`. Override the bucket width with
`interval`, as a day count such as `7d`, or `auto` to keep the width the preset chose.

Each point covers `bucket_start` through `observed_on` inclusive. The newest bucket always ends
on `to`, so the oldest is the short one when the window does not divide evenly.

## Filling the gaps

A price produces a point only on the days it moved. A printing that has not moved inside the
window returns no points at all, and one that moved once returns a single point. Plotted
directly, both read as missing data even though the price is known for every day.

`range` sets `fill=locf`, which carries the last observed price forward across days with no
movement. You get one point per bucket, and a condition that has not moved inside the window
stays in the response instead of dropping out of it.

Set `fill=none` for only the days the price changed. `interval` requires `fill=locf`; sending it
alongside `fill=none` is a `400`.

## Telling a sighting from a carried value

Two fields on every point separate the two:

* `as_of` is the date the price was actually observed. It matches `observed_on` for a real
  sighting and is earlier when the value was carried forward.
* `observations` counts the real observations inside the point. `0` means every day it covers was
  carried forward.

`observations: 0` does not on its own tell you a price was steady. It tells you no price was
observed inside that point. Read `as_of` to see how far back the value came from, and decide how
far a carried value should be trusted before you draw it as flat.


## OpenAPI

````yaml openapi.json GET /v1/cards/{id}/prices
openapi: 3.0.0
info:
  title: Cromos API
  version: 1.0.0
servers:
  - url: https://api.cromos.so
security:
  - bearerAuth: []
paths:
  /v1/cards/{id}/prices:
    get:
      tags:
        - Cards
      summary: Get card prices
      description: >-
        Daily price history for every printing of one card. 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 card 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: getCardPrices
      parameters:
        - schema:
            type: string
          required: true
          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: Card 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/CardPriceHistory'
                  error:
                    type: object
                    nullable: true
                required:
                  - data
                  - error
              example:
                data:
                  from: '2026-05-21'
                  to: '2026-08-19'
                  interval: 1d
                  fill: none
                  variants:
                    - variant:
                        type: holo
                        subtype: null
                        size: standard
                        stamps: []
                        foil: null
                      tcgplayer:
                        - condition: HP
                          currency: USD
                          history:
                            - observed_on: '2026-07-31'
                              bucket_start: '2026-07-31'
                              market: 26815
                              low: 19999
                              high: 37450
                              as_of: '2026-07-31'
                              observations: 1
                        - condition: MP
                          currency: USD
                          history:
                            - observed_on: '2026-07-31'
                              bucket_start: '2026-07-31'
                              market: 31782
                              low: 23274
                              high: 36500
                              as_of: '2026-07-31'
                              observations: 1
                        - condition: DMG
                          currency: USD
                          history:
                            - observed_on: '2026-07-31'
                              bucket_start: '2026-07-31'
                              market: 27844
                              low: 20123
                              high: 35000
                              as_of: '2026-07-31'
                              observations: 1
                            - observed_on: '2026-08-05'
                              bucket_start: '2026-08-05'
                              market: 27912
                              low: 20123
                              high: 35000
                              as_of: '2026-08-05'
                              observations: 1
                            - observed_on: '2026-08-17'
                              bucket_start: '2026-08-17'
                              market: 28111
                              low: 20123
                              high: 35000
                              as_of: '2026-08-17'
                              observations: 1
                        - condition: LP
                          currency: USD
                          history:
                            - observed_on: '2026-07-31'
                              bucket_start: '2026-07-31'
                              market: 34531
                              low: 26499
                              high: 39089
                              as_of: '2026-07-31'
                              observations: 1
                            - observed_on: '2026-08-02'
                              bucket_start: '2026-08-02'
                              market: 34486
                              low: 26499
                              high: 39089
                              as_of: '2026-08-02'
                              observations: 1
                            - observed_on: '2026-08-10'
                              bucket_start: '2026-08-10'
                              market: 34202
                              low: 26499
                              high: 37484
                              as_of: '2026-08-10'
                              observations: 1
                            - observed_on: '2026-08-17'
                              bucket_start: '2026-08-17'
                              market: 33870
                              low: 31679
                              high: 37484
                              as_of: '2026-08-17'
                              observations: 1
                            - observed_on: '2026-08-18'
                              bucket_start: '2026-08-18'
                              market: 33786
                              low: 31679
                              high: 37484
                              as_of: '2026-08-18'
                              observations: 1
                        - condition: NM
                          currency: USD
                          history:
                            - observed_on: '2026-07-31'
                              bucket_start: '2026-07-31'
                              market: 36875
                              low: 26307
                              high: 38760
                              as_of: '2026-07-31'
                              observations: 1
                            - observed_on: '2026-08-02'
                              bucket_start: '2026-08-02'
                              market: 36640
                              low: 26307
                              high: 38399
                              as_of: '2026-08-02'
                              observations: 1
                            - observed_on: '2026-08-05'
                              bucket_start: '2026-08-05'
                              market: 36933
                              low: 26307
                              high: 38173
                              as_of: '2026-08-05'
                              observations: 1
                            - observed_on: '2026-08-10'
                              bucket_start: '2026-08-10'
                              market: 37022
                              low: 34999
                              high: 38498
                              as_of: '2026-08-10'
                              observations: 1
                            - observed_on: '2026-08-17'
                              bucket_start: '2026-08-17'
                              market: 36295
                              low: 28052
                              high: 39868
                              as_of: '2026-08-17'
                              observations: 1
                            - observed_on: '2026-08-18'
                              bucket_start: '2026-08-18'
                              market: 36064
                              low: 28052
                              high: 39868
                              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:
    CardPriceHistory:
      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.
        variants:
          type: array
          items:
            type: object
            properties:
              variant:
                type: object
                properties:
                  type:
                    type: string
                    description: >-
                      The printing: `normal`, `holo`, `reverse` and so on. A
                      printing, not a physical dimension. See `size`.
                  subtype:
                    type: string
                    nullable: true
                    description: A narrower printing within `type`, where one exists.
                  size:
                    type: string
                    nullable: true
                    description: >-
                      The physical card size, such as `standard` or `jumbo`. A
                      different axis from `type`: a jumbo card and a holo card
                      are not alternatives.
                  stamps:
                    type: array
                    items:
                      type: string
                    description: >-
                      Promotional stamps printed on this variant, such as a
                      prerelease or staff stamp.
                  foil:
                    type: string
                    nullable: true
                    description: The foil treatment, where the printing carries one.
                required:
                  - type
                  - subtype
                  - size
                  - stamps
                  - foil
              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:
              - variant
              - tcgplayer
      required:
        - from
        - to
        - interval
        - fill
        - variants
    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

````