PKCryptolisting WebSocket
Entegrasyon Kılavuzu

Sadece birkaç satır kodla Upbit, Bithumb, Binance ve Bybit'ten gerçek zamanlı duyurular alabilirsiniz.
Telegram bot'undan API anahtarınızı alın ve aşağıdaki kılavuzu izleyerek bağlanın.

ENDPOINT · KR
wss://kr.pkcryptolisting.com
Yalnızca Upbit · Bithumb
ENDPOINT · TOKYO
wss://tokyo.pkcryptolisting.com
Upbit · Bithumb · Binance · Bybit
PROTOCOL
WebSocket Secure (WSS)
AUTH
API Key (Telegram üzerinden alın)
SERVER LOCATION
AWS Seoul (ap-northeast-2) / AWS Tokyo (ap-northeast-1)
1. Bağlantı ve Kimlik Doğrulama
WebSocket bağlantısı kurulduktan hemen sonra bir kimlik doğrulama mesajı gönderilmelidir. 5 saniye içinde kimlik doğrulanmazsa otomatik olarak sonlandırılırbağlantı otomatik olarak sonlandırılır
Yalnızca belirli bir borsanın duyurularını almak için exchange alanı ekleyin.
⚠️ Notlar
wss://kr.pkcryptolisting.com(Korea) uç noktası yalnızca UPBIT · BITHUMB destekler.
wss://tokyo.pkcryptolisting.com(Tokyo) uç noktası UPBIT · BITHUMB · BINANCE · BYBIT dahil tüm borsaları destekler.
pip install websockets
npm install ws
go get github.com/gorilla/websocket
[dependencies]
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = { version = "0.21", features = ["native-tls"] }
futures-util = "0.3"
serde_json = "1"
url = "2"
import asyncio, json, websockets

async def connect():
    async with websockets.connect("wss://kr.pkcryptolisting.com") as ws: # or wss://tokyo.pkcryptolisting.com for all 4 exchanges 

        # send auth message
        await ws.send(json.dumps({
            "type":     "auth",
            "key":      "YOUR_API_KEY",   # issued via Telegram bot
            # "exchange": "Upbit"  # optional: "Upbit" | "Bithumb" (omit for all)
        }))

asyncio.run(connect())
// npm install ws
const WebSocket = require("ws");
const ws = new WebSocket("wss://kr.pkcryptolisting.com"); // or wss://tokyo.pkcryptolisting.com for all 4 exchanges 
ws.on("open", () => {
  // send auth message
  ws.send(JSON.stringify({ type: "auth", key: "YOUR_API_KEY",   // issued via Telegram bot
    // exchange: "Upbit"  // optional: "Upbit" | "Bithumb" (omit for all)
  }));
});
// go get github.com/gorilla/websocket
conn, _, _ := websocket.DefaultDialer.Dial("wss://kr.pkcryptolisting.com", nil) 
 // or wss://tokyo.pkcryptolisting.com for all 4 exchanges 
// send auth message
auth, _ := json.Marshal(map[string]string{"type": "auth", "key": "YOUR_API_KEY"})
// "exchange": "Upbit"  // optional: "Upbit" | "Bithumb" (omit for all)
conn.WriteMessage(websocket.TextMessage, auth)
let url = url::Url::parse("wss://kr.pkcryptolisting.com").unwrap();
 // or wss://tokyo.pkcryptolisting.com for all 4 exchanges 
let (mut ws, _) = connect_async(url).await.unwrap();
// send auth message
let auth = serde_json::json!({"type": "auth", "key": "YOUR_API_KEY"
  // "exchange": "Upbit"  // optional: "Upbit" | "Bithumb" (omit for all)
}).to_string();
ws.send(Message::Text(auth)).await.ok();
2. Kimlik Doğrulama Yanıtı
Kimlik doğrulama başarılı olduğunda plan, gecikme ve son kullanma tarihi bilgileri döndürülür.
✓ Başarılı (auth_ok)
{
  "type":       "auth_ok",
  "plan":       "premium",
  "delay_ms":   0,
  "expires_at": "2026-06-30",
  "message":   "Connected..."
}
✕ Başarısız (error)
{
  "type":    "error",
  "code":    4004,
  "message": "Invalid key"
}
3. Mesaj Alımı
Kimlik doğrulama sonrası yeni bir duyuru algılandığında otomatik olarak alınır. async for kullanıldığında, bağlantı sona erdiğinde döngüden otomatik olarak çıkılır.
# message loop — exits cleanly on disconnect
    async for raw in ws:
        msg      = json.loads(raw)
        msg_type = msg.get("type")
    
        if msg_type == "auth_ok":
            print(f"connected  plan={msg['plan']}  delay={msg['delay_ms']}ms")
    
        elif msg_type == "error":
            print(f"error {msg['code']}: {msg['message']}")
            break
    
        elif msg_type == "plan_updated":  # plan changed
            print(f"plan updated: {msg['plan']}  delay={msg['delay_ms']}ms")
    
        else:  # announcement
            print(f"[{msg['exchange']}] {msg['title']}")
            print(f"  symbol={msg['symbol']}  detected={msg['detectedTime']} {msg.get('timezone', '')}")
// message loop — exits cleanly on disconnect
    ws.on("message", (raw) => {
      const msg = JSON.parse(raw);
      if (msg.type === "auth_ok")
        console.log(`connected  plan=${msg.plan}  delay=${msg.delay_ms}ms`);
      else if (msg.type === "error") { console.log(`error ${msg.code}: ${msg.message}`); ws.close(); }
      else if (msg.type === "plan_updated")  // plan changed
        console.log(`plan updated: ${msg.plan}  delay=${msg.delay_ms}ms`);
      else {  // announcement
        console.log(`[${msg.exchange}] ${msg.title}`);
        console.log(`  symbol=${msg.symbol}  detected=${msg.detectedTime} ${msg.timezone || ''}`);
      }
    });
// message loop — exits cleanly on disconnect
    for {
        _, raw, err := conn.ReadMessage()
        if err != nil { break }
        var msg map[string]interface{}
        json.Unmarshal(raw, &msg)
        switch msg["type"] {
        case "auth_ok":  fmt.Printf("connected  plan=%v  delay=%vms
    ", msg["plan"], msg["delay_ms"])
        case "error":    fmt.Printf("error %v: %v
    ", msg["code"], msg["message"]); break
        case "plan_updated":  // plan changed
            fmt.Printf("plan updated: %v  delay=%vms
    ", msg["plan"], msg["delay_ms"])
        default:  // announcement
            fmt.Printf("[%v] %v
    ", msg["exchange"], msg["title"])
            fmt.Printf("  symbol=%v  detected=%v %v
    ", msg["symbol"], msg["detectedTime"], msg["timezone"])
        }
    }
// message loop — exits cleanly on disconnect
    while let Some(Ok(raw)) = ws.next().await {
        let msg: Value = serde_json::from_str(&raw.to_string()).unwrap_or_default();
        match msg["type"].as_str().unwrap_or("") {
            "auth_ok" => println!("connected  plan={}  delay={}ms", msg["plan"], msg["delay_ms"]),
            "error" => { println!("error {}: {}", msg["code"], msg["message"]); break; }
            "plan_updated" =>  // plan changed
                println!("plan updated: {}  delay={}ms", msg["plan"], msg["delay_ms"]),
            _ => {  // announcement
                println!("[{}] {}", msg["exchange"], msg["title"]);
                println!("  symbol={}  detected={} {}", msg["symbol"], msg["detectedTime"], msg["timezone"]);
            }
        }
    }
4. Alınan Veri Formatı
Duyuru verisi aşağıdaki formatta iletilir. symbol alanı tek bir dize, bir dizi (array) veya boş bir dize olabilir.
⚠️ Notlar
title, category Alanlar, UPBIT · BITHUMB için Korece, BINANCE · BYBIT için orijinal İngilizce olarak alınır.
detectedTimeMotorumuzun duyuruyu algıladığı zaman (mikrosaniye hassasiyeti)
{
  "title":        "펏지펭귄(PENGU) 신규 거래지원 안내 (KRW, BTC, USDT 마켓)",
  "category":     "거래",
  "symbol":       "PENGU",       
  "exchange":     "Upbit",      
  "detectedTime": "2025-05-09 15:00:00.333851",
  "timezone":     "KST",
  "url":          "https://www.upbit.com/service_center/notice?id=5104&view=share"
}
AlanTürAçıklama
titlestringBorsa duyurusunun orijinal başlığı
categorystringDuyuru kategorisi — aşağıdaki kategori listesine bakın
symbolstring | array Çıkarılan coin sembolü. Tekil: "BTC", Çoklu: ["BTC","ETH"], Boşsa: "", Free plan: "***"
exchangestring Duyuru kaynağı borsa: "Upbit", "Bithumb", "Binance", "Bybit"
detectedTimestring Motorumuzun duyuruyu algıladığı zaman (mikrosaniye hassasiyeti). Basic planda +30ms ek gecikme uygulanır
timezonestring detectedTime için referans zaman dilimi. KST (Upbit, Bithumb) veya UTC (Binance, Bybit)
urlstringOrijinal duyuru bağlantısı
Plan Farkları
Tüm planlar aynı altyapıyı kullanır. Yalnızca gecikme ve sembol görünürlüğü farklıdır.
Free
0ms Gecikme
Sembol *** Maskeleme
Basic
+30ms Gecikme
Tam Sembol Görünürlüğü
Premium
0ms Gecikme
Tam Sembol Görünürlüğü
⚠️ Notlar
Tek bir API Key ile tek bir bölgeden birden fazla cihaz bağlantısına izin verilmez şeklinde Zaten aktif bir bağlantı varken başka bir yerden bağlanmaya çalışılırsa, yeni bağlantı denemesi hata kodu 4006 ile engellenir.
Hata Kodları
Bağlantı veya kimlik doğrulama başarısız olduğunda aşağıdaki kodlar döndürülür.
CODEAçıklamaÇözüm
4001Kimlik Doğrulama Zaman AşımıBağlandıktan sonra 5 saniye içinde bir auth mesajı gönderin.
4002Geçersiz JSONJSON formatını doğrulayın.
4003Eksik Kimlik Doğrulama Mesajıtype: "auth" mesajı gereklidir.
4004Geçersiz AnahtarAnahtarınızı Telegram bot'undan kontrol edin.
4005Abonelik Süresi DolduPlanınızı Telegram bot'u üzerinden yenileyin.
4006Yinelenen BağlantıMevcut bağlantıyı sonlandırın ve yeniden bağlanın.
4029Çok Fazla İstek (Hız Sınırı)Lütfen daha sonra tekrar deneyin
Kategoriler
Bu, alınan değerlerin bir listesidir. category alan değerleri UPBIT · BITHUMB için Korece, BINANCE · BYBIT için orijinal İngilizce olarak alınır.
UPBIT 8 Kategori
안내Genel hizmet duyuruları
거래Yeni pazar eklemeleri ve listeden çıkarmalar
입출금Para yatırma/çekme durdurma ve yeniden başlatma
점검Sistem bakımı
디지털 자산Airdrop'lar ve diğerleri
NFTNFT ile ilgili duyurular
서비스+Ek hizmetler
이벤트Etkinlikler & Promosyonlar
BITHUMB 12 Kategori
거래유의Yatırım uyarısı verilen varlıklar
거래지원종료İşlem desteğinin sona ermesi (Listeden Çıkarma)
공시Kamuyu aydınlatma bilgileri
마켓 추가Yeni pazar eklemeleri
수수료 이벤트İşlem ücreti avantajları
신규서비스Yeni hizmet lansmanları
안내Genel duyurular
업데이트Uygulama & Hizmet güncellemeleri
이벤트Etkinlikler & Promosyonlar
입출금Para yatırma/çekme durdurma ve yeniden başlatma
점검Sistem bakımı
후기Bithumb vb. incelemeler
BINANCE 8 Kategori
New Cryptocurrency ListingYeni Kripto Para Listelemeleri
DelistingListeden Çıkarmalar
Maintenance UpdatesAğ Yükseltmeleri & Cüzdan Bakımı
Crypto AirdropAirdrop'lar
Latest Binance NewsEn Son Binance Haberleri
Latest ActivitiesEn Son Etkinlikler & Promosyonlar
New Fiat ListingsYeni Fiat Parite Listelemeleri
API UpdatesAPI Güncellemeleri
BYBIT 9 Kategori
New ListingsYeni Listelemeler
DelistingsListeden Çıkarmalar
Latest ActivitiesEn Son Etkinlikler
EarnKazanç (Earn)
AlphaAlfa
Latest Bybit NewsEn Son Bybit Haberleri
Maintenance UpdatesBakım Güncellemeleri
Partnership AnnouncementOrtaklık Duyuruları
Listing BillboardListeleme Panosu
Tam Örnek Kod
Otomatik yeniden bağlanma ve üstel geri çekilme (exponential backoff) uygulanmış eksiksiz çalışan bir koddur. Sadece YOUR_API_KEY değiştirip hemen çalıştırın.
import asyncio, json, websockets

KEY         = "YOUR_API_KEY"   # issued via Telegram bot
ENDPOINT    = "wss://kr.pkcryptolisting.com"
RETRIES     = 20

def handle_notice(evt: dict):
    exchange = evt.get("exchange", "")
    title    = evt.get("title", "")
    category = evt.get("category", "")
    symbol   = evt.get("symbol", "")
    detected = evt.get("detectedTime", "")
    timezone = evt.get("timezone", "")
    url      = evt.get("url", "")
    print(f"[{exchange}] [{category}] {title}")
    print(f"  symbol={symbol}")
    print(f"  detected={detected} {timezone}")
    print(f"  {url}")

async def listen():
    for attempt in range(RETRIES):
        try:
            async with websockets.connect(ENDPOINT) as ws:
                await ws.send(json.dumps({"type": "auth", "key": KEY}))

                async for raw in ws:
                    evt      = json.loads(raw)
                    evt_type = evt.get("type")

                    if evt_type == "auth_ok":
                        print(f"connected  plan={evt['plan']}  delay={evt['delay_ms']}ms  expires={evt['expires_at']}")
                        attempt = 0  # reset retry counter on success

                    elif evt_type == "error":
                        print(f"[{evt['code']}] {evt['message']}")
                        if evt["code"] in (4004, 4005, 4006, 4029):
                            return  # do not reconnect
                        break

                    elif evt_type == "plan_updated":
                        print(f"plan changed → {evt['plan']}  delay={evt['delay_ms']}ms  expires={evt['expires_at']}")

                    else:
                        handle_notice(evt)

        except websockets.ConnectionClosed as e:
            print(f"closed: {e}")
        except Exception as e:
            print(f"error: {e}")

        backoff = min(2 ** attempt, 300)
        print(f"retry in {backoff}s...")
        await asyncio.sleep(backoff)

if __name__ == "__main__":
    asyncio.run(listen())
// npm install ws
const WebSocket = require("ws");

const KEY      = "YOUR_API_KEY";   // issued via Telegram bot
const ENDPOINT = "wss://kr.pkcryptolisting.com";
const RETRIES  = 20;

function handleNotice(evt) {
  console.log(`[${evt.exchange}] [${evt.category}] ${evt.title}`);
  console.log(`  symbol=${evt.symbol}`);
  console.log(`  detected=${evt.detectedTime} ${evt.timezone || ''}`);
  console.log(`  ${evt.url}`);
}

function listen(attempt = 0) {
  if (attempt >= RETRIES) return;
  const ws = new WebSocket(ENDPOINT);
  ws.on("open", () => ws.send(JSON.stringify({ type: "auth", key: KEY })));
  ws.on("message", (raw) => {
    const evt = JSON.parse(raw);
    if (evt.type === "auth_ok") {
      console.log(`connected  plan=${evt.plan}  delay=${evt.delay_ms}ms  expires=${evt.expires_at}`);
      attempt = 0;  // reset retry counter on success
    } else if (evt.type === "error") {
      console.log(`[${evt.code}] ${evt.message}`);
      if ([4004,4005,4006,4029].includes(evt.code)) return;  // do not reconnect
      ws.close();
    } else if (evt.type === "plan_updated")
      console.log(`plan changed → ${evt.plan}  delay=${evt.delay_ms}ms  expires=${evt.expires_at}`);
    else handleNotice(evt);
  });
  ws.on("close", () => {
    const b = Math.min(2 ** attempt, 300);
    console.log(`retry in ${b}s...`);
    setTimeout(() => listen(attempt + 1), b * 1000);
  });
  ws.on("error", (e) => console.log(`error: ${e.message}`));
}

listen();
// go get github.com/gorilla/websocket
package main

import (
    "encoding/json"; "fmt"; "math"; "time"
    "github.com/gorilla/websocket"
)

const (key = "YOUR_API_KEY"; endpoint = "wss://kr.pkcryptolisting.com"; retries = 20)   // issued via Telegram bot

type Evt struct {
    Type,Plan,Message,ExpiresAt,Exchange,Title,Category,DetectedTime,Timezone,URL string
    Code,DelayMs int; Symbol interface{}
}

func handleNotice(e Evt) {
    fmt.Printf("[%s] [%s] %s
  symbol=%v
  detected=%s %s
",
        e.Exchange, e.Category, e.Title, e.Symbol, e.DetectedTime, e.Timezone, e.URL)
}

func listen() {
    for a := 0; a < retries; a++ {
        c, _, err := websocket.DefaultDialer.Dial(endpoint, nil)
        if err != nil { fmt.Println("error:", err) } else {
            b, _ := json.Marshal(map[string]string{"type":"auth","key":key})
            c.WriteMessage(websocket.TextMessage, b)
            for { _, raw, err := c.ReadMessage(); if err != nil { fmt.Println("closed:", err); break }
                var e Evt; json.Unmarshal(raw, &e)
                switch e.Type {
                case "auth_ok": fmt.Printf("connected  plan=%s  delay=%dms  expires=%s
",e.Plan,e.DelayMs,e.ExpiresAt); a=0  // reset retry counter on success
                case "error": fmt.Printf("[%d] %s
",e.Code,e.Message)
                    if e.Code==4004||e.Code==4005||e.Code==4006||e.Code==4029 { return }  // do not reconnect
                case "plan_updated": fmt.Printf("plan changed → %s  delay=%dms  expires=%s
",e.Plan,e.DelayMs,e.ExpiresAt)
                default: handleNotice(e)
                }
            }; c.Close()
        }
        bf := time.Duration(math.Min(math.Pow(2,float64(a)),300))*time.Second
        fmt.Printf("retry in %vs...
", bf.Seconds()); time.Sleep(bf)
    }
}
func main() { listen() }
use futures_util::{SinkExt, StreamExt};
use tokio_tungstenite::{connect_async, tungstenite::Message};
use serde_json::{json, Value};
use std::time::Duration;

const KEY: &str      = "YOUR_API_KEY";   // issued via Telegram bot
const ENDPOINT: &str = "wss://kr.pkcryptolisting.com";
const RETRIES: u32   = 20;

fn handle_notice(e: &Value) {
    println!("[{}] [{}] {}
  symbol={}
  detected={} {}
  {}",
        e["exchange"],e["category"],e["title"],e["symbol"],e["detectedTime"],e["timezone"],e["url"]);
}

#[tokio::main]
async fn main() {
    for attempt in 0..RETRIES {
        match connect_async(url::Url::parse(ENDPOINT).unwrap()).await {
            Ok((mut ws, _)) => {
                ws.send(Message::Text(json!({"type":"auth","key":KEY}).to_string())).await.ok();
                while let Some(Ok(raw)) = ws.next().await {
                    if let Ok(e) = serde_json::from_str::<Value>(&raw.to_string()) {
                        match e["type"].as_str().unwrap_or("") {
                            "auth_ok" => println!("connected  plan={}  delay={}ms  expires={}",
                                e["plan"],e["delay_ms"],e["expires_at"]),
                            "error" => {
                                println!("[{}] {}",e["code"],e["message"]);
                                let c=e["code"].as_i64().unwrap_or(0);
                                if [4004,4005,4006,4029].contains(&c) { return; }  // do not reconnect
                                break;
                            }
                            "plan_updated" => println!("plan changed → {}  delay={}ms  expires={}",
                                e["plan"],e["delay_ms"],e["expires_at"]),
                            _ => handle_notice(&e),
                        }
                    }
                }
            }
            Err(e) => println!("error: {}", e),
        }
        let b = (2u64.pow(attempt)).min(300);
        println!("retry in {}s...", b);
        tokio::time::sleep(Duration::from_secs(b)).await;
    }
}

API Anahtarı Al

Telegram bot'undan ücretsiz olarak alabilirsiniz.
Ücretli plana yükseltme işlemi de bot üzerinden yapılabilir.

Telegram Üzerinden Al →