# Current prices of a sealed product

> The live price series of one sealed product, in the same shape as the card route.

- **Endpoint**: `GET /v1/sealed/{id}/prices`
- **Cost**: 2 credits
- **Minimum plan**: free
- **Cache-Control**: `public, max-age=300`

Source: https://pokemontcgapi.com/docs/api/prices/current-sealed

Same envelope as `/v1/cards/{id}/prices` — `index`, `quotes`, `meta.plan_notes` — so one client handles both. The differences are what a sealed product does not have: `condition`, `printing` and `grading` are always null, and `locale` is the language the box was printed in. `index` is null today: the composite is computed for cards only, and the euro figure on the product, `index_eur`, is the catalogue price.

Observations come from Cardmarket (lowest, 1/7/30-day averages and trend, per printing language, back to November 2024), TCGplayer and community submissions, under the same allow-list and 24-hour delay as cards. This sample shows four of the 7 rows the product carries. `GET /v1/sealed/{id}` carries `index_eur` and `last_price_at` if all you need is one number.

## Path parameters

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `id` **required** | string | — | The `sku` or the `slug` of the product, as on `/v1/sealed/{id}`. |

## Query parameters

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `source` | string | — | Keep only rows from one source, as listed by `GET /v1/prices/sources`. A card can carry over a hundred rows once graded medians are included, so this is usually the difference between a response you parse and one you filter. An unknown value is `INVALID_PARAMETER` with the valid list in `details`, never a silently unfiltered page. |
| `variant` | string | — | Keep only one variant: `LOW`, `MARKET`, `TREND`, `AVG_1D`, `AVG_7D`, `AVG_30D`, `MEDIAN_GRADED`, `INDEX`. |
| `locale` | string | — | Keep only rows for one printing language. Rows that do not state a language are excluded rather than assumed to match. |

## Headers

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `X-Api-Key` **required** | string | — | Your API key. `Authorization: Bearer <key>` is accepted as an alias. |
| `If-None-Match` | string | — | Send back the `ETag` you stored. The API returns a strong ETag on every catalogue response, and a 304 is a header exchange: no body, no database row read. |

## Example request

**curl**

```bash
curl -s "https://api.pokemontcgapi.com/v1/sealed/evolving-skies-booster-box/prices" \
  -H "X-Api-Key: $PTCG_API_KEY"
```

**TypeScript**

`request.ts`

```ts
const url = new URL("https://api.pokemontcgapi.com/v1/sealed/evolving-skies-booster-box/prices");

const res = await fetch(url, {
  headers: { "X-Api-Key": process.env.PTCG_API_KEY ?? "" },
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`${error.code}: ${error.message} (${error.request_id})`);
}

const { data, meta } = await res.json();
```

**Python**

`request.py`

```python
import os, httpx

res = httpx.get(
    "https://api.pokemontcgapi.com/v1/sealed/evolving-skies-booster-box/prices",
    headers={"X-Api-Key": os.environ["PTCG_API_KEY"]},
)
res.raise_for_status()
payload = res.json()
```

## Example response

`200 OK` · `Cache-Control: public, max-age=300`

`response.json`

```json
{
  "data": {
    "sealed_id": "evolving-skies-booster-box",
    "index": null,
    "quotes": [
      {
        "source": "CARDMARKET",
        "variant": "LOW",
        "basis": "ASKING",
        "amount": 2175,
        "currency": "EUR",
        "locale": "en",
        "condition": null,
        "printing": null,
        "grading": null,
        "as_of": "2026-09-01",
        "sample_n": null,
        "provenance": "Cardmarket"
      },
      {
        "source": "CARDMARKET",
        "variant": "LOW",
        "basis": "ASKING",
        "amount": 1349,
        "currency": "EUR",
        "locale": "fr",
        "condition": null,
        "printing": null,
        "grading": null,
        "as_of": "2026-09-01",
        "sample_n": null,
        "provenance": "Cardmarket"
      },
      {
        "source": "CARDMARKET",
        "variant": "LOW",
        "basis": "ASKING",
        "amount": 1240,
        "currency": "EUR",
        "locale": "de",
        "condition": null,
        "printing": null,
        "grading": null,
        "as_of": "2026-09-01",
        "sample_n": null,
        "provenance": "Cardmarket"
      },
      {
        "source": "CARDMARKET",
        "variant": "LOW",
        "basis": "ASKING",
        "amount": 1000,
        "currency": "EUR",
        "locale": "es",
        "condition": null,
        "printing": null,
        "grading": null,
        "as_of": "2026-09-01",
        "sample_n": null,
        "provenance": "Cardmarket"
      }
    ]
  },
  "meta": {
    "quotes": 4,
    "delayed_hours": 0
  }
}
```

## Errors

Every error body carries `error.code`, `error.message` and `error.request_id`. Switch on the code, never on the message.

| Status | Code | When |
| --- | --- | --- |
| 401 | `MISSING_API_KEY` | No `X-Api-Key` header and no bearer token on a route that requires one. |
| 401 | `INVALID_API_KEY` | The key does not match any account. |

The full taxonomy, with what to do about each code, is on the [errors](https://pokemontcgapi.com/docs/errors) page.
