# Service status

> Catalogue counts, the age of each ingest job and whether the upstream contract still holds — the numbers this site quotes, straight from the service.

- **Endpoint**: `GET /v1/status`
- **Cost**: free, no key needed
- **Minimum plan**: free
- **Cache-Control**: `public, max-age=60`

Source: https://pokemontcgapi.com/docs/api/status/get

No key yet? One call gets you one: `POST /v1/accounts/free` with an `Idempotency-Key` header and your email address returns a working key in the response. Keep the original Idempotency-Key and body for response replay for up to 24 hours, under the conditions in the quickstart. The trial is 800 credits over 30 days once the address is confirmed, no card; paid plans start at 29 € a month. See the [quickstart](https://pokemontcgapi.com/docs/quickstart) and the [pricing](https://pokemontcgapi.com/pricing).

`catalog` is what the database holds right now; every count on this site is read from here at build time and names this endpoint. `sources` lists the three ingest jobs — catalogue sync, price refresh, index rebuild — with the timestamp of the last success and its age in hours, so the freshness of what you read is one request away instead of a claim on a marketing page.

`upstream.contract_ok` says whether the read contract against the source database still compiles. If it ever turns false the catalogue keeps serving from its last good state, and the error text says which source broke. For a bare liveness probe use `GET /v1/health`, which answers `{ "status": "ok", "db": true }` and nothing else.

## Example request

**curl**

```bash
curl -s "https://api.pokemontcgapi.com/v1/status" \
  -H "X-Api-Key: $PTCG_API_KEY"
```

**TypeScript**

`request.ts`

```ts
const url = new URL("https://api.pokemontcgapi.com/v1/status");

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/status",
    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=60`

`response.json`

```json
{
  "status": "ok",
  "catalog": {
    "sets": 651,
    "cards": 57450,
    "sealed": 2091,
    "artists": 402
  },
  "sources": [
    {
      "source": "refresh-catalog",
      "last_success_at": "2026-09-02T22:21:28.703Z",
      "age_hours": 0.9,
      "state": "fresh"
    },
    {
      "source": "refresh-index",
      "last_success_at": "2026-09-02T23:09:52.114Z",
      "age_hours": 0.1,
      "state": "fresh"
    },
    {
      "source": "refresh-prices",
      "last_success_at": "2026-09-02T23:07:22.204Z",
      "age_hours": 0.1,
      "state": "fresh"
    }
  ],
  "upstream": {
    "contract_ok": true,
    "error": null
  },
  "version": "dev"
}
```
