API Reference

Complete reference for Prism's JSON-RPC API, HTTP endpoints, and custom extensions.

Table of Contents


HTTP Endpoints

Prism exposes the following HTTP endpoints:

Endpoint
Method
Description
Content-Type

/

POST

Single or batch JSON-RPC request

application/json

/health

GET

Health check and status information

application/json

/metrics

GET

Prometheus metrics

text/plain

Note: Batch requests are sent to / as an array, not to a separate /batch endpoint.

/ - Single JSON-RPC Request

Send a single JSON-RPC 2.0 request.

Request:

POST / HTTP/1.1
Host: localhost:3030
Content-Type: application/json
X-API-Key: your-api-key-here  # Optional, if auth enabled

{
  "jsonrpc": "2.0",
  "method": "eth_blockNumber",
  "params": [],
  "id": 1
}

Response:

HTTP/1.1 200 OK
Content-Type: application/json
X-Cache-Status: MISS

{
  "jsonrpc": "2.0",
  "result": "0x11a6e3b",
  "id": 1
}

/ - Batch Requests

Send multiple JSON-RPC requests in a single HTTP call by passing an array:

Request:

POST / HTTP/1.1
Host: localhost:3030
Content-Type: application/json

[
  {
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  },
  {
    "jsonrpc": "2.0",
    "method": "eth_chainId",
    "params": [],
    "id": 2
  }
]

Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
  {
    "jsonrpc": "2.0",
    "result": "0x11a6e3b",
    "id": 1
  },
  {
    "jsonrpc": "2.0",
    "result": "0x1",
    "id": 2
  }
]

/health - Health Check

Get system health and upstream status.

Request:

GET /health HTTP/1.1
Host: localhost:3030

Response:

{
  "status": "healthy",
  "version": "1.0.0",
  "upstreams": [
    {
      "name": "alchemy-mainnet",
      "healthy": true,
      "chain_id": 1,
      "latest_block": 18500000,
      "finalized_block": 18499900,
      "response_time_ms": 45,
      "error_count": 0,
      "circuit_breaker": "closed"
    },
    {
      "name": "infura-mainnet",
      "healthy": true,
      "chain_id": 1,
      "latest_block": 18500001,
      "finalized_block": 18499901,
      "response_time_ms": 52,
      "error_count": 0,
      "circuit_breaker": "closed"
    }
  ],
  "cache": {
    "enabled": true,
    "blocks_cached": 1500,
    "logs_cached": 25000,
    "transactions_cached": 10000,
    "cache_hit_rate": 0.87
  },
  "metrics": {
    "total_requests": 125000,
    "total_errors": 145,
    "average_latency_ms": 38.5
  }
}

/metrics - Prometheus Metrics

Prometheus-compatible metrics endpoint.

Request:

GET /metrics HTTP/1.1
Host: localhost:3030

Response:

# HELP rpc_requests_total Total number of RPC requests
# TYPE rpc_requests_total counter
rpc_requests_total{method="eth_blockNumber",upstream="alchemy"} 1250

# HELP rpc_cache_hits_total Cache hits by method
# TYPE rpc_cache_hits_total counter
rpc_cache_hits_total{method="eth_getBlockByNumber"} 890

# HELP rpc_request_duration_seconds Request latency histogram
# TYPE rpc_request_duration_seconds histogram
rpc_request_duration_seconds_bucket{method="eth_getLogs",upstream="alchemy",le="0.05"} 450
rpc_request_duration_seconds_bucket{method="eth_getLogs",upstream="alchemy",le="0.1"} 780
rpc_request_duration_seconds_bucket{method="eth_getLogs",upstream="alchemy",le="+Inf"} 892
rpc_request_duration_seconds_sum{method="eth_getLogs",upstream="alchemy"} 45.2
rpc_request_duration_seconds_count{method="eth_getLogs",upstream="alchemy"} 892

Supported RPC Methods

Prism supports the following Ethereum JSON-RPC methods:

Cached Methods

These methods use Prism's caching system for improved performance:

Method
Cache Type
Description

eth_getBlockByHash

Block Cache

Get block by hash (with or without transactions)

eth_getBlockByNumber

Block Cache

Get block by number (with or without transactions)

eth_getLogs

Log Cache

Get event logs with partial-range support

eth_getTransactionByHash

Transaction Cache

Get transaction by hash

eth_getTransactionReceipt

Transaction Cache

Get transaction receipt

Forwarded Methods (No Caching)

These methods are forwarded directly to upstream providers:

Method
Description

net_version

Get network ID

eth_blockNumber

Get latest block number

eth_chainId

Get chain ID

eth_gasPrice

Get current gas price

eth_getBalance

Get account balance

eth_getCode

Get contract code


Request Format

All requests must conform to JSON-RPC 2.0 specification.

Structure

{
  "jsonrpc": "2.0",
  "method": "method_name",
  "params": [...],
  "id": 1
}
Field
Type
Required
Description

jsonrpc

string

Yes

Must be "2.0"

method

string

Yes

RPC method name (e.g., "eth_blockNumber")

params

array

No

Method parameters (can be empty [] or omitted)

id

number/string

Yes

Request identifier, echoed in response

Method-Specific Parameters

eth_getBlockByNumber

{
  "jsonrpc": "2.0",
  "method": "eth_getBlockByNumber",
  "params": [
    "0x1000000",  // Block number (hex) or "latest", "earliest", "pending"
    true          // Include full transaction objects (true) or hashes only (false)
  ],
  "id": 1
}

eth_getBlockByHash

{
  "jsonrpc": "2.0",
  "method": "eth_getBlockByHash",
  "params": [
    "0x1234567890abcdef...",  // Block hash (32 bytes, hex-encoded)
    false                      // Include transactions
  ],
  "id": 1
}

eth_getLogs

{
  "jsonrpc": "2.0",
  "method": "eth_getLogs",
  "params": [{
    "fromBlock": "0x1000000",  // Start block (hex) or "latest", "earliest"
    "toBlock": "0x1000100",    // End block (hex) or "latest", "earliest"
    "address": "0x1234...",    // Contract address or array of addresses
    "topics": [                // Event topics filter (optional)
      "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",  // Topic 0
      null,                                                                      // Topic 1 (any)
      "0x000000000000000000000000abcdef1234567890abcdef1234567890abcdef"       // Topic 2
    ]
  }],
  "id": 1
}

eth_getTransactionByHash

{
  "jsonrpc": "2.0",
  "method": "eth_getTransactionByHash",
  "params": [
    "0x1234567890abcdef..."  // Transaction hash (32 bytes, hex-encoded)
  ],
  "id": 1
}

eth_getTransactionReceipt

{
  "jsonrpc": "2.0",
  "method": "eth_getTransactionReceipt",
  "params": [
    "0x1234567890abcdef..."  // Transaction hash (32 bytes, hex-encoded)
  ],
  "id": 1
}

Response Format

All responses conform to JSON-RPC 2.0 specification.

Success Response

{
  "jsonrpc": "2.0",
  "result": <result_data>,
  "id": 1
}
Field
Type
Description

jsonrpc

string

Always "2.0"

result

any

Method-specific result data

id

number/string

Request ID echoed from request

Error Response

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32600,
    "message": "Invalid Request",
    "data": "Additional error information"
  },
  "id": 1
}
Field
Type
Description

jsonrpc

string

Always "2.0"

error.code

integer

Error code (see Error Codes)

error.message

string

Human-readable error message

error.data

any

Optional additional error data

id

number/string/null

Request ID or null if ID couldn't be determined


Custom Headers

Prism adds custom headers to responses for observability and debugging.

X-Cache-Status

Indicates how the request was served from cache or upstream.

Values:

Value
Meaning

MISS

Request served entirely from upstream (not in cache)

FULL

Complete cache hit, no upstream call needed

PARTIAL

Some data from cache, rest fetched from upstream

EMPTY

Cached empty result (e.g., no logs found in range)

PARTIAL_WITH_FAILURES

Partial cache hit with some upstream failures

Example:

HTTP/1.1 200 OK
Content-Type: application/json
X-Cache-Status: FULL

Request Headers

X-API-Key (Authentication)

Include your API key when authentication is enabled.

X-API-Key: your-api-key-here

Alternatively, use query parameter:

POST /?api_key=your-api-key-here

Standard Headers

Content-Type: application/json  # Required for POST requests
Accept: application/json         # Optional

Batch Requests

Send multiple requests in a single HTTP call to reduce latency.

Format

Array of JSON-RPC request objects:

[
  {
    "jsonrpc": "2.0",
    "method": "eth_getBlockByNumber",
    "params": ["0x1000000", false],
    "id": 1
  },
  {
    "jsonrpc": "2.0",
    "method": "eth_getLogs",
    "params": [{
      "fromBlock": "0x1000000",
      "toBlock": "0x1000010"
    }],
    "id": 2
  }
]

Response

Array of JSON-RPC response objects (order may not match request order):

[
  {
    "jsonrpc": "2.0",
    "result": { /* block data */ },
    "id": 1
  },
  {
    "jsonrpc": "2.0",
    "result": [ /* logs array */ ],
    "id": 2
  }
]

Benefits

  • Reduced HTTP overhead: Single connection for multiple requests

  • Lower latency: Batch processing reduces round-trip time

  • Atomic execution: All requests processed together

Limitations

  • Maximum batch size: Configured by max_concurrent_requests

  • Each request is still processed independently (no transaction semantics)

  • Cache status header applies to batch as a whole


Error Codes

Prism follows JSON-RPC 2.0 error codes with some extensions.

Standard JSON-RPC Errors

Code
Message
Description

-32700

Parse error

Invalid JSON received

-32600

Invalid Request

Request object is malformed

-32601

Method not found

Method does not exist or is not supported

-32602

Invalid params

Invalid method parameters

-32603

Internal error

Internal server error

Ethereum-Specific Errors

Code
Message
Description

-32000

Server error

Generic server error

-32001

Resource not found

Requested resource does not exist

-32002

Resource unavailable

Resource temporarily unavailable

-32003

Transaction rejected

Transaction would not be accepted

-32004

Method not supported

Method is not implemented

-32005

Limit exceeded

Request exceeds defined limit

Prism-Specific Errors

Code
Message
Description

-32050

No healthy upstreams

All upstream providers are unavailable

-32051

Circuit breaker open

Upstream circuit breaker is open

-32052

Consensus failure

Upstreams disagree on response (consensus mode)

-32053

Rate limit exceeded

Request rate limit exceeded

-32054

Authentication failed

Invalid or missing API key

-32055

Method not allowed

API key does not have permission for this method

Upstream Provider Errors

Errors from upstream providers are passed through with their original error codes.

Example Upstream Error:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32005,
    "message": "Query returned more than 10000 results",
    "data": "Try with a smaller block range"
  },
  "id": 1
}

Code Examples

JavaScript / Node.js

const axios = require('axios');

async function getBlockNumber() {
  const response = await axios.post('http://localhost:3030/', {
    jsonrpc: '2.0',
    method: 'eth_blockNumber',
    params: [],
    id: 1
  }, {
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': 'your-api-key-here'  // If auth enabled
    }
  });

  console.log('Block number:', response.data.result);
  console.log('Cache status:', response.headers['x-cache-status']);
}

getBlockNumber();

Python

import requests

def get_block_number():
    url = 'http://localhost:3030/'
    headers = {
        'Content-Type': 'application/json',
        'X-API-Key': 'your-api-key-here'  # If auth enabled
    }
    payload = {
        'jsonrpc': '2.0',
        'method': 'eth_blockNumber',
        'params': [],
        'id': 1
    }

    response = requests.post(url, json=payload, headers=headers)
    data = response.json()

    print(f"Block number: {data['result']}")
    print(f"Cache status: {response.headers.get('X-Cache-Status')}")

get_block_number()

cURL

# Simple request
curl -X POST http://localhost:3030/ \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

# Batch request (array to same / endpoint)
curl -X POST http://localhost:3030/ \
  -H "Content-Type: application/json" \
  -d '[
    {"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1},
    {"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":2}
  ]'

# Get logs with cache status
curl -s -D - http://localhost:3030/ \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_getLogs",
    "params": [{
      "fromBlock": "0x1000000",
      "toBlock": "0x1000100",
      "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
    }],
    "id": 1
  }' | grep -i cache-status

Rust (using reqwest)

use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();

    let response = client
        .post("http://localhost:3030/")
        .header("Content-Type", "application/json")
        .header("X-API-Key", "your-api-key-here")
        .json(&json!({
            "jsonrpc": "2.0",
            "method": "eth_blockNumber",
            "params": [],
            "id": 1
        }))
        .send()
        .await?;

    let cache_status = response
        .headers()
        .get("x-cache-status")
        .and_then(|v| v.to_str().ok());

    let body: serde_json::Value = response.json().await?;

    println!("Block number: {}", body["result"]);
    println!("Cache status: {:?}", cache_status);

    Ok(())
}

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

type JsonRpcRequest struct {
    Jsonrpc string        `json:"jsonrpc"`
    Method  string        `json:"method"`
    Params  []interface{} `json:"params"`
    ID      int           `json:"id"`
}

type JsonRpcResponse struct {
    Jsonrpc string          `json:"jsonrpc"`
    Result  json.RawMessage `json:"result"`
    ID      int             `json:"id"`
}

func main() {
    req := JsonRpcRequest{
        Jsonrpc: "2.0",
        Method:  "eth_blockNumber",
        Params:  []interface{}{},
        ID:      1,
    }

    payload, _ := json.Marshal(req)
    httpReq, _ := http.NewRequest("POST", "http://localhost:3030/", bytes.NewBuffer(payload))
    httpReq.Header.Set("Content-Type", "application/json")
    httpReq.Header.Set("X-API-Key", "your-api-key-here")

    client := &http.Client{}
    resp, _ := client.Do(httpReq)
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)
    var response JsonRpcResponse
    json.Unmarshal(body, &response)

    fmt.Printf("Block number: %s\n", response.Result)
    fmt.Printf("Cache status: %s\n", resp.Header.Get("X-Cache-Status"))
}

Web3 Library Integration

Prism can be used as a drop-in replacement for any Ethereum RPC endpoint.

ethers.js

const { ethers } = require('ethers');

const provider = new ethers.JsonRpcProvider('http://localhost:3030/', {
  name: 'mainnet',
  chainId: 1
});

// Use like any other provider
const blockNumber = await provider.getBlockNumber();
console.log('Block number:', blockNumber);

const block = await provider.getBlock(blockNumber);
console.log('Block:', block);

web3.py

from web3 import Web3

w3 = Web3(Web3.HTTPProvider('http://localhost:3030/'))

# Use like any other Web3 instance
block_number = w3.eth.block_number
print(f'Block number: {block_number}')

block = w3.eth.get_block(block_number)
print(f'Block: {block}')

web3.js

const Web3 = require('web3');

const web3 = new Web3('http://localhost:3030/');

// Use like any other Web3 instance
web3.eth.getBlockNumber().then(blockNumber => {
  console.log('Block number:', blockNumber);
});

web3.eth.getBlock(18500000).then(block => {
  console.log('Block:', block);
});

Next: Learn about Caching or Routing Strategies.

Last updated