RPC WebSocket beta
Use the Starkscan JSON-RPC WebSocket route only after your key and workload are explicitly enrolled.
RPC WebSocket beta
Use this page only when Starkscan has explicitly enrolled your client for the WebSocket beta and provided fresh route evidence. The default Starkscan RPC contract is still authenticated HTTP JSON-RPC; WebSocket support is a separate partner-beta lane.
Endpoint and auth
The beta mainnet route is:
wss://api.starkscan.co/v1/SN_MAIN/rpc/wsAuthentication uses the same Starkscan API key as HTTP RPC, sent as:
X-Starkscan-Api-Key: <starkscan_api_key>Use a server, backend worker, or client library that can set WebSocket headers.
The browser-native WebSocket constructor cannot set X-Starkscan-Api-Key, so
do not build browser-only integrations against this route until Starkscan
publishes a browser-compatible auth shape.
The URL-token HTTP node URL is not a WSS credential. Do not put a Starkscan API key in the WSS URL path or query string unless Starkscan publishes a specific compatibility route for that shape.
Enrollment request
Before testing WSS, ask your Starkscan partner or operator contact for named client WebSocket beta enrollment. Include:
- customer or workspace name
- chain and environment
- expected concurrent connections per API key
- expected subscriptions per connection
- subscription methods and filters you plan to use
- reconnect and HTTP backfill strategy
- whether your client can send
X-Starkscan-Api-Keyduring the WebSocket upgrade
Starkscan should return the approved key profile, connection and subscription caps, route, and current WSS certification boundary before you send production traffic.
Supported methods
The beta route is for Starknet JSON-RPC subscriptions:
| Method | Use |
|---|---|
starknet_subscribeNewHeads | receive new-head notifications |
starknet_subscribeEvents | receive event notifications for bounded filters |
starknet_subscribeTransactionStatus | receive transaction status updates |
starknet_subscribeNewTransactionReceipts | receive new transaction receipt notifications |
starknet_subscribeNewTransactions | receive new transaction notifications |
starknet_unsubscribe | close a subscription |
An active new-head subscription can also receive the server notification
starknet_subscriptionReorg. It is not a separate client subscription method.
Treat its affected block range as invalidated, roll back any derived local
state for that range, and reconcile canonical blocks over HTTP before accepting
later live notifications.
Only the six request methods listed above can reach the WSS upstream. The
gateway rejects HTTP read, trace, write, unknown, and wildcard-looking method
names locally; a name that merely starts with starknet_subscribe is not
accepted. JSON-RPC request batches and binary WebSocket frames also fail closed.
Use authenticated HTTP RPC for every non-subscription request.
The capability manifest retains methodFamilies for older consumers, but that
field is classification-only. Integrations must use the exact methods list as
the forwarding contract; starknet_subscribe* is never a wildcard permission.
HTTP JSON-RPC still rejects subscription methods with the rpc_ws class. That
fail-closed behavior is intentional; use the WSS route for subscriptions and
the HTTP route for reads, calls, events backfill, simulation, fee, and
signed-payload submission.
Caps and backpressure
Default beta caps are intentionally bounded:
| Limit | Default |
|---|---|
| Connections per key | 2 |
| Subscriptions per connection | 16 |
| Client JSON-RPC messages per key | 120 per minute |
| Client message size | 1 MiB |
| Upstream connect timeout | 5 seconds |
| Client send timeout | 2 seconds |
These limits can change per partner tier. Handle cap and rate-limit signals explicitly:
| Signal | Meaning | Client action |
|---|---|---|
WebSocket upgrade returns HTTP 429 | connection cap or WSS route budget is exhausted | honor Retry-After when present; otherwise back off with jitter before opening another connection |
JSON-RPC error error.data.code = "rpc_wss_subscription_limit" and error.data.quotaClass = "rpc_ws" | the connection hit its subscription cap | unsubscribe unused streams or open a new connection only if your key tier allows it |
JSON-RPC error error.data.code = "rate_limited" and quotaClass = "rpc_ws" | the key exhausted its per-message WSS budget | honor the returned retry delay before sending another request |
JSON-RPC error error.data.code = "rpc_wss_method_not_allowed" | the request is not one of the exact subscription methods above | move that call to authenticated HTTP RPC; do not retry it over WSS |
JSON-RPC error error.data.code = "rpc_wss_subscription_batch_unsupported" | subscription operations were sent as a JSON-RPC batch | send each subscription operation as one request with its own unique id |
HTTP JSON-RPC returns 429 with error.data.code = "rate_limited" for subscription probes | the HTTP fail-closed route is quota-limited while rejecting WSS-only methods | honor Retry-After; do not treat this as WSS subscription success |
| clean WebSocket close before a response | upstream or gateway backpressure, maintenance, or transient network loss | reconnect with exponential backoff, then backfill over HTTP before trusting live events again |
Every subscription request needs a unique JSON-RPC string or numeric id. A
subscription slot is released only after the upstream returns true for the
corresponding starknet_unsubscribe request. Treat a failed or interrupted
unsubscribe as still consuming the slot until the connection is closed.
Subscription operations must be sent one request at a time; a JSON-RPC batch
containing a subscription operation is rejected with
rpc_wss_subscription_batch_unsupported so the gateway can enforce the cap
without ambiguity.
Do not reconnect in a tight loop. Use exponential backoff with jitter and keep one reconnect attempt in flight per client instance.
Reconnect and backfill
WebSocket delivery is live, not an archival replay contract. Clients should keep their own cursor:
- latest observed block number for new heads
- event filter plus last processed block for event streams
- transaction hash for transaction-status subscriptions
On reconnect, resume by backfilling over HTTP before trusting live notifications again:
- use
starknet_blockNumberorstarknet_blockHashAndNumberto find the new head - use bounded
starknet_getEventswindows for event gaps - use
starknet_getTransactionReceiptorstarknet_getTransactionStatusfor transaction gaps
Apply the same HTTP reconciliation boundary after
starknet_subscriptionReorg; a reorg notification is an invalidation signal,
not a complete replacement-history payload.
Keep backfill windows bounded. For starknet_getEvents, prefer the named
filter wrapper, keep chunk_size <= 1000, and keep the block span at or below
10,000.
Error reports
For every WSS issue report, include:
- endpoint host and chain
- subscription method and params, with API keys removed
- close code and close reason, if present
- JSON-RPC error object, if present
- last notification block or cursor processed
- whether the client was reconnecting or opening a first connection
- matching HTTP backfill request IDs, if the issue involves a gap
Do not include the full API key, URL-token RPC URL, private upstream URL, full event payload dumps, calldata, signatures, or raw subscription ids in shared tickets.
Readiness boundary
Do not treat WSS as ready because HTTP RPC provider readiness passed. A
customer-facing WSS claim needs a deploy attestation with
rpcWssReadiness.status=passed, including Starkscan WSS route proof, upstream
WSS proof, reconnect/backfill proof, and connection/subscription cap proof.
The certification fixture also proves that reorg notifications survive the
gateway unchanged without retaining their payload in the attestation.
Related docs: