Honeycluster Team-
The XRP Ledger exposes its API through two transport protocols: HTTP JSON-RPC and WebSocket. Both give you access to the same set of commands, but the way they handle connections, latency, and data flow is fundamentally different. Picking the wrong one for your use case means either wasted bandwidth or missed ledger events.
This guide breaks down when to use each, with real code examples you can run against Honeycluster endpoints today.
HTTP JSON-RPC is the simpler of the two. You send a POST request with a JSON body, the server responds with JSON, and the connection closes. Stateless, familiar, and easy to debug with curl.
JavaScriptconst response = await fetch("https://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-rpc/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ method: "account_info", params: [ { account: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", ledger_index: "validated" } ] }) }); const data = await response.json(); console.log("Balance:", data.result.account_data.Balance);
The request/response cycle is straightforward. No handshake overhead beyond the standard TCP + TLS setup, and HTTP/2 connection reuse keeps subsequent calls fast.
JavaScriptconst response = await fetch("https://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-rpc/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ method: "tx", params: [ { transaction: "E2F28FBE4A206D... (tx hash)", binary: false } ] }) }); const tx = await response.json(); console.log("Transaction type:", tx.result.TransactionType); console.log("Validated:", tx.result.validated);
WebSocket opens a persistent, full-duplex connection. Once the handshake completes, both client and server can push messages at any time without the overhead of new HTTP requests. This is what you want when the ledger needs to talk to you, not the other way around.
JavaScriptconst WebSocket = require("ws"); const ws = new WebSocket("wss://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-ws/"); ws.on("open", () => { ws.send( JSON.stringify({ command: "subscribe", streams: ["ledger"] }) ); console.log("Subscribed to ledger stream"); }); ws.on("message", (data) => { const msg = JSON.parse(data); if (msg.type === "ledgerClosed") { console.log(`Ledger #${msg.ledger_index} closed`); console.log(` Transactions: ${msg.txn_count}`); console.log(` Close time: ${msg.ledger_time}`); } }); ws.on("close", () => { console.log("Connection closed -- implement reconnection logic here"); });
JavaScriptconst WebSocket = require("ws"); const ws = new WebSocket("wss://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-ws/"); const WATCHED_ACCOUNT = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"; ws.on("open", () => { ws.send( JSON.stringify({ command: "subscribe", accounts: [WATCHED_ACCOUNT] }) ); }); ws.on("message", (data) => { const msg = JSON.parse(data); if (msg.transaction && msg.transaction.TransactionType === "Payment") { console.log("Payment detected!"); console.log(` From: ${msg.transaction.Account}`); console.log(` To: ${msg.transaction.Destination}`); console.log(` Amount: ${JSON.stringify(msg.transaction.Amount)}`); } });
| HTTP JSON-RPC | WebSocket | |
|---|---|---|
Connection model | Stateless, one request per connection (or reused via HTTP/2) | Persistent, full-duplex |
Latency | Higher per-call due to connection setup | Lower after initial handshake |
Subscriptions | Not supported | Native support via subscribe command |
Overhead | HTTP headers on every request | Minimal frame overhead after handshake |
Reconnection | Not needed (stateless) | Must be handled by the client |
Best for | On-demand queries, serverless, scripts | Streaming, real-time monitoring, high-throughput |
Ease of use | Very simple ( fetch / curl) | Requires connection lifecycle management |
Firewall friendliness | Works everywhere | Occasionally blocked by corporate proxies |
This is the most frequent anti-pattern. Developers write a setInterval that hits the HTTP endpoint every second to check for new ledgers or transactions.
JavaScript// Don't do this setInterval(async () => { const res = await fetch("https://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-rpc/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ method: "ledger", params: [{ ledger_index: "validated" }] }) }); const data = await res.json(); // check if ledger index changed... }, 1000);
This wastes bandwidth, adds latency (you only discover new ledgers at the next poll interval), and puts unnecessary load on the server. Use a WebSocket subscription instead. You get the data pushed to you the moment the ledger closes.
Rule of thumb
If you find yourself polling an HTTP endpoint more than once every 30 seconds for the same type of data, you almost certainly want a WebSocket subscription.
WebSocket connections drop. Servers restart, networks hiccup, load balancers rotate. If your code assumes the connection will stay open forever, you will miss events silently.
Always implement reconnection with exponential backoff:
JavaScriptfunction connect() { const ws = new WebSocket("wss://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-ws/"); ws.on("open", () => { retryDelay = 1000; // reset on successful connect ws.send(JSON.stringify({ command: "subscribe", streams: ["ledger"] })); }); ws.on("message", (data) => { // handle messages }); ws.on("close", () => { console.log(`Reconnecting in ${retryDelay}ms...`); setTimeout(connect, retryDelay); retryDelay = Math.min(retryDelay * 2, 30000); }); } let retryDelay = 1000; connect();
Don't forget resubscription
After reconnecting, your previous subscriptions are gone. You must re-send your subscribe commands inside the open handler every time.
id fieldBoth protocols support an id field in requests so you can match responses to their originating calls. This is especially important on WebSocket where multiple responses can arrive interleaved. Always set a unique id on each request and correlate it on the response side.
Json{ "id": "account-check-42", "command": "account_info", "account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "ledger_index": "validated" }
Honeycluster provides both HTTP and WebSocket endpoints for the XRP Ledger, optimized for low latency and high availability.
| Protocol | Endpoint |
|---|---|
HTTP JSON-RPC | https://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-rpc/ |
WebSocket | wss://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-ws/ |
Both endpoints support the full XRPL API command set. Requests are routed to geographically distributed nodes, and connections are load-balanced automatically.
Rate limits
Free-tier access is available for development and testing. For production workloads that require higher throughput or guaranteed SLAs, check out our infrastructure plans on the Honeycluster dashboard.
The decision usually comes down to a single question: does your application need to react to chain events as they happen?
Many production applications use both. A common pattern is to maintain a WebSocket connection for real-time ledger and transaction monitoring, while using HTTP for ad-hoc lookups triggered by user actions (searching for a transaction hash, checking a balance on demand).
Spin up a quick test right now. Open a terminal and hit the HTTP endpoint:
Bashcurl -s -X POST https://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-rpc/ \ -H "Content-Type: application/json" \ -d '{"method":"server_info","params":[{}]}' | jq .result.info.validated_ledger
Or open a WebSocket connection:
Bashwscat -c wss://743ad329-0d975b0d.sandblocks.dev/proxy/xrpl-ws/ \ -x '{"command":"subscribe","streams":["ledger"]}'
Both should return data within milliseconds. From there, integrate the right protocol into your stack and start building.
Head over to the Honeycluster Dashboard to grab your API keys and explore the full endpoint documentation. If you have questions, drop into our community channels -- we are always happy to help developers ship faster on the XRP Ledger.
Build on infrastructure you can trust
Managed nodes, real-time indexing, and production-grade APIs for the XRP Ledger.

Honeycluster Team-Mar 15, 2026A detailed look at the physical and cloud infrastructure that powers Honeycluster — from rack-mounted on-prem servers to cloud services.

Honeycluster Team-Mar 13, 2026Colocation, power, bandwidth, and the questions you should be asking before you sign a contract. Lessons from building Honeycluster's physical infrastructure.

Honeycluster Team-Mar 9, 2026Most users never think about what's running beneath their favorite XRP Ledger app. Reliable data feeds. Real-time indexing. Historical analytics. That's infrastructure — and it's the reason everything just works.