Pars CloudPars Cloud

Authentication

Every request to the Pars Cloud API must be authenticated. This guide covers how to get your API key, use it in requests, handle rate limits, and manage errors.

1

Get Your API Key

Sign in to your Pars Cloud dashboard at cloud.pars.network and navigate to Settings → API Keys.

Key types

PrefixEnvironmentUse for
$bn_live_ProductionLive mainnet requests
$bn_test_TestnetDevelopment and testing (testnets only)

Security

Never expose your API key in client-side code, public repositories, or browser network requests. Always use server-side code or environment variables.

# .env.local (Next.js, Vite, etc.)
BOOTNODE_API_KEY=bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

# Never commit this file to version control.
# Add .env.local to your .gitignore.
2

Use the X-API-Key Header

The recommended authentication method. Pass your API key in the X-API-Key header.

# curl
curl https://api.bootno.de/v1/gas/ethereum/prices \
  -H "X-API-Key: bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

# TypeScript / fetch
const res = await fetch("https://api.bootno.de/v1/gas/ethereum/prices", {
  headers: {
    "X-API-Key": process.env.BOOTNODE_API_KEY!,
  },
});

# Python / requests
import requests
res = requests.get(
    "https://api.bootno.de/v1/gas/ethereum/prices",
    headers={"X-API-Key": "bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"},
)

# Go / net/http
req, _ := http.NewRequest("GET", "https://api.bootno.de/v1/gas/ethereum/prices", nil)
req.Header.Set("X-API-Key", "bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6")
3

Use the Authorization Bearer Header

Alternatively, use the standard Bearer token format. Both methods are equivalent.

# curl
curl https://api.bootno.de/v1/gas/ethereum/prices \
  -H "Authorization: Bearer bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

# TypeScript / fetch
const res = await fetch("https://api.bootno.de/v1/gas/ethereum/prices", {
  headers: {
    Authorization: `Bearer ${process.env.BOOTNODE_API_KEY}`,
  },
});

# Python / requests
import requests
res = requests.get(
    "https://api.bootno.de/v1/gas/ethereum/prices",
    headers={"Authorization": "Bearer bn_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"},
)
4

Rate Limiting

All API responses include rate limit headers. When you exceed your limit, the API returns HTTP 429.

PlanRequests / secRequests / dayCompute Units / sec
Free10100,000200
Growth1005,000,0002,000
EnterpriseCustomCustomCustom

Response headers:

X-RateLimit-Limit: 100          # Max requests per second
X-RateLimit-Remaining: 97       # Remaining in current window
X-RateLimit-Reset: 1706400000   # Unix timestamp when window resets
Retry-After: 1                  # Seconds to wait (only on 429)

Different methods consume different compute units (CU). Simple reads like eth_blockNumber cost 1 CU, while archive calls like eth_getStorageAt with a historical block cost 20 CU.

5

Error Handling

Pars Cloud returns structured error responses. Always check the HTTP status code and handle errors gracefully with retries for transient failures.

// Robust API client with retry logic
async function bootnodeRequest(
  path: string,
  options: RequestInit = {}
): Promise<any> {
  const maxRetries = 3;
  const baseDelay = 1000; // 1 second

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fetch(`https://api.bootno.de/v1${path}`, {
      ...options,
      headers: {
        "X-API-Key": process.env.BOOTNODE_API_KEY!,
        "Content-Type": "application/json",
        ...options.headers,
      },
    });

    // Success
    if (res.ok) {
      return res.json();
    }

    // Parse error
    const error = await res.json().catch(() => ({
      error: { code: "unknown", message: res.statusText, status: res.status },
    }));

    // Don't retry client errors (except rate limits)
    if (res.status !== 429 && res.status < 500) {
      throw new Error(
        `Bootnode API error [${error.error.code}]: ${error.error.message}`
      );
    }

    // Retry with exponential backoff
    if (attempt < maxRetries) {
      const retryAfter = res.headers.get("Retry-After");
      const delay = retryAfter
        ? parseInt(retryAfter, 10) * 1000
        : baseDelay * Math.pow(2, attempt);
      console.warn(
        `Bootnode request failed (attempt ${attempt + 1}/${maxRetries + 1}), ` +
        `retrying in ${delay}ms...`
      );
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }

  throw new Error("Bootnode API: max retries exceeded");
}

// Usage:
// const prices = await bootnodeRequest("/gas/ethereum/prices");
// const wallet = await bootnodeRequest("/wallets/create", {
//   method: "POST",
//   body: JSON.stringify({ owner: "0x...", chain: "base" }),
// });

Error Response Format

// 401 Unauthorized
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key. Check your X-API-Key header.",
    "status": 401
  }
}

// 429 Rate Limited
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after 1 second.",
    "status": 429
  }
}

// 400 Bad Request
{
  "error": {
    "code": "invalid_request",
    "message": "Missing required parameter: chain",
    "status": 400
  }
}

API Key Scopes

When creating an API key, you can restrict it to specific scopes for least-privilege access:

ScopeAccess
rpc:readJSON-RPC read methods (eth_call, eth_getBalance, etc.)
rpc:writeJSON-RPC write methods (eth_sendRawTransaction)
data:readToken, NFT, and transfer APIs
wallets:manageCreate and manage smart wallets
webhooks:manageCreate, update, and delete webhooks
gas:manageGas policies and sponsorship
bundler:sendSubmit UserOperations to the bundler

Next Steps