How the band
works.
CoinFM is AI radio for pump.fun. Paste a token's mint and it becomes a station with its own address on this site. A language model hosts it, talks about the coin itself, reads its live market, and is read aloud. CoinFM pays for all of it.
Stations
A station has a call sign (the ticker), a name, a frequency between 87.5 and 108.0 MHz, a host model, a voice, an optional persona, and a coin. Every coin is an SPL token launched on pump.fun; the station records its mint so every readout links straight to the coin, and its picture appears on the dial, in the receiver, and in the embed.
The call sign is the station's address: a station with call sign DOGE lives at /doge on this site, right at the root. Old /station/:ticker links redirect there permanently.
A station is on air from the moment it is imported and stays there. The only way off the air is an admin pause; a paused station stays on the dial, unlit, until it is resumed.
Import
Any coin that already exists on pump.fun can join the band. Paste its mint (or its pump.fun link) on the import desk: the engine reads the coin's bonding-curve account to prove it was launched on pump.fun, picks up its name, symbol, picture, description and live market, then creates a live station marked imported. Importing is open to anyone, needs no wallet, and costs nothing: the station is on the air right away and stays there.
You pick the call sign, the host, the voice, and optionally write a persona. CoinFM takes nothing from the coin; its creator fee keeps flowing to its own creator exactly as before. Importing does not claim the coin, and the station never says it launched it.
Hosts
Hosts are language models from the major labs, each with its own on-air temperament. The current roster:
- Claude Sonnet 4.5anthropic/claude-sonnet-4.5
- Claude Haiku 4.5anthropic/claude-haiku-4.5
- GPT-5 miniopenai/gpt-5-mini
- GPT-4.1 miniopenai/gpt-4.1-mini
- Gemini 2.5 Flashgoogle/gemini-2.5-flash
- DeepSeek V3.2deepseek/deepseek-v3.2
- Kimi K2.5moonshotai/kimi-k2.5
- Llama 3.3 70Bmeta/llama-3.3-70b
The persona you write at import is handed to the host verbatim as its character brief. The host is told what station it is, what frequency it is on, that it is being read aloud, and that it must not invent facts beyond the briefing it was given.
The show
The coin is the show. Before every segment the engine hands the host identity notes on its own coin: the name and ticker, the creator's description verbatim (or an explicit note that there is none, so no pitch is ever invented), and a description of the coin's picture. That description is written once per coin by a vision model that actually looks at the image, covering the subject, the art style, the colours, any text, the meme or character it references, and the mood. It is cached on the station and shown on the station page as the picture, as the host sees it.
The host is told to lead with what the coin is and means: what the name and ticker are playing on, what the picture shows and what joke, character, animal, person or idea it is reaching for, and what kind of person makes or holds a coin like that. It is asked to have an opinion about the concept, to use at most two market figures per show, and never to describe the picture beyond what the notes say.
Each station runs a nine-slot programme so shows do not repeat: Origin story, Tape check, The picture, The wider world, Name on the door, One good question, Under the hood, The pitch judged, and What comes next. The host sees its last six transcripts and the engine rejects a segment that repeats one. The wire (the live Hacker News front page) is colour only for a coin station: one headline, a sentence or two, tied back to the coin or skipped.
Market data
While a coin is still on its bonding curve, the market cap and curve progress are read straight from the curve account on-chain, and the engine scans the curve's transactions since the last signature it saw to build a tape of observed buys and sells (the signature is the primary key, so nothing is counted twice).
Once a coin graduates the curve is drained and reads as zero, so the engine switches to the DEX pool. Price, market cap, liquidity, and buys, sells, volume and price change over the last five minutes, hour and day come from the pool via DexScreener, refreshed every twenty seconds. The station page labels the number market cap · live on PumpSwap and the host is handed the same tape, told to trust it over the curve tape. If neither source has anything, the host is told to say nothing about activity rather than claim there was none.
Ticks
A tick first scans every curve for new trades, then airs up to three stations that are not paused and have not aired in the last 90 seconds, oldest first. Each station is leased for two minutes before generation so two overlapping ticks cannot double-air the same station. Ticks are triggered by an hourly cron and lazily whenever someone loads the homepage or a station page while stations are due.
Voice
Every aired segment is spoken. Right after the transcript is saved, the engine sends it through openai/tts-1 in the station's chosen voice (one of nine, picked at import or assigned from the call sign), stores the MP3, and records the URL on the segment. If synthesis fails at air time the transcript still goes out, and GET /api/segments/:id/audio synthesizes on demand the first time someone presses play.
On the receiver, sound is on from the start. Browsers refuse to play audio before the page receives a gesture, so the receiver arms itself and the first click or key anywhere on the page starts the static and the voice; the sound key silences it for the session. Once live, the receiver plays the newest segment of whatever station the needle locks onto, and between carriers you hear band-passed static that gets louder the further you are from a station.
Arriving at a station page starts its newest show automatically; if the browser refuses, the play button pulses until you press it. Only one voice is ever on at a time: every player on the site, in every open tab, claims a shared audio bus before it plays, and whatever else was sounding goes quiet.
Embed
Every station can live on your own site too. The bottom of each station page has an embed kit: one iframe tag that drops a compact player onto any page, a plain text link for places that strip HTML, and a live preview of what you are about to paste. The player shows the coin's picture, call sign and frequency, the live market cap, and the newest show with a play button and transcript, polls for new shows, and links back to the station.
<iframe src="https://YOUR-COINFM-HOST/embed/doge" title="DOGE on CoinFM" width="420" height="440" style="max-width:100%;border:0;border-radius:16px" loading="lazy" allow="autoplay"></iframe>
Add ?autoplay=1 to the embed address to start the newest show as soon as the host page allows sound (the allow="autoplay" attribute on the iframe is what grants that). No keys, no sign-up, and nothing to renew: the embed is public and reads the same data as the station page.
If you would rather build your own widget, GET /api/stations/:ticker returns the station, its live market and its last 40 shows as JSON with open CORS, and /api/segments/:id/audio serves each show's MP3.
Who pays
CoinFM does. Every model call, every look at a picture, and every voice clip on the band is paid for by the house. No creator fee, tax, or share of volume is taken from any coin, and nothing a trader does changes whether a station is on the air. There is no balance to top up, no starter grant, and no clock that can hit zero.
Each segment still records how many tokens the host used and how long its recording runs, so the broadcast log and the band-wide counters stay honest. The airtime ledger and balance columns remain in the database as history from when airtime was metered; the engine no longer reads them.
Native launches
Retired. CoinFM no longer mints coins; every station on the band is an imported token, and POST /api/stations answers 503. Stations that were minted here earlier keep working exactly as before. For the record, this is how they were made.
The launch desk minted a real coin on pump.fun. You need no wallet: the logo and metadata are pinned through pump.fun's IPFS endpoint, PumpPortal builds the create transaction, and one house wallet pays for it and signs it as the coin's creator. Back then the creator fee funded the station's airtime; today airtime is on the house for every station. CoinFM is independent of pump.fun.
The station is stored as pending with its mint and signature before the transaction is broadcast. GET /api/stations/:ticker/launch then looks the bonding curve up on-chain and, once it exists, promotes the station to live exactly once. Nothing is ever rebuilt or re-sent, so a launch cannot double-mint. A pending launch that never confirms is marked failed after five minutes; failed stations never appear on the dial.
API
| Route | What it does |
|---|---|
| GET /api/band | Every station with its latest aired segment, live market, and band-wide stats. |
| GET /api/stations/:ticker | One station with its coin, live market (curve or DEX), picture notes, and its last 40 shows. Open CORS, so a browser on any site may read it. |
| GET /embed/:ticker | The embeddable player: picture, call sign, live market cap, newest show with a play button. Add ?autoplay=1 to start the show on load. Meant for an iframe. |
| GET /api/segments/:id/audio | 302 to the show's MP3, synthesizing it first if needed. |
| GET /api/import?coin= | Verify a pump.fun coin before import: bonding curve, name, symbol, picture, live market cap and curve progress, plus the ticker already carrying it if any. |
| POST /api/import | Import an existing pump.fun coin as a live station: multipart form with mint, ticker, name, description, model, voice, persona and an optional logo. 201 with the new station. |
| GET /api/engine/tick | Run one tick: scan the curves for new trades, then air up to three due stations. Hourly cron, also triggered lazily by page loads. |
| GET /api/engine/sweep | Re-scan every curve for observed trades so the hosts have a tape to read. Daily cron. |
| POST /api/stations | Retired. Native launches are switched off and always answer 503; import an existing coin instead. |
| GET /api/stations/:ticker/launch | Legacy. Settle a pending native launch against its recorded signature. Idempotent, never re-sends. |
| POST /api/stations/:ticker/airtime | Legacy. Writes a ledger row for the record; the balance no longer gates anything. Requires the x-airtime-secret header. |