# Slopify Station API — draft specification (v0)

> **STATUS: IN PROGRESS — NOTHING BELOW IS LIVE YET.**
> This is the plan we are building toward, published early so agents and vibe
> coders can design against it and tell us what's wrong with it. Endpoints,
> shapes, and names WILL change. The only API that exists today is the read-only
> jukebox described at the bottom. Watch this file — it's the changelog.

## The idea

Anyone gets an API key and creates their own **station**: a named host with a
personality, a voice, a musical lean, and a vault of everything it generates.
Stations broadcast into Discord (today's mode) or stream over plain HTTP for
terminals and web players (planned). The best generated tracks get published to
a public **market** where anyone can browse, play, and remix the ridiculousness.

Two audiences, one API:

- **Gaming crews** — create a station, attach it to a Discord server, done.
- **Vibe coders** — create a station, tune it from a TUI while you ship, publish
  its bangers to the market, jam to everyone else's.

## Concepts

| thing | what it is |
|---|---|
| **Station** | persona + dials + voice + keys. Owns a vault. Has a public page at `slopify.live/stations/:slug` |
| **Host** | the station's DJ: name, personality prompt, ElevenLabs voice |
| **Broadcast** | a live session — into a Discord voice channel, or (planned) an HTTP audio stream |
| **Transmission** | one generated artifact (song, ad, ident) saved to the station's vault |
| **Market** | the public feed of published transmissions, ranked by plays and 🔥 |

## Auth (draft)

- API keys: `Authorization: Bearer slp_live_...`, issued per account.
- **BYOK stays the law.** Your station generates on *your* ElevenLabs/OpenRouter
  keys, attached to the station at create time (stored encrypted, never returned
  by the API). Slopify keys authenticate *you*; they never pay for generation.
- Market playback is served from cached renders — playing other people's slop
  costs nobody any generation credits.

## Endpoints (draft)

```
POST   /v1/stations                  create a station
  { name, slug, host: { name, personality, voice_id },
    dials: { energy, darkness, absurdity, sincerity, themes },
    genre_lean, byok: { elevenlabs_key, openrouter_key } }
  → { station_id, slug, page_url }

GET    /v1/stations/:id              station + dials + stats
PATCH  /v1/stations/:id              tune dials / persona / voice
DELETE /v1/stations/:id              off the air, forever

POST   /v1/stations/:id/attach      attach to a Discord guild (bot must be invited)
POST   /v1/stations/:id/broadcasts  (planned) start a headless HTTP stream broadcast
GET    /v1/stations/:id/events      SSE: now-playing, call-ins, listener counts

GET    /v1/stations/:id/transmissions   the station's vault
POST   /v1/transmissions/:id/publish    push a transmission to the market
GET    /v1/market                        browse: ?sort=hot|new|plays&genre=...
```

## The TUI (planned)

```
npx slopify tune interdimensional-radio   # play a station in your terminal
npx slopify steer "more synthwave"        # steer it without leaving the shell
npx slopify callin "big deploy energy"    # you're on the air
```

## Rollout phases

1. **Now** — read-only jukebox (live today, stable to build against):
   `GET /api/tracks` → `[{ id, title, plays, duration, src, cover }]`,
   `GET /tracks/:id.mp3` (HTTP range supported), `GET /covers/:id.png`.
2. **Keys + station create** — `POST /v1/stations` with BYOK, attach to Discord.
3. **Streams + TUI** — headless broadcasts over HTTP audio, `npx slopify`.
4. **The market** — publishing, charts, per-station public pages for everyone.

## What we want from you (yes, you, the agent reading this)

If you're designing an integration against this draft: the shapes above are
negotiable, the BYOK principle and the read-only endpoints in phase 1 are not.
Build against phase 1 today; treat everything else as a preview. Feedback:
`/callin` on station 001 and yell about it — call-ins are persisted, and the
humans read the logs.

*Last updated: 2026-07-15 · draft v0 · in progress — really.*
