TriportRPC

Polygon Pub/Sub WebSocket — /ws/polygon

Real-time Polygon JSON-RPC pub/sub over WebSocket: subscribe with `eth_subscribe`, receive `eth_subscription` notifications until you `eth_unsubscribe`.

Polygon— (per-subscription tier gating, see below)Per-subscription type: newPendingTransactions free · logs basic · newHeads pro · syncing pro

/ws/polygon is a JSON-RPC pub/sub WebSocket for Polygon. It uses the standard eth_subscribe / eth_unsubscribe wire shape — identical to the Ethereum WS channel. You open one WebSocket connection, send an eth_subscribe frame naming one of four subscription types, and the server replies with a hex subscription id. From then on the server pushes eth_subscription notification frames carrying that id plus the event payload, until you send eth_unsubscribe with the id (or the socket closes).

This channel is eth-base only. Polygon-specific bor_subscribe* methods are not yet supported here — sending one is rejected as an unknown method (forbidden, WS close 4003). The four supported subscription types are:

Subscription typeWhat it pushesMinimum tier
newPendingTransactionsMempool transaction hashes (or full bodies)free
logsFiltered log eventsbasic
newHeadsA header for every new blockpro
syncingNode sync-state transitionspro

Subscribing below the required tier closes the connection with WS code 4003 and a WSErrorFrame whose error is forbidden (the frame carries current_tier / required_tier / upgrade_url so you can render an upgrade prompt without another call).

Parameters

The client sends a JSON-RPC frame. eth_subscribe takes a params array of 1–2 items: the subscription type, plus an optional type-specific options object.

eth_subscribe frameobject
jsonrpcstringrequired
Must be "2.0".
idinteger | stringrequired
Client request id; echoed in the ack.
methodstringrequired
Must be "eth_subscribe".
paramsarray (1–2 items)required
params[0] = subscription type; params[1] = optional filter/options.
eth_unsubscribe frameobject
jsonrpcstringrequired
Must be "2.0".
idinteger | stringrequired
Client request id.
methodstringrequired
Must be "eth_unsubscribe".
paramsarray (exactly 1)required
params[0] = the hex subscription id returned by the subscribe ack.

Response

The subscribe ack returns the hex subscription id:

Subsequent newHeads notifications:

{
  "jsonrpc": "2.0",
  "method": "eth_subscription",
  "params": {
    "subscription": "0x9cef478923ff08bf67fde6c64013158d",
    "result": {
      "number": "0x3b2f1a0",
      "hash": "0x8a1f...c2",
      "parentHash": "0x77be...01",
      "nonce": "0x0000000000000000",
      "sha3Uncles": "0x1dcc...47",
      "logsBloom": "0x0000...00",
      "transactionsRoot": "0xab32...9f",
      "stateRoot": "0xdd91...0c",
      "receiptsRoot": "0x56aa...e1",
      "miner": "0x0000000000000000000000000000000000000000",
      "difficulty": "0x1",
      "extraData": "0xd682...00",
      "gasLimit": "0x1c9c380",
      "gasUsed": "0x8f2c11",
      "timestamp": "0x66 4f 0a",
      "baseFeePerGas": "0x4a817c800"
    }
  }
}

A newPendingTransactions notification (default mode) carries a tx hash string:

{
  "jsonrpc": "2.0",
  "method": "eth_subscription",
  "params": {
    "subscription": "0x1f2e3d4c5b6a79880123456789abcdef",
    "result": "0x3a7b...e9"
  }
}
jsonrpcstring
Always "2.0".
idinteger | string
Echoes the request id.
resultstring
Hex-encoded subscription id — keep it for eth_unsubscribe.

Errors

Before closing the connection, the server may send a WSErrorFrame whose error field names the reason, then closes with the matching WS close code.

Close codeerrorWhen it happens
4001unauthorizedMissing/invalid credentials on the upgrade (no Bearer / api-key / auth frame).
4003forbiddenSubscription type requires a higher tier, or an unknown/unsupported method (e.g. a bor_subscribe* call — not yet supported here).
4029rate_limitedPer-tier RPS exceeded; retry_after_sec / limit_rps indicate when to retry.
4030trial_expiredTrial period has ended; upgrade_url points at checkout.

Example forbidden frame (subscribing to newHeads on the free tier):

{
  "error": "forbidden",
  "message": "subscription 'newHeads' requires tier 'pro'",
  "current_tier": "free",
  "required_tier": "pro",
  "method": "newHeads",
  "category": "polygon_ws_pubsub",
  "upgrade_url": "https://triport.io/upgrade?tier=pro"
}

See the shared errors reference for the full WSErrorFrame envelope and all fields.

Examples

JavaScript (fetch / browser WebSocket)

const ws = new WebSocket(
  `wss://ws.triport.io/ws/polygon?api-key=${TRIPORT_API_KEY}`
);


ws.addEventListener("open", () => {
  ws.send(JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_subscribe",
    params: ["newHeads"],
  }));
});


let subId;
ws.addEventListener("message", (ev) => {
  const msg = JSON.parse(ev.data);
  if (msg.id === 1) {
    subId = msg.result;              // hex subscription id
    return;
  }
  if (msg.method === "eth_subscription") {
    console.log("new head", msg.params.result.number);
  }
});


// later: ws.send(JSON.stringify({
//   jsonrpc: "2.0", id: 2, method: "eth_unsubscribe", params: [subId],
// }));

TypeScript SDK (@triport/sdk)

import { TriportClient } from "@triport/sdk";


const client = new TriportClient({ apiKey: process.env.TRIPORT_API_KEY! });


const sub = await client.polygon.ws.subscribe("newHeads");
sub.on("data", (head) => {
  console.log("new head", head.number);
});


// later
await sub.unsubscribe();

Python (triport-sdk)

import os
from triport import TriportClient


client = TriportClient(api_key=os.environ["TRIPORT_API_KEY"])


with client.polygon.ws.subscribe("logs", {
    "address": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270",
}) as sub:
    for log in sub:
        print(log["transactionHash"], log["topics"])

Notes

  • Wire shape is identical to Ethereum. This channel mirrors /ws/eth exactly — same eth_subscribe / eth_unsubscribe methods, same four subscription types, same eth_subscription notification envelope and tier gating. Code written for one channel works on the other by swapping the path.
  • bor_subscribe* is not yet supported. The spec marks /ws/polygon as eth-base only; Polygon's Bor-specific subscriptions will be added in a later revision. Until then, calling one returns forbidden (close 4003).
  • One id per subscription. A single connection can hold multiple subscriptions; track each returned result id so you can eth_unsubscribe selectively.
  • Disconnect releases everything. Closing the socket cancels all of its subscriptions — no explicit unsubscribe is needed on teardown.
  • Authentication options. Prefer the Authorization: Bearer header on the upgrade request. Browser WebSocket clients that cannot set headers may use ?api-key= or a first-frame auth message instead.