Pinnacle odds WebSocket in Java
Answer: with Java 11 or newer you need no library: HttpClient.newWebSocketBuilder() can set the x-api-key header, connect to wss://pinnfeed.io/v1/stream, send a JSON subscribe, and answer the server's ping (every 20 seconds) with {"type":"pong"}. Frames arrive as welcome, subscribed, snapshot parts and then delta frames. Builder (€99/mo) is required.
Minimal client#
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
public class PinnFeedStream {
public static void main(String[] args) throws Exception {
String key = System.getenv("PINNFEED_KEY"); // ps_live_...
CountDownLatch closed = new CountDownLatch(1);
WebSocket.Listener listener = new WebSocket.Listener() {
final StringBuilder buf = new StringBuilder();
public void onOpen(WebSocket ws) {
ws.sendText("{\"type\":\"subscribe\",\"sports\":[\"soccer\"],\"markets\":[\"moneyline\"],\"main\":true}", true);
ws.request(1);
}
public CompletionStage<?> onText(WebSocket ws, CharSequence part, boolean last) {
buf.append(part);
if (last) {
String msg = buf.toString();
buf.setLength(0);
if (msg.startsWith("{\"type\":\"ping\"")) ws.sendText("{\"type\":\"pong\"}", true);
else System.out.println(msg.length() > 160 ? msg.substring(0, 160) + "..." : msg);
}
ws.request(1);
return null;
}
public CompletionStage<?> onClose(WebSocket ws, int code, String reason) {
System.out.println("closed " + code + " " + reason);
closed.countDown();
return null;
}
public void onError(WebSocket ws, Throwable e) {
e.printStackTrace();
closed.countDown();
}
};
HttpClient.newHttpClient().newWebSocketBuilder()
.header("x-api-key", key)
.buildAsync(URI.create("wss://pinnfeed.io/v1/stream"), listener)
.join();
closed.await();
}
}
Run with java PinnFeedStream.java (Java 11+ single-file launch). Large snapshots arrive in several text parts, which is why the listener buffers until last is true. Parse with Jackson or Gson in real code.
Close codes to handle#
| Code | Meaning | Fix |
|---|---|---|
4002 no_subscription | No subscribe within 30 s | Send it in onOpen |
4008 slow_consumer | Your client fell behind (server buffer over 16 MB) | Process frames off the listener thread; subscribe to fewer markets |
HTTP 403 plan_lacks_ws | Free or Hobby key | Use a Builder or Pro key |
The server drops the connection if it hears no pong for 60 seconds. Reconnect with backoff and expect a fresh snapshot: reconnect pattern, ping/pong, snapshot/delta. Other languages: Go, C#, Rust, TypeScript.
Plans#
The WebSocket is on Builder (€99/mo, 3 connections) and Pro. 3-day trial; a card is required and it is charged after day 3 unless you cancel. Prototype on Free REST first: signup.
Educational content for adults (18+).
See also: Swift client.
Questions people ask#
Is there an official Java SDK?#
No. The JDK client plus a JSON library is enough.
Kotlin or Spring?#
The same frames work with OkHttp's WebSocket or Spring's WebSocketClient; set the x-api-key header the same way. Full example: Kotlin + OkHttp.
Can I pass the key in the URL?#
Yes, wss://pinnfeed.io/v1/stream?key=ps_live_... works; the header keeps it out of logs.