# 12. API Endpoints

[< Back to Index](README.md) | [Next: Implementation >](13-implementation.md)

---

All endpoints are under `/v2/` and require bearer token authentication.

## 12.1 Evolution Track Endpoints

```
GET /v2/evolution/tracks
  Query params: card_type, track_family
  Returns: list of evolution_track records with milestones nested

GET /v2/evolution/tracks/{track_id}
  Returns: single track with all milestones

GET /v2/evolution/tracks/{track_id}/milestones
  Returns: all milestones for track, grouped by tier
```

## 12.2 Card State Endpoints

> **Note:** Endpoints accept `card_id` for convenience since the bot always has it available.
> The server resolves `card_id` to `(player_id, team_id)` internally via a single join — no
> extra round trip. Evolution state is keyed by `(player_id, team_id)` in the database.

```
GET /v2/teams/{team_id}/evolutions
  Returns: all evolution_card_state records for team, with nested progress

GET /v2/evolution/cards/{card_id}
  Returns: evolution_card_state for a specific card, with nested progress

POST /v2/evolution/cards/{card_id}/evaluate
  Action: Force re-evaluation of this card's evolution state from player_season_stats
  Use cases: admin correction, cache invalidation after data fix, on-demand status refresh
  Returns: updated evolution_card_state with new current_tier and progress counts
```

## 12.3 Cosmetics Endpoints

```
GET /v2/evolution/cosmetics
  Returns: catalog of available cosmetic types with descriptions and costs

GET /v2/evolution/cards/{card_id}/cosmetics
  Returns: all cosmetics purchased for this card by the requesting team

POST /v2/evolution/cards/{card_id}/cosmetics
  Body: { cosmetic_type, cosmetic_key }
  Validates: card ownership, sufficient wallet balance, cosmetic not already active
  Action: Deducts currency, creates evolution_cosmetic record, triggers variant render
          (static PNG or animated APNG depending on cosmetic type)
  Returns: created cosmetic record + new image_url

DELETE /v2/evolution/cards/{card_id}/cosmetics/{cosmetic_id}
  Action: Deactivates cosmetic (no refund). Cosmetic record preserved for audit.
  Returns: updated cosmetic record
```

## 12.4 Modified Card Endpoints

```
GET /v2/players/{player_id}/battingcard
  New optional query param: variant (integer)
  If variant provided: returns ratings for that variant (used by game engine for evolved cards)
  If not provided: returns variant=0 (base card) as before

GET /v2/players/{player_id}/pitchingcard
  Same modification as battingcard

GET /v2/players/{player_id}/battingcard?variant={hash}&render=true&cosmetics=frame_gold,bg_dark
  Triggers Playwright render with cosmetic CSS applied, uploads to S3, stores URL on
  battingcard.image_url for that variant. If any cosmetic is animated, renders APNG instead of PNG.
  Used by the evolution pipeline, not by the bot at display time.
  Returns: the rendered image (PNG or APNG).
```

## 12.5 Admin Endpoints

```
POST /v2/admin/evolution/tracks
  Body: full evolution_track definition with milestones
  Creates new track (admin only)

PATCH /v2/admin/evolution/milestones/{milestone_id}
  Body: { threshold, description }
  Updates threshold or description (admin only, does not retroactively revoke progress)

POST /v2/admin/evolution/cards/{card_id}/apply-boost
  Action: Manually trigger tier boost application (for recovery from failed boost events)
  Admin only

POST /v2/admin/evolution/cards/{card_id}/initialize
  Action: Create evolution_card_state for a card that was acquired before the system launched
  Admin only; used for backfill of existing card inventory
```
