Authenticate by passing your license key as a query parameter.
Channels
Channel
Description
/feed
All announcements from all sources (unfiltered)
/listings
Only listing-related announcements (filtered by keyword rules)
The /listings channel forwards only listing-related events: new spot/futures listings, delistings, launchpool/launchpad/megadrop, pre-market launches, and KRW/BTC market additions. Maintenance, airdrops, trading pair updates, and other non-listing announcements are filtered out.
Filtering is keyword-based. If an exchange changes their announcement format, some listings may not pass through until the filter is updated. For maximum reliability, use +/feed and apply your own filtering logic. Message format is identical on both channels.
Messages
Connection Confirmation
Sent immediately after successful authentication. Contains sent_time for measuring initial latency.
import asyncio, json, logging, time, websockets
from datetime import datetime, timezone
logging.basicConfig(level=logging.INFO, format="%(asctime)s.%(msecs)03d UTC | %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
logging.Formatter.converter = time.gmtime
log = logging.getLogger(__name__)
API_KEY = "YOUR_API_KEY"
URL = f"ws://tokyo.coinlisting.pro:8765/feed?key={API_KEY}"
async def listen():
async for ws in websockets.connect(URL):
try:
async for msg in ws:
data = json.loads(msg)
if data.get("type") == "connection":
expiry = datetime.strptime(data["expiry"], "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
remaining = expiry - datetime.now(timezone.utc)
days, hours = remaining.days, remaining.seconds // 3600
log.info(f"Connected as {data['username']} | expires in {days}d {hours}h")
t0 = time.time()
await ws.send(json.dumps({"type": "ping"}))
elif data.get("type") == "pong":
log.info(f"Connection latency: ~{(time.time() - t0) * 500:.0f}ms")
else:
log.info(data)
except websockets.ConnectionClosedError as e:
if e.code == 1008:
log.error(f"Auth error: {e.reason}")
return
log.warning(f"Disconnected ({e.code}), reconnecting...")
if __name__ == "__main__":
try:
asyncio.run(listen())
except KeyboardInterrupt:
log.info("Stopped")
2026-02-02 15:03:42.198 UTC | Connected as demo | expires in 332d 8h
2026-02-02 15:03:42.264 UTC | Connection latency: ~33ms
2026-02-02 15:03:43.571 | {'source': 'BINANCE', 'title': 'Binance Will List Example Token (EXT)', 'url': 'https://www.binance.com/en/support/announcement/...', 'sent_time': 1770044623571, 'sent_time_iso': '2026-02-02T15:03:43.571000+00:00'}
2026-02-02 15:03:43.707 | {'source': 'COINBASE', 'title': 'Spot trading for Zama (ZAMA) will go live on 2 February 2026.', 'url': 'https://x.com/CoinbaseMarkets/status/2018339552952307904', 'sent_time': 1770044623707, 'sent_time_iso': '2026-02-02T15:03:43.707000+00:00', 'twitter_user': 'CoinbaseMarkets', 'twitter_id': '2018339552952307904'}