JSON-RPC
Overview
Section titled “Overview”The JSON-RPC endpoint provides a standard EVM-compatible interface to the Hyperliquid L1 node. Requests are proxied through the Aleatoric gateway with TLS termination, API key authentication, and per-tier rate limiting. The interface conforms to the Ethereum JSON-RPC specification and is compatible with any EVM client library (ethers.js, web3.py, viem, etc.).
Endpoints
Section titled “Endpoints”| Region | URL | Notes |
|---|---|---|
| US (East US 2) | https://rpc.aleatoric.systems | Primary |
| JP (Japan East) | https://rpc-jp.aleatoric.systems | Live production edge |
All requests must be sent as POST with Content-Type: application/json. The US production endpoint is the default North America path. The JP production endpoint is available for approved Japan-region clients and low-latency APAC routing.
Authentication
Section titled “Authentication”Every request must include your API key in the x-api-key HTTP header:
x-api-key: ak_live_your_key_hereRequests without a valid key receive an HTTP 401 response before the JSON-RPC layer processes the payload.
Supported Methods
Section titled “Supported Methods”| Method | Parameters | Returns | Description |
|---|---|---|---|
eth_blockNumber | — | QUANTITY | Latest block number |
eth_chainId | — | QUANTITY | Chain ID (hex) |
eth_getBlockByNumber | QUANTITY|TAG, Boolean | Block | Block by number; true for full txs |
eth_getBlockByHash | DATA(32), Boolean | Block | Block by hash; true for full txs |
eth_getBalance | DATA(20), QUANTITY|TAG | QUANTITY | Account balance in wei |
eth_getTransactionByHash | DATA(32) | Transaction | Transaction by hash |
eth_getTransactionReceipt | DATA(32) | Receipt | Receipt including logs and status |
eth_getTransactionCount | DATA(20), QUANTITY|TAG | QUANTITY | Nonce for address |
eth_call | CallObject, QUANTITY|TAG | DATA | Execute read-only call (no state change) |
eth_estimateGas | CallObject, QUANTITY|TAG | QUANTITY | Estimated gas for transaction |
eth_getLogs | FilterObject | Log[] | Event logs matching filter criteria |
eth_getCode | DATA(20), QUANTITY|TAG | DATA | Contract bytecode at address |
eth_getStorageAt | DATA(20), QUANTITY, QUANTITY|TAG | DATA(32) | Raw storage slot value |
net_version | — | STRING | Network ID |
Tag values: "latest", "earliest", "pending". Most queries should use "latest".
Request Format
Section titled “Request Format”Every request is a JSON object with four fields:
{ "jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}| Field | Type | Required | Description |
|---|---|---|---|
jsonrpc | string | Yes | Must be "2.0" |
method | string | Yes | RPC method name |
params | array | Yes | Positional parameters (may be empty) |
id | integer|string | Yes | Client-chosen request identifier, echoed in response |
Request & Response Examples
Section titled “Request & Response Examples”eth_blockNumber
Section titled “eth_blockNumber”Returns the number of the most recent block.
curl -s -X POST https://rpc.aleatoric.systems \ -H "Content-Type: application/json" \ -H "x-api-key: ak_live_your_key_here" \ -d '{ "jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1 }'{ "jsonrpc": "2.0", "id": 1, "result": "0x138e3f0"}The result is a hex-encoded block number. In this example, .
eth_getBlockByNumber
Section titled “eth_getBlockByNumber”Returns block data. Pass true as the second parameter to include full transaction objects; false for transaction hashes only.
curl -s -X POST https://rpc.aleatoric.systems \ -H "Content-Type: application/json" \ -H "x-api-key: ak_live_your_key_here" \ -d '{ "jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", false], "id": 2 }'{ "jsonrpc": "2.0", "id": 2, "result": { "number": "0x138e3f0", "hash": "0x5a2f3c...", "parentHash": "0x91b8e2...", "timestamp": "0x65f1a2b0", "transactions": ["0xabc123...", "0xdef456..."], "gasUsed": "0x5208", "gasLimit": "0x1c9c380" }}eth_getLogs
Section titled “eth_getLogs”Query event logs by block range, address, and topic filters. The fromBlock / toBlock range is capped at 10,000 blocks per request.
curl -s -X POST https://rpc.aleatoric.systems \ -H "Content-Type: application/json" \ -H "x-api-key: ak_live_your_key_here" \ -d '{ "jsonrpc": "2.0", "method": "eth_getLogs", "params": [{ "fromBlock": "0x138e000", "toBlock": "0x138e3f0", "address": "0x1234567890abcdef1234567890abcdef12345678", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" ] }], "id": 3 }'{ "jsonrpc": "2.0", "id": 3, "result": [ { "address": "0x1234567890abcdef1234567890abcdef12345678", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "0x000000000000000000000000bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ], "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000", "blockNumber": "0x138e100", "transactionHash": "0xfedcba...", "logIndex": "0x0" } ]}The topics[0] value above is the ERC-20 Transfer(address,address,uint256) event signature. The data field encodes the transfer amount; here wei = 1 token (assuming 18 decimals).
eth_call
Section titled “eth_call”Execute a read-only contract call. This does not create a transaction or consume gas.
curl -s -X POST https://rpc.aleatoric.systems \ -H "Content-Type: application/json" \ -H "x-api-key: ak_live_your_key_here" \ -d '{ "jsonrpc": "2.0", "method": "eth_call", "params": [{ "to": "0x1234567890abcdef1234567890abcdef12345678", "data": "0x70a08231000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, "latest"], "id": 4 }'{ "jsonrpc": "2.0", "id": 4, "result": "0x0000000000000000000000000000000000000000000000056bc75e2d63100000"}The data field contains the ABI-encoded function selector for balanceOf(address) (0x70a08231) followed by the zero-padded address argument.
Batch Requests
Section titled “Batch Requests”The endpoint supports batch requests per the JSON-RPC 2.0 specification. Send an array of request objects and receive an array of responses. The maximum batch size is 100 requests.
curl -s -X POST https://rpc.aleatoric.systems \ -H "Content-Type: application/json" \ -H "x-api-key: ak_live_your_key_here" \ -d '[ {"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}, {"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id": 2}, {"jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "latest"], "id": 3} ]'[ {"jsonrpc": "2.0", "id": 1, "result": "0x138e3f0"}, {"jsonrpc": "2.0", "id": 2, "result": "0xa4b1"}, {"jsonrpc": "2.0", "id": 3, "result": "0x56bc75e2d63100000"}]Notes on batching:
- Each request in the batch counts as one request against your rate limit.
- A batch with requests is rejected with a single error response.
- Responses are returned in the same order as requests.
- If an individual request within the batch fails, only that entry contains an error object; the rest succeed normally.
Error Responses
Section titled “Error Responses”Errors follow the JSON-RPC 2.0 error format:
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32601, "message": "Method not found" }}Standard Error Codes
Section titled “Standard Error Codes”| Code | Message | Description |
|---|---|---|
-32700 | Parse error | Invalid JSON payload |
-32600 | Invalid Request | Missing required fields or wrong jsonrpc version |
-32601 | Method not found | Unknown or unsupported method name |
-32602 | Invalid params | Wrong number or type of parameters |
-32603 | Internal error | Server-side failure |
Gateway Error Codes
Section titled “Gateway Error Codes”These are returned as HTTP status codes before the JSON-RPC layer:
| HTTP Status | Cause | Response Body |
|---|---|---|
401 | Missing or invalid x-api-key | {"error": "Unauthorized"} |
429 | Rate limit exceeded | {"error": "Rate limit exceeded", "retry_after_ms": N} |
502 | Upstream node unavailable | {"error": "Bad Gateway"} |
503 | Service temporarily unavailable | {"error": "Service Unavailable"} |
Rate Limiting
Section titled “Rate Limiting”Rate limits are enforced at the Nginx gateway layer per API key.
| Limit | Value |
|---|---|
| Global burst cap | 5,000 req/s per API key |
| Sustained throughput | Tier-dependent (see Rate Limits) |
| Batch counting | Each request in a batch counts individually |
When a rate limit is hit, the gateway returns HTTP 429 with a retry_after_ms field indicating the minimum backoff in milliseconds. Clients should implement exponential backoff rather than retrying at a fixed interval.
For sustained high-throughput workloads (e.g., block-by-block indexing), consider:
- Using batch requests to reduce HTTP overhead (up to 100 per batch).
- Connecting to the regional endpoint closest to your infrastructure.
- Upgrading to a higher tier if you consistently hit limits.