Summary
The Celo API is a JSON-RPC interface that lets your application read chain state, submit transactions, and subscribe to events on Celo Mainnet. You connect to it through an HTTPS endpoint using standard EVM methods such as eth_blockNumber, eth_getBalance, and eth_call, plus Celo-specific calls for fee currencies and mobile-friendly gas abstraction. This article covers the chain settings you need, how to send your first request, and how to diagnose the failures developers hit most often. It also explains when a shared public endpoint is enough and when a dedicated Celo node is the better fit for production workloads.
The Celo API is the JSON-RPC interface your application uses to talk to Celo Mainnet. If you searched for "celo api", you probably need one of three things: the correct chain settings to add Celo to a wallet, a working endpoint to send your first request, or a way to debug why a request is failing. This page answers all three, then helps you decide whether a shared endpoint is enough or whether your workload needs a dedicated Celo node.
Celo is an EVM-compatible Layer 1, so most of your Ethereum tooling works without modification. The differences that matter are chain ID, the native currency symbol, and Celo-specific methods around fee currencies and gas abstraction. Get those right and the rest is standard JSON-RPC.
Chain settings at a glance
Before you write any code, confirm the network parameters. These are the values you enter in a wallet, a Hardhat config, or a viem chain definition.
| Setting | Value |
|---|---|
| Network name | Celo Mainnet |
| Chain ID | 42220 |
| Native currency | CELO (18 decimals) |
| RPC transport | HTTP |
| Block explorer | https://celoscan.io |
| Public endpoint | https://celo.api.onfinality.io/public |
If you are adding Celo to a wallet, use the network name and chain ID exactly as shown. A mismatched chain ID is the single most common reason a wallet refuses to sign or a dApp reports "wrong network".
For a managed endpoint you can use in development, OnFinality exposes a public Celo RPC URL. For production traffic, review RPC pricing and the Celo network page to pick a plan that matches your request volume.
Sending your first Celo API request
Every Celo API call is a POST request with a JSON body containing jsonrpc, method, params, and id. Start with eth_chainId to confirm you are connected to the right network, then eth_blockNumber to check that the node is synced.
curl -X POST https://celo.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_chainId",
"params": [],
"id": 1
}'
The response returns the chain ID in hex. For Celo Mainnet that is 0xa4ec, which is 42220 in decimal. If you get a different value, you are pointed at the wrong network.
Once the chain ID checks out, query a balance and read a contract:
curl -X POST https://celo.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": ["0xYourAddressHere", "latest"],
"id": 2
}'
eth_call works the same way as on Ethereum. Pass the to address, the encoded function data, and the block tag. Celo's EVM compatibility means ABI encoding libraries such as ethers and viem work without special handling.
Connecting from JavaScript
If you prefer a client library, viem and ethers both support Celo through a custom chain definition. The example below uses viem and points at the public endpoint.
import { createPublicClient, http, defineChain } from "viem";
const celo = defineChain({
id: 42220,
name: "Celo Mainnet",
nativeCurrency: { name: "CELO", symbol: "CELO", decimals: 18 },
rpcUrls: {
default: { http: ["https://celo.api.onfinality.io/public"] },
},
blockExplorers: {
default: { name: "Celoscan", url: "https://celoscan.io" },
},
});
const client = createPublicClient({ chain: celo, transport: http() });
const blockNumber = await client.getBlockNumber();
const balance = await client.getBalance({ address: "0xYourAddressHere" });
console.log({ blockNumber, balance });
For wallet-based apps, the same values go into wallet_addEthereumChain. Keep the chain ID and RPC URL consistent between your wallet config and your backend so users do not see network-switch prompts mid-session.
When a public endpoint is enough, and when it is not
A shared public endpoint is fine for local development, prototypes, and low-volume read paths. It is a poor fit once you have real users, because you share throughput with everyone else and cannot control latency spikes.
Use this table to decide what your workload actually needs.
| Workload | Shared public endpoint | Dedicated Celo node |
|---|---|---|
| Local development and testing | Good fit | Unnecessary |
| Prototype with a handful of users | Usually fine | Optional |
| Production dApp with steady traffic | Risky under load | Recommended |
| Indexer or backend worker | Not suitable | Recommended |
| Wallet with many concurrent users | Not suitable | Recommended |
| Archive or historical queries | Usually unavailable | Required |
If you are unsure where you land, start with the RPC provider selection guide and then compare plans on the pricing page. OnFinality offers both shared RPC API access and dedicated nodes for teams that need isolated capacity.
Celo-specific methods worth knowing
Because Celo was designed for mobile payments, it adds methods that Ethereum does not have. Two are worth knowing early.
eth_gasPrice returns a gas price, but Celo also supports paying gas in approved ERC-20 tokens. If your app lets users pay fees in a stablecoin, you will interact with the fee-currency contract rather than only the native CELO balance. Read the current fee currency before constructing a transaction, and check the account has enough of that token.
Celo also supports eth_getLogs with the same filter shape as Ethereum. If you are indexing events, keep block ranges modest and paginate. Large unbounded log queries are a common cause of timeouts on any provider, not just Celo.
Debug path for common Celo API errors
Most Celo API problems fall into a small set of categories. Work through them in order.
| Symptom | Likely cause | What to do |
|---|---|---|
eth_chainId returns the wrong value | Endpoint points at another network | Recheck the URL and chain ID 42220 |
-32601 method not found | Method not supported by the node | Confirm the method name and node type |
-32000 on eth_getLogs | Block range too large | Reduce the range and paginate |
| Transaction stuck pending | Gas price too low or nonce gap | Recheck nonce and fee settings |
429 responses | Rate limited on a shared endpoint | Move to a dedicated plan |
| Balance reads fail for a token | Wrong contract or decimals | Verify the token address and ABI |
Start every debug session by confirming the chain ID. If that is correct, check whether the failing call is a read or a write. Reads usually fail because of malformed parameters or oversized queries. Writes usually fail because of nonce, gas, or fee-currency issues.
For a broader checklist that applies across networks, see the RPC endpoints guide.
Running your own node versus using a managed Celo API
Some teams consider running their own Celo node. It is a legitimate option, but the operational cost is easy to underestimate. You need to provision hardware, keep the client updated through network upgrades, monitor disk growth, and handle failover when the node falls behind.
A managed Celo API removes that maintenance. You get an endpoint, and the provider handles upgrades, monitoring, and availability. The tradeoff is that you depend on the provider's infrastructure, which is why failover planning matters.
A practical middle ground for production apps is to use a primary managed endpoint and keep a second provider or a self-hosted node as a fallback. Configure your client to retry against the secondary endpoint when the primary returns repeated errors. This is simpler than running two nodes yourself and covers the most common outage scenario.
Production readiness checklist
Before you ship, confirm each of these.
- Chain ID is hardcoded to 42220 and validated at startup.
- The RPC URL comes from environment configuration, not source code.
- You have a fallback endpoint and a retry policy with backoff.
- Log queries are paginated and bounded.
- You monitor error rates and latency, not just uptime.
- Fee-currency logic is tested if users pay gas in tokens.
- You have reviewed RPC pricing against expected request volume.
A simple monitoring probe that checks chain ID and block height catches most connectivity problems before users do:
async function healthCheck(url) {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_blockNumber",
params: [],
id: 1,
}),
});
const data = await res.json();
return parseInt(data.result, 16);
}
Run this on a schedule and alert when the block height stops advancing. A stalled height is a clearer signal than a failed HTTP request.
Key Takeaways
- Celo is EVM-compatible, so standard Ethereum JSON-RPC methods work with chain ID 42220.
- Always verify
eth_chainIdbefore debugging anything else. - Shared public endpoints suit development; production workloads benefit from dedicated capacity.
- Celo's fee-currency model adds token-gas logic that Ethereum apps do not have.
- Paginate
eth_getLogsand monitor block height, not just HTTP status. - Plan a fallback endpoint before launch, not after an incident.
Frequently Asked Questions
What is the Celo API?
It is the JSON-RPC interface for Celo Mainnet. You send POST requests to an endpoint and receive chain data or submit transactions using standard EVM methods.
What is the Celo chain ID?
Celo Mainnet uses chain ID 42220, which is 0xa4ec in hex.
Can I use Ethereum tools with Celo?
Yes. Because Celo is EVM-compatible, libraries like ethers, viem, and Hardhat work with a custom chain definition that sets the chain ID and RPC URL.
Why does my Celo request return a 429 error?
A 429 means you are being rate limited, which is common on shared public endpoints under load. Moving to a dedicated plan or reducing request bursts usually resolves it.
Does Celo support paying gas in stablecoins?
Celo supports paying gas in approved fee currencies. Your app needs to read the fee-currency contract and confirm the account holds enough of that token before sending a transaction.
Should I run my own Celo node?
Run your own node if you need full control or archive data and can absorb the maintenance. Otherwise a managed Celo API plus a fallback endpoint is usually simpler for production apps.
If you want to move from a public endpoint to managed infrastructure, start on the Celo network page, compare RPC plans, and review the full list of supported RPC networks if you operate across multiple chains.