Sticky Sessions
Pin your requests to a single backend node using the DWSESSION cookie. Useful for consistent state across sequential calls like eth_getFilterChanges, eth_subscribe, and trace workflows.
Dwellir endpoints are backed by multiple blockchain nodes behind a load balancer. By default, each request may land on a different node. Sticky sessions let you pin all your requests to the same backend node using a cookie, which is important when your workflow depends on consistent state across sequential calls.
When You Need Sticky Sessions
- Filter-based workflows --
eth_newFilter/eth_getFilterChangesrequire the same node because filters are local to the node that created them. - Pending transaction monitoring --
eth_newPendingTransactionFilterfollowed byeth_getFilterChanges. - Debug and trace sequences -- multi-step trace workflows where intermediate state lives on a single node.
- Any stateful JSON-RPC sequence -- whenever a later call depends on state created by an earlier call on the same node.
WebSocket connections are inherently sticky because they maintain a single long-lived TCP connection to one backend. Sticky sessions are only relevant for HTTP requests.
How It Works
-
First request (no cookie) -- the load balancer picks a healthy backend node, serves the response, and returns a
Set-Cookieheader:Text Set-Cookie: DWSESSION=<node-id>; Path=/; Max-Age=604800; SameSite=Lax -
Subsequent requests -- your HTTP client sends the cookie back. The load balancer routes the request to the same node. No new
Set-Cookieis returned when the session is maintained. -
Cookie expiry -- the cookie is valid for 7 days (
Max-Age=604800). After that, the next request is treated as a first request and a new node is assigned.
Usage Examples
cURL
# Step 1: Make the first request and save the cookie
curl -c cookies.txt -X POST \
-H "Content-Type: application/json" \
https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY \
-d '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"fromBlock":"latest"}],"id":1}'
# Step 2: Subsequent requests reuse the cookie
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY \
-d '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x1"],"id":2}'Python (requests)
import requests
url = "https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY"
# Use a Session -- it stores and sends cookies automatically
session = requests.Session()
# First request receives the DWSESSION cookie
response = session.post(url, json={
"jsonrpc": "2.0",
"method": "eth_newFilter",
"params": [{"fromBlock": "latest"}],
"id": 1
})
filter_id = response.json()["result"]
# Subsequent requests send the cookie and hit the same node
response = session.post(url, json={
"jsonrpc": "2.0",
"method": "eth_getFilterChanges",
"params": [filter_id],
"id": 2
})JavaScript (fetch)
// In browsers, fetch sends cookies automatically with credentials: "include"
const url = "https://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY";
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_newFilter",
params: [{ fromBlock: "latest" }],
id: 1,
}),
});
const { result: filterId } = await response.json();
// The browser stores the DWSESSION cookie and sends it on the next request
const changes = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_getFilterChanges",
params: [filterId],
id: 2,
}),
});Node.js (ethers.js / web3.js)
Standard provider classes in ethers.js and web3.js do not send cookies. If your workflow requires sticky sessions from a Node.js backend, use a cookie-aware HTTP client like the Python requests.Session example above, or use a WebSocket connection which is inherently sticky:
import { WebSocketProvider } from "ethers";
// WebSocket connections are always sticky -- single TCP connection to one node
const provider = new WebSocketProvider(
"wss://api-ethereum-mainnet.n.dwellir.com/YOUR_API_KEY"
);
const filterId = await provider.send("eth_newFilter", [
{ fromBlock: "latest" },
]);
const changes = await provider.send("eth_getFilterChanges", [filterId]);Important Notes
- Health takes priority -- if your pinned node becomes unhealthy (e.g., falls behind on block height), the load balancer may route you to a different node and return a new
Set-Cookie. This is by design to avoid sending requests to a degraded node. - Not a guarantee -- sticky sessions are best-effort. Always handle the case where your session-dependent call fails (e.g., filter not found) by re-creating the filter.
- WebSocket is simpler -- if your use case allows it, prefer WebSocket connections. They are inherently sticky and also support server-pushed subscriptions like
eth_subscribe. - Cookie scope -- the
DWSESSIONcookie is scoped toPath=/, so it applies to all requests to the same endpoint domain. If you use multiple chains, each domain gets its own independent cookie.
Tracing
Use debug_traceTransaction, trace_transaction, and other tracing APIs to inspect smart contract execution, debug failed transactions, and analyze gas usage on Dwellir archive nodes.
Agent Tooling
Tools, skills, and documentation endpoints built for AI coding agents. Migrate RPC endpoints, query Hyperliquid, and consume docs programmatically.