On the wire · 05:10:49 UTC Live 583 · Prematch 14,343 · Markets 57,147 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Tutorial · Kotlin · WebSocket

WebSocket de cuotas Pinnacle en Kotlin (OkHttp)

Actualizado el · PinnFeed · 1 min de lectura

Respuesta: con OkHttp, construya un Request a wss://pinnfeed.io/v1/stream con cabecera x-api-key, llame newWebSocket, envíe un JSON subscribe en onOpen, y responda {"type":"pong"} a cada ping del servidor (cada 20 s). Frames: welcome, subscribed, partes snapshot, luego delta. Builder (99 €/mes) o Pro.

Gradle#

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.12.0")
    implementation("org.json:json:20240303")
}

Client#

import okhttp3.*
import org.json.JSONObject
import java.util.concurrent.TimeUnit

fun main() {
    val key = System.getenv("PINNFEED_KEY") ?: error("set PINNFEED_KEY")   // ps_live_...
    val client = OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build()

    fun connect(delayMs: Long = 0) {
        Thread.sleep(delayMs)
        val req = Request.Builder().url("wss://pinnfeed.io/v1/stream").header("x-api-key", key).build()
        client.newWebSocket(req, object : WebSocketListener() {
            override fun onOpen(ws: WebSocket, response: Response) {
                ws.send("""{"type":"subscribe","sports":["soccer"],"markets":["moneyline"],"main":true}""")
            }
            override fun onMessage(ws: WebSocket, text: String) {
                val msg = JSONObject(text)
                when (msg.getString("type")) {
                    "ping" -> ws.send("""{"type":"pong"}""")
                    "delta" -> {
                        val changes = msg.getJSONArray("changes")
                        for (i in 0 until changes.length()) {
                            val ch = changes.getJSONObject(i)
                            if (ch.getString("kind") == "market" && ch.getString("op") == "upsert") {
                                val m = ch.getJSONObject("market")
                                if (m.optDouble("maxStake", 0.0) >= 100) println("${m.getLong("eventId")} ${m.getJSONArray("outcomes")}")
                            }
                        }
                    }
                    "error" -> println("error ${msg.optString("code")}: ${msg.optString("message")}")
                }
            }
            override fun onClosed(ws: WebSocket, code: Int, reason: String) {
                println("closed $code $reason")
                if (code != 4001) connect(2000)          // 4001 = key revoked
            }
            override fun onFailure(ws: WebSocket, t: Throwable, response: Response?) {
                println("failure ${response?.code} ${t.message}")
                connect(5000)
            }
        })
    }
    connect()
}

CTA#

Builder (€99/mes). Prueba de 3 días; tarjeta requerida. REST gratis: signup.

Preguntas frecuentes#

¿Por qué Builder?#

/v1/stream exige Builder o Pro. Free/Hobby reciben 403 plan_lacks_ws.

¿Hace falta un SDK oficial?#

No — OkHttp + JSON bastan.

¿Contenido educativo para adultos?#

Sí (18+).

Contenido educativo para mayores de 18 años. Sin pronósticos ni ganancias garantizadas. En España, apuesta solo con operadores con licencia de la DGOJ.

El plan WebSocket: Builder, 99 €/mes.

Cuotas de Pinnacle en tiempo real por un único WebSocket: los 13 deportes, todos los mercados, cuotas justas sin margen y cuotas de cierre. 3 días gratis y cancelas con un clic.

Form K-1 · Free API key

Get your free API key.

One field. No password, no card: enter your email, click the link we send, and your key is on screen.

By continuing you agree to the Terms and Privacy Policy.

One free key per email. Link valid for 20 minutes.