---
name: metadata-api
description: >
  Public multi-vertical metadata API for anime, manga, games, cartoons, POD blanks,
  TCG cards, figures/Nendoroids, board games, and soundtracks (OST). Use when an agent
  needs series/character data, product blanks, card lookups, figure SKUs, tabletop
  metadata, soundtrack albums, or to report incorrect catalog rows.
---

# Metadata API skill

Open, MIT-licensed metadata API for companion apps and agents.

**Access (not a free plan):** limited **free preview** per IP × catalog (sample quality), then **prepaid credits** on a wallet for full catalog. Discovery (`/v1/health`, `/v1/preview`, `/SKILL.md`, pay routes) stays open. Details: repo `docs/ACCESS.md`.

## Base URL

| Environment | Base |
|-------------|------|
| Production (apex) | `https://metadata.fyi` |
| Production (vertical host) | `https://{vertical}.metadata.fyi` |
| Local | `http://127.0.0.1:8787` |

Always prefer **versioned** routes under `/v1/`.

## Select a vertical

Send one of:

1. Header: `X-Metadata-Vertical: anime` (or `manga`, `lightnovels`, `game`, `cartoons`, `comics`, `pod`, `tcg`, `figures`, `modelkits`, `plush`, `boardgames`, `ost`, `consoles`, `esports`)
2. Host: `anime.metadata.fyi`, `pod.metadata.fyi`, …
3. Query: `?vertical=anime`

Aliases: `blanks`→pod, `cards`/`pokemon`→tcg, `nendoroid`→figures, `gunpla`→modelkits, `ln`→lightnovels, `bgg`→boardgames, `soundtrack`→ost, `nick`→cartoons, `platform`/`arcade`→consoles, `marvel`/`dc`→comics.

**Data shapes:** see repository `docs/SCHEMAS.md` (Series, PodBlank, TcgCard, GameConsole, EsportsPlayer, OstAlbum, ReportPayload, …).

## Discovery endpoints (start here)

```http
GET /llms.txt
GET /SKILL.md
GET /v1/verticals
GET /v1/health
GET /v1/stats
GET /v1/preview
GET /
GET /openapi.json
```

`GET /v1/stats` is free (no wallet) — public **platform** traffic (paths, verticals, status, paid/unpaid mix). No wallet addresses. UI: `/stats.html`. Per-wallet account stats live on `/settings.html` (signed-in).

`GET /v1/preview` reports free-preview remaining for the current IP × vertical (**does not** consume a slot).

## Core patterns by vertical

### Media (anime | manga | game | cartoons)

```http
GET /v1/search?q={query}
GET /v1/series?q=
GET /v1/series/{id}
GET /v1/characters/{id}
```

Anime series may include `seasons[]`. Manga series may include `volumes[]` / `volumeCount`.
Series may list `ostAlbumIds` when soundtrack rows are linked.

### POD / blanks (`pod`)

```http
GET /v1/products?q=3001
GET /v1/products/{id}
GET /v1/print-methods
GET /v1/brands
GET /v1/providers
GET /v1/affiliates?vertical=pod
```

### TCG (`tcg`)

```http
GET /v1/tcg/games
GET /v1/tcg/cards?game=pokemon&q=pikachu
GET /v1/tcg/cards/{id}
```

### Figures (`figures`)

```http
GET /v1/figures/items?kind=nendoroid
GET /v1/figures/items/{id}
GET /v1/figures/makers
GET /v1/figures/lines
```

### Board games (`boardgames`)

```http
GET /v1/boardgames?players=2&q=wingspan
GET /v1/boardgames/{id}
GET /v1/publishers
```

### Soundtracks (`ost`)

```http
GET /v1/ost/albums?media=anime&q=cowboy
GET /v1/ost/albums?series=attack-on-titan
GET /v1/ost/albums/{id}
GET /v1/ost/artists?q=sawano
GET /v1/search?q=persona
```

Albums include `mediaVertical` + `seriesSlug` linking back to anime/game series.

### Consoles (`consoles`) — hardware, **not** nested under `game`

```http
GET /v1/consoles?formFactor=arcade
GET /v1/consoles?generation=9&q=playstation
GET /v1/consoles/{id}
GET /v1/manufacturers
```

### Esports (`esports`)

```http
GET /v1/esports/titles
GET /v1/esports/titles/league-of-legends
GET /v1/esports/leagues?title=dota-2
GET /v1/esports/teams?q=t1
GET /v1/esports/players?q=faker
```

### Comics (`comics`) — western only (use `manga` for manga)

```http
GET /v1/search?q=spider-man
GET /v1/series/batman
GET /v1/characters/batman__bruce-wayne
```

## Flag incorrect data (not a catalog route)

Do **not** invent catalog patches. Humans use the form at `/feedback.html`.
Agents POST JSON to the **same** endpoint:

```http
POST /feedback
Content-Type: application/json
Accept: application/json

{
  "kind": "correction",
  "vertical": "anime",
  "entityKind": "series",
  "entityId": "one-piece",
  "field": "title",
  "message": "Description is truncated / wrong title on slug X",
  "suggestedValue": { "title": "…" },
  "sources": ["https://…"],
  "agent": { "name": "my-agent", "url": "https://…" }
}
```

Kinds: `correction` | `missing` | `spam` | `dmca` | `other`.  
Response `202` with `{ id, persisted: true, status: "queued" }`. Operator queue only — **not** auto-applied.  
`POST /v1/report` is deprecated (alias → same queue).

Suggest new rows:

```http
POST /v1/contribute
Content-Type: application/json

{
  "kind": "character",
  "vertical": "cartoons",
  "payload": { "name": "…", "seriesId": "…" },
  "note": "missing cast member",
  "sources": ["https://…"]
}
```

## Affiliates

```http
GET /v1/affiliates
GET /v1/affiliates?vertical=figures
GET /v1/affiliates?configured=1
```

## Access: preview · credits · x402

Full write-up: repository **`docs/ACCESS.md`**.

### Free preview (teaser — not a free plan)

- Without a funded wallet, catalog routes use a **limited preview** per client IP × vertical (default **8 / 24h**, search pages capped).
- Headers: `X-Metadata-Tier: preview`, `X-Preview-Remaining`, `X-Preview-Limit`.
- Check without consuming: `GET /v1/preview`.
- When exhausted: **402** `PREVIEW_EXHAUSTED` — buy credits for full access.
- Exports never use preview.

### Prepaid credits (full catalog)

- After minting credits, send `X-Wallet-Address: 0x…` on catalog requests. Tier `paid` while **balance &gt; 0**.
- Top up: Reown Pay on `/pricing.html`, or settle USDG then `POST /v1/pay/claim` `{ wallet, usdg|packId, txHash }`. Quote: `GET /v1/pay/quote?usdg=20`. Balance: `GET /v1/pay/balance?wallet=0x…`.
- Stripe: `POST /v1/pay/stripe/checkout` → webhook/sync mints credits. Methods: `GET /v1/pay/methods`.
- **Plain reads** with balance &gt; 0 are rate-limited but **do not debit 1 credit per request**. Export-style routes debit credits (`cost > 0`).
- Service keys (`X-Metadata-Service-Key`) are unlimited first-party access (see `docs/SERVICE-ACCOUNTS.md`).

### x402 ($0.01 / request · Marian)

- When `X402_ENABLED=1`, **402** includes `accepts[]` for **$0.01 USDG** on Robinhood (`eip155:4663`) via **Marian**.
- Retry with **`X-PAYMENT`** (base64 payment payload) → Metadata verify+settle on Marian → this request is served as paid.
- Prepaid credits (Reown/Stripe claim) still unlock full access with `X-Wallet-Address` while balance &gt; 0.
- Requires `TREASURY_ADDRESS` + `X402_FACILITATOR_API_KEY` (Marian merchant key). See `docs/ACCESS.md`.

## Legal

Public-data aggregation; no claim of ownership of third-party IP. See `/legal.html` on the hub. Prefer official / public sources in report `sources`.

## Quick curl

```bash
# Discovery (no credits)
curl -s "$BASE/v1/health" -H "X-Metadata-Vertical: anime"

# Free preview teaser (no wallet; limited per IP×vertical)
curl -s "$BASE/v1/preview" -H "X-Metadata-Vertical: anime"
curl -s "$BASE/v1/search?q=rem" -H "X-Metadata-Vertical: anime"

# Full catalog (funded wallet)
export WALLET=0xYOUR
curl -s "$BASE/v1/search?q=rem" -H "X-Metadata-Vertical: anime" -H "X-Wallet-Address: $WALLET"
curl -s "$BASE/v1/figures/items?kind=nendoroid&limit=5" -H "X-Metadata-Vertical: figures" -H "X-Wallet-Address: $WALLET"
curl -s "$BASE/v1/ost/albums?media=game&q=persona" -H "X-Metadata-Vertical: ost" -H "X-Wallet-Address: $WALLET"

# Feedback form / agents (open)
curl -s -X POST "$BASE/feedback" -H "Content-Type: application/json" -H "Accept: application/json" -d \
  '{"kind":"correction","vertical":"anime","entityKind":"series","entityId":"one-piece","message":"example flag from skill","agent":{"name":"skill"}}'
```

## Source

Open source: Forgejo / git repo for this project. Data under `packages/api/data/`. Human PRs welcome (`CONTRIBUTING.md`).
