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

# Events

> What each event means, when it fires, and the records it carries.

Names are `<game>.<entity>.<action>`. The `pokemon.` prefix leaves room for another game without
renaming anything you have already built against.

Every record shape below is the **same shape `/v1` already serves** for that entity — a card in
`pokemon.cards.updated` is exactly what `GET /v1/cards/{id}` returns inside its `data`, and so on.
One definition, two transports: a webhook payload can never drift from what the REST API would
tell you about the same row.

A delivery carries these records directly. The `{ data, error }` envelope belongs to a `/v1`
read, not to a delivery — nothing below is wrapped in it.

A group that changed more than 500 records in one run arrives split across several deliveries, each
carrying a `chunk: { index, of }` field alongside the records — see
[the delivery body](/webhooks/overview#the-delivery-body). A smaller group carries no `chunk` key
at all.

## Cards

### `pokemon.cards.updated`

**Card details changed** — a card's own data moved: a new card appeared, or an existing one's
name, rarity, illustrator, category, metadata or variants changed.

```json theme={null}
{
  "id": "evt_2f8a1c9b4e7d4a3f8c1b6e2d9a0f4c7b",
  "name": "pokemon.cards.updated",
  "created_at": "2026-07-31T03:58:41.006Z",
  "data": {
    "cards": [
      {
        "id": "sv08-238",
        "expansion_id": "sv08",
        "number": "238",
        "name": "Pikachu ex",
        "rarity": "Special illustration rare",
        "illustrator": "GIDORA",
        "image": {
          "low": "https://assets.cromos.so/cards/sv08-238/low.webp",
          "high": "https://assets.cromos.so/cards/sv08-238/high.webp"
        },
        "category": "Pokemon",
        "metadata": {
          "hp": 200,
          "types": ["Lightning"],
          "pokedex_numbers": [25],
          "stage": "Basic",
          "evolve_from": null,
          "description": null,
          "effect": null,
          "trainer_type": null,
          "energy_type": null,
          "retreat": 1,
          "abilities": [
            {
              "kind": "ability",
              "name": "Resolute Heart",
              "text": "If this Pokémon has full HP and would be Knocked Out by damage from an attack, it is not Knocked Out, and its remaining HP becomes 10."
            }
          ],
          "attacks": [
            {
              "name": "Topaz Bolt",
              "cost": ["Grass", "Lightning", "Metal"],
              "damage": "300",
              "text": "Discard 3 Energy from this Pokémon."
            }
          ],
          "weaknesses": [{ "type": "Fighting", "modifier": "x2" }],
          "resistances": null,
          "legality": { "expanded": true, "standard": true }
        },
        "variants": [
          {
            "type": "holo",
            "subtype": null,
            "size": "standard",
            "stamps": [],
            "foil": null,
            "tcgplayer": [
              {
                "condition": "NM",
                "currency": "USD",
                "market": 32497,
                "low": 28899,
                "high": 42599,
                "observed_on": "2026-07-31"
              },
              {
                "condition": "LP",
                "currency": "USD",
                "market": 27591,
                "low": 23304,
                "high": 32190,
                "observed_on": "2026-07-31"
              },
              {
                "condition": "MP",
                "currency": "USD",
                "market": 22000,
                "low": 22000,
                "high": 22000,
                "observed_on": "2026-07-31"
              },
              {
                "condition": "HP",
                "currency": "USD",
                "market": 22499,
                "low": 22499,
                "high": 22499,
                "observed_on": "2026-07-31"
              },
              {
                "condition": "DMG",
                "currency": "USD",
                "market": 21894,
                "low": 21500,
                "high": 22681,
                "observed_on": "2026-07-31"
              }
            ],
            "cardmarket": {
              "price_kind": "plain",
              "currency": "EUR",
              "observed_on": "2026-08-03",
              "avg": 33173,
              "low": 17500,
              "trend": 34316,
              "avg_holo": null,
              "low_holo": null,
              "trend_holo": 0
            }
          }
        ]
      }
    ]
  }
}
```

### `pokemon.cards.deleted`

**A card was removed.** Ingest never deletes a card today — a payload that comes back empty is
treated as an upstream outage, not a deletion — so this event has no producer yet. It stays in the
catalogue so a mirror already knows how to handle a card deletion the day one becomes possible,
rather than that being a docs change, a console change and your own deploy all at once.

```json theme={null}
{
  "id": "evt_4c1a7f9b2e6d3a8f1c5b9e2d4a7f8c3b",
  "name": "pokemon.cards.deleted",
  "created_at": "2026-07-31T03:58:41.006Z",
  "data": { "card_ids": ["sv08-999"] }
}
```

## Card variants

### `pokemon.card_variants.deleted`

**A card printing was removed** — one or more `card_variants` rows were pruned because the
printing they described no longer exists upstream. `variant_ids` are those variants' own numeric
ids; the card itself is not necessarily deleted, only that printing of it.

```json theme={null}
{
  "id": "evt_9a3f6c1e8d2b4a7f9c1e6d3a8f2b5c7d",
  "name": "pokemon.card_variants.deleted",
  "created_at": "2026-07-31T03:58:41.006Z",
  "data": { "variant_ids": [48212, 48214] }
}
```

## Card prices

### `pokemon.card_prices.updated`

**Card prices changed** — new current prices for one or more cards, all in the one currency named
by `data.currency`. Subscribe to this once and filter on `currency` rather than needing separate
subscriptions per currency.

USD rows carry the TCGplayer columns:

```json theme={null}
{
  "id": "evt_7b3e9d1a2c4f4b8e9a6d3c1f5b2e8a4d",
  "name": "pokemon.card_prices.updated",
  "created_at": "2026-07-31T04:02:11.184Z",
  "data": {
    "currency": "USD",
    "cards": [
      {
        "card_id": "sv08-238",
        "prices": [
          {
            "variant": "Holofoil",
            "condition": "NM",
            "currency": "USD",
            "market": 32497,
            "low": 28899,
            "high": 42599
          },
          {
            "variant": "Holofoil",
            "condition": "LP",
            "currency": "USD",
            "market": 27591,
            "low": 23304,
            "high": 32190
          },
          {
            "variant": "Holofoil",
            "condition": "MP",
            "currency": "USD",
            "market": 22000,
            "low": 22000,
            "high": 22000
          },
          {
            "variant": "Holofoil",
            "condition": "HP",
            "currency": "USD",
            "market": 22499,
            "low": 22499,
            "high": 22499
          },
          {
            "variant": "Holofoil",
            "condition": "DMG",
            "currency": "USD",
            "market": 21894,
            "low": 21500,
            "high": 22681
          }
        ]
      }
    ]
  }
}
```

EUR rows carry the Cardmarket columns instead, keyed by `price_kind` rather than `condition`:

```json theme={null}
{
  "variant": "holo",
  "currency": "EUR",
  "price_kind": "plain",
  "avg": 33173,
  "low": 17500,
  "trend": 34316,
  "avg_holo": null,
  "low_holo": null,
  "trend_holo": 0
}
```

A card with nothing priced in the named currency is left out of `cards` entirely rather than
listed with an empty `prices` array.

## Sealed products

### `pokemon.products.updated`

**Sealed product details changed** — a booster box, ETB, collection or similar changed: its name,
number, image, the expansions it belongs to, or its current prices.

This product carries no Cardmarket link today, so `cardmarket` is `null` rather than an object —
the same nullability `/v1/products/{id}` returns for any product with no Cardmarket id on file.

```json theme={null}
{
  "id": "evt_5a2f7c1e8d3b4a9f6c2e1d8b3a7f4c9e",
  "name": "pokemon.products.updated",
  "created_at": "2026-07-31T03:59:12.301Z",
  "data": {
    "products": [
      {
        "id": 476452,
        "name": "Scarlet & Violet Booster Box",
        "clean_name": "Scarlet and Violet Booster Box",
        "number": null,
        "image": {
          "low": "https://assets.cromos.so/products/476452/low.webp",
          "high": "https://assets.cromos.so/products/476452/high.webp"
        },
        "tcgplayer_url": "https://www.tcgplayer.com/product/476452/pokemon-sv01-scarlet-and-violet-base-set-scarlet-and-violet-booster-box",
        "expansions": [{ "id": "sv01", "name": "Scarlet & Violet" }],
        "tcgplayer": [
          {
            "condition": "NM",
            "variant": "Normal",
            "currency": "USD",
            "market": 31101,
            "low": 29999,
            "high": 31698,
            "observed_on": "2026-07-31"
          }
        ],
        "cardmarket": null
      }
    ]
  }
}
```

### `pokemon.products.removed`

**A sealed product was removed** — pruned from the catalogue, or detached from every expansion it
was listed under. `product_ids` are those products' own numeric ids.

```json theme={null}
{
  "id": "evt_1e4b7a2f9c6d3e8a1b4f7c2e9a6d3b8f",
  "name": "pokemon.products.removed",
  "created_at": "2026-07-31T03:59:12.301Z",
  "data": { "product_ids": [476452, 502001] }
}
```

## Sealed product prices

### `pokemon.product_prices.updated`

**Sealed product prices changed** — the same currency-filtered shape as `card_prices.updated`, one
`product_id` and its priced rows per entry.

```json theme={null}
{
  "id": "evt_8c2f5a1e7d4b3a9f6c1e8d2b5a7f4c9e",
  "name": "pokemon.product_prices.updated",
  "created_at": "2026-07-31T04:03:47.552Z",
  "data": {
    "currency": "USD",
    "products": [
      {
        "product_id": 476452,
        "prices": [
          {
            "variant": "Normal",
            "condition": "NM",
            "currency": "USD",
            "market": 31101,
            "low": 29999,
            "high": 31698
          }
        ]
      }
    ]
  }
}
```

A sealed product has one Cardmarket identity rather than a printing to discriminate, so its EUR
rows carry no `price_kind` (a different product from the one above — product `502001`, "151
Poster Collection" — since `476452` carries no Cardmarket link to show one):

```json theme={null}
{
  "currency": "EUR",
  "avg": 7091,
  "low": 4299,
  "trend": 6999,
  "avg_holo": null,
  "low_holo": null,
  "trend_holo": 0
}
```

## Expansions

### `pokemon.expansions.created`

**A new expansion appeared** — one we had never seen is now in the catalogue. It usually arrives
sparse, named and dated, with cards landing over the following days — treat it as "start
watching", not "fetch everything now".

```json theme={null}
{
  "id": "evt_3c9f2b8e1d4a7c5f9b3e2a6d1c8f4b7e",
  "name": "pokemon.expansions.created",
  "created_at": "2026-07-31T03:57:02.884Z",
  "data": {
    "expansions": [
      {
        "id": "sv10",
        "series_id": "sv",
        "name": "Destined Rivals",
        "logo": {
          "low": "https://assets.cromos.so/expansions/sv10/logo/low.webp",
          "high": "https://assets.cromos.so/expansions/sv10/logo/high.webp"
        },
        "symbol": "https://assets.cromos.so/expansions/sv10/symbol/image.webp",
        "release_date": "2025-05-30",
        "card_count_total": 244,
        "card_count_official": 182,
        "legal_standard": false,
        "legal_expanded": true
      }
    ]
  }
}
```

### `pokemon.expansions.updated`

**Expansion details changed** — an expansion's own name, series, logo, symbol or legality was
corrected. Nothing about its cards or prices changes here; those arrive as their own events.

```json theme={null}
{
  "id": "evt_5d2a9f1c7b4e8a3f6c1d9b2e4a7f8c3d",
  "name": "pokemon.expansions.updated",
  "created_at": "2026-07-31T03:57:02.884Z",
  "data": {
    "expansions": [
      {
        "id": "sv08",
        "series_id": "sv",
        "name": "Surging Sparks",
        "logo": {
          "low": "https://assets.cromos.so/expansions/sv08/logo/low.webp",
          "high": "https://assets.cromos.so/expansions/sv08/logo/high.webp"
        },
        "symbol": null,
        "release_date": "2024-11-08",
        "card_count_total": 252,
        "card_count_official": 191,
        "legal_standard": false,
        "legal_expanded": true
      }
    ]
  }
}
```

## Series

### `pokemon.series.created`

**A new series appeared.**

The `sv` series actually carries 19 expansions; trimmed to the first three below (still in
release-date order) to keep the example short.

```json theme={null}
{
  "id": "evt_8f1e4c7a3b9d2e6f1a4c8b3e7d2a9f5c",
  "name": "pokemon.series.created",
  "created_at": "2026-07-31T03:56:18.442Z",
  "data": {
    "series": [
      {
        "id": "sv",
        "name": "Scarlet & Violet",
        "logo": {
          "low": "https://assets.cromos.so/series/sv/logo/low.webp",
          "high": "https://assets.cromos.so/series/sv/logo/high.webp"
        },
        "expansions": [
          {
            "id": "sv01",
            "name": "Scarlet & Violet",
            "logo": {
              "low": "https://assets.cromos.so/series/sv/logo/low.webp",
              "high": "https://assets.cromos.so/series/sv/logo/high.webp"
            },
            "symbol": "https://assets.cromos.so/expansions/sv01/symbol/image.webp",
            "release_date": "2023-03-31",
            "card_count_total": 258
          },
          {
            "id": "sve",
            "name": "Scarlet & Violet Energy",
            "logo": null,
            "symbol": null,
            "release_date": "2023-03-31",
            "card_count_total": 24
          },
          {
            "id": "svp",
            "name": "SVP Black Star Promos",
            "logo": null,
            "symbol": null,
            "release_date": "2023-03-31",
            "card_count_total": 226
          }
        ]
      }
    ]
  }
}
```

### `pokemon.series.updated`

**Series details changed** — a series' own name or logo was corrected.

Trimmed the same way as above: the first three of `sv`'s 19 expansions, in release-date order.

```json theme={null}
{
  "id": "evt_6b9d2a7f4c1e8b3a6d9f2c5e8b1a4d7f",
  "name": "pokemon.series.updated",
  "created_at": "2026-07-31T03:56:18.442Z",
  "data": {
    "series": [
      {
        "id": "sv",
        "name": "Scarlet & Violet",
        "logo": {
          "low": "https://assets.cromos.so/series/sv/logo/low.webp",
          "high": "https://assets.cromos.so/series/sv/logo/high.webp"
        },
        "expansions": [
          {
            "id": "sv01",
            "name": "Scarlet & Violet",
            "logo": {
              "low": "https://assets.cromos.so/series/sv/logo/low.webp",
              "high": "https://assets.cromos.so/series/sv/logo/high.webp"
            },
            "symbol": "https://assets.cromos.so/expansions/sv01/symbol/image.webp",
            "release_date": "2023-03-31",
            "card_count_total": 258
          },
          {
            "id": "sve",
            "name": "Scarlet & Violet Energy",
            "logo": null,
            "symbol": null,
            "release_date": "2023-03-31",
            "card_count_total": 24
          },
          {
            "id": "svp",
            "name": "SVP Black Star Promos",
            "logo": null,
            "symbol": null,
            "release_date": "2023-03-31",
            "card_count_total": 226
          }
        ]
      }
    ]
  }
}
```
