Skip to main content

Redstone Live Feeds

Best suited for dApps that require low-latency data.

Connecting WebSocket API

Open a WebSocket connection and include your API key in the HTTP upgrade request header:

x-api-key: <your-api-key>
ResponseMeaning
HTTP 101Connection accepted
HTTP 401 or 403Missing or invalid API key
HTTP 429Per-key connection limit reached (max 30 concurrent connections)

Subscribing to feeds

After the connection is open, send a JSON text frame to subscribe or unsubscribe. Multiple items can be batched in a single message.

{ "op": "subscribe",   "items": [{ "feedId": "ETH", "type": "price",             "dataServiceId": "redstone-primary-prod" }] }
{ "op": "unsubscribe", "items": [{ "feedId": "ETH", "type": "price", "dataServiceId": "redstone-primary-prod" }] }
{ "op": "subscribe", "items": [{ "feedId": "ETH", "type": "redstonePackages", "dataServiceId": "redstone-primary-prod" }] }
FieldTypeDescription
feedIdstringFeed identifier, e.g. "ETH", "BTC"
type"price" | "redstonePackages"Subscription channel (see below)
dataServiceIdstringData service identifier optional default is "redstone-primary-prod"

Note: subscribe and unsubscribe must use the exact same type, dataServiceId, and feedId to address the correct channel. Unsubscribing from price does not affect an active redstonePackages subscription for the same feed.


Message types

price

Delivers one lightweight aggregated tick which is median from quorum of signers.

{
"type": "price",
"dataServiceId": "redstone-primary-prod",
"dataPackageId": "ETH",
"timestamp": 1712345678000,
"value": 2543.12,
}
FieldTypeDescription
type"price"Discriminant field
dataServiceIdstringData service identifier
dataPackageIdstringFeed identifier
timestampnumberMillisecond timestamp of the data round
valuenumberMedian price across all merged signer payloads

Only published when at least one numeric data point is present in the merged payloads.


redstonePackages

Delivers the raw signed oracle packages from quorum of signers.

  • Payloads in a single batch are guaranteed to contain packages from 3 unique Redstone nodes with the same timestamp.
  • Whitelisted signer addresses: initial-state.json
  • You can use this function SignedDataPackage.fromObj() from package to recover signer address.
  • Most feeds have exactly 1 element in dataPoints. Only feeds prefixed with __ can contain multiple data points.

Recommended algorithm for safe consumption:

  1. Filter out packages with non-whitelisted signers or invalid signatures.
  2. Check that the minimum signer count threshold is met.
  3. Calculate the median across the verified packages.
{
"type": "redstonePackages",
"dataServiceId": "redstone-primary-prod",
"payloads": [
{
"dataPackageId": "ETH",
"timestampMilliseconds": 1712345678000,
"dataPoints": [{ "dataFeedId": "ETH", "value": 2543.12 }],
"signature": "<base64>",
},
// ... one entry per signer
],
}
FieldTypeDescription
type"redstonePackages"Discriminant field
dataServiceIdstringData service identifier
payloadsSignedDataPackagePlainObj[]One signed package per merged signer

Parsing messages

Use the type field to distinguish message kinds on the client side:

ws.on("message", (raw) => {
const msg = JSON.parse(raw);
if (msg.type === "price") {
console.log(msg.dataPackageId, msg.value);
} else if (msg.type === "redstonePackages") {
console.log(msg.dataPackageId, msg.payloads.length, "signers");
}
});

Keepalive

The server sends a WebSocket ping frame after 120 seconds of inactivity. Spec-compliant clients respond with a pong automatically — no application-level handling is required. If no pong is received the server closes the connection with code 1001. Reconnect and re-subscribe after that.


Connection lifetime

Connections are forcibly closed after 8 hours (code 1006) regardless of activity. Clients must handle this close event and reconnect.