tokens:live
A single stream of token lifecycle events across every mint. Subscribe once, then dispatch on each message's type field.
tokens:live
lifecycle events for every token
Event types
| type | When | Data |
|---|---|---|
token_created | Token is deployed on chain. | {mint, symbol, name, deployed_at, launchpad, image_uri} |
token_graduated | Migrates to Raydium/PumpSwap. | {mint, symbol, name, migrated_at, mcap} |
token_dex_paid | DexScreener paid order confirmed. | {mint, symbol, name, dex_paid_at} |
token_metadata_retrieved | IPFS/Arweave metadata merged. | {mint, symbol, name, image_uri, description, twitter, telegram, website} |
token_duplication_status_updated | Any duplication flag flipped. | {mint, symbol, name, duplication: { ... }} |
Wire frame
[null,null,"tokens:live","token_event",{
"type": "token_graduated",
"data": {
"mint": "BgNrWZK...",
"symbol": "SMP",
"name": "Sample Token",
"migrated_at": "2026-07-11T13:00:00Z",
"mcap": 42000
}
}]
Connect (terminal)
export API_KEY=sk_live_yourkeyhere
{
printf '["1","1","tokens:live","phx_join",{}]\n'
n=2
while sleep 25; do
printf '[null,"%s","phoenix","heartbeat",{}]\n' "$n"
n=$((n+1))
done
} | websocat "wss://api.cookin.fun/socket/websocket?vsn=2.0.0&api_key=$API_KEY"
Requires websocat. The block sends the join frame + a heartbeat every 25s so Phoenix doesn't drop the connection.
Connect (Node.js)
const WebSocket = require("ws");
const API_KEY = process.env.API_KEY;
const url = `wss://api.cookin.fun/socket/websocket?vsn=2.0.0&api_key=${API_KEY}`;
const ws = new WebSocket(url);
ws.on("open", () => {
// Join tokens:live (ref="1", join_ref="1").
ws.send(JSON.stringify(["1", "1", "tokens:live", "phx_join", {}]));
// Heartbeat every 25s so Phoenix doesn't drop us.
let n = 2;
setInterval(() => {
ws.send(JSON.stringify([null, String(n++), "phoenix", "heartbeat", {}]));
}, 25_000);
});
ws.on("message", (buf) => {
const [joinRef, ref, topic, event, payload] = JSON.parse(buf);
if (event === "token_event") console.log("token:", payload.type, payload.data);
if (event === "frame") console.log("frame:", payload.data.signature);
});
Connect (Python)
import asyncio, json, os, websockets
API_KEY = os.environ["API_KEY"]
URL = f"wss://api.cookin.fun/socket/websocket?vsn=2.0.0&api_key={API_KEY}"
async def run():
async with websockets.connect(URL) as ws:
# Join tokens:live.
await ws.send(json.dumps(["1", "1", "tokens:live", "phx_join", {}]))
# Heartbeat every 25s so Phoenix doesn't drop us.
async def heartbeat():
n = 2
while True:
await asyncio.sleep(25)
await ws.send(json.dumps([None, str(n), "phoenix", "heartbeat", {}]))
n += 1
asyncio.create_task(heartbeat())
async for msg in ws:
_joinRef, _ref, _topic, event, payload = json.loads(msg)
if event == "token_event":
print("token:", payload["type"], payload["data"])
elif event == "frame":
print("frame:", payload["data"]["signature"])
asyncio.run(run())
Wire protocol details on the frames:live page (join / reply / heartbeat frames are identical across channels).