Olenza Node — JSON-RPC
Direct JSON-RPC to our own full nodes for every chain. No node to run yourself.
Machine-readable: OpenAPI 3.1 · these docs as markdown · llms.txt
Endpoint
POST https://node.olenza.io/v1/rpc/{chain}
Chains: btc, ltc, zec, dcr, xmr. The body is a standard JSON-RPC request, or an array of them for a batch. Monero (xmr) takes one call per request: monerod does not accept batches, so the gateway refuses an array for it with INVALID_REQUEST, not counted.
Authentication
Send your API key in a header:
X-API-Key: olz_…
Authorization: Bearer olz_… (either one)
If your client cannot set headers, put the key in the path: https://node.olenza.io/v1/rpc/{chain}/olz_…. Prefer the header: our servers never log the path or the full key, but your own tools, proxies and browser history may keep a URL. The same key works for the Explorer API (header only there).
Examples
Each chain speaks its own node's dialect — the gateway does not translate. One example per dialect:
Bitcoin-style RPC — BTC, LTC, ZEC, DCR
curl https://node.olenza.io/v1/rpc/btc \
-H "X-API-Key: $OLENZA_KEY" \
--data '{"jsonrpc":"1.0","id":1,"method":"getblockcount","params":[]}'
Example response
{"result":969857,"error":null,"id":1}Monero daemon RPC — XMR
curl https://node.olenza.io/v1/rpc/xmr \
-H "X-API-Key: $OLENZA_KEY" \
--data '{"jsonrpc":"2.0","id":"0","method":"get_block_count"}'
Example response
{"id":"0","jsonrpc":"2.0","result":{"count":3776747,"status":"OK","untrusted":false}}Opening an endpoint in a browser shows a short help page; a GET from code is refused with 405 USE_POST.
Limits and headers
Once your key is recognised, every response — answers and refusals alike — carries your current limits. Refusals before that (401, an unknown chain, TOO_MANY_INVALID_KEYS) do not.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your burst size |
X-RateLimit-Remaining | Requests you can send right now |
X-RateLimit-Reset | Seconds until the burst is fully refilled (not a timestamp) |
X-Quota-Daily-Remaining | Units left today (UTC) |
X-Quota-Monthly-Remaining | Units left this month (UTC) |
X-Quota-Key-Daily-Remaining | Units left today on this key, when you set a per-key daily cap |
X-Request-Id | A unique id for this request, on every response — quote it if you contact support |
Errors
Errors are JSON-RPC error objects. error.data.reason is a stable code:
| HTTP | Reason | What to do |
|---|---|---|
| 401 | MISSING_API_KEY, INVALID_API_KEY | Check the key |
| 403 | KEY_REVOKED | The key was revoked — create a new one |
| 403 | ACCOUNT_SUSPENDED | Email support@olenza.io with your account email and the X-Request-Id of a failed call |
| 403 | CHAIN_NOT_IN_PLAN, PLAN_UNAVAILABLE | Your account does not cover this — contact support |
| 403 | METHOD_NOT_ALLOWED | The method is not available — see the list below |
| 404 | CHAIN_NOT_FOUND | Check the chain in the URL |
| 405 | USE_POST | The endpoint was called with GET — send a POST with a JSON-RPC body |
| 400 | INVALID_REQUEST, BATCH_TOO_LARGE, INVALID_PARAMS | Fix the request (a batch sent to Monero is INVALID_REQUEST: send one call per request) |
| 400 | RANGE_TOO_LARGE | Ask for a smaller range and page through it (at most 1,000 blocks for Monero header ranges; on Decred 100 blocks or 10 windows for ticketfeeinfo/txfeeinfo, a 1,440-block txfeeinfo range, 10,000 for ticketvwap; per request, summed over a batch: at most 50,000 key derivations for the descriptors of deriveaddresses/utxoupdatepsbt, and one gettreasuryspendvotes call (Decred) listing at most 4 treasury spends) |
| 413 | REQUEST_TOO_LARGE | Send a smaller request |
| 429 | RATE_LIMITED | Wait Retry-After seconds |
| 429 | TOO_MANY_CONCURRENT | Too many of your calls are running at once — wait for one to finish |
| 429 | TOO_MANY_INVALID_KEYS | Too many unknown keys from your address — fix the key, then wait Retry-After seconds |
| 429 | DAILY_QUOTA_EXCEEDED, MONTHLY_QUOTA_EXCEEDED, KEY_DAILY_QUOTA_EXCEEDED | Wait for the next UTC day/month |
| 502 | NODE_ERROR | Retry shortly; not counted, unless the call ran past the time limit |
| 502 | RESPONSE_TOO_LARGE | The answer is over 64 MB — ask for less; counted, since the node did the work |
| 503 | NODE_BUSY, NODE_SYNCING, NODE_UNAVAILABLE, SERVICE_UNAVAILABLE | Retry shortly; not counted |
| 503 | GATEWAY_BUSY | We are at capacity — wait Retry-After seconds. Not counted, unless the answer had already passed 1 MB |
Errors returned by the node itself (for example "Block not found") are passed through unchanged.
Using the API means accepting the Terms of Service — in short: one free account per person, no reselling raw access, no getting around limits.
Available methods
Only these methods are available — wallet, peer, node-control and UTXO-set scan methods are not. Every call counts as one unit.
BTC · bitcoin dialect · 45 methods · Bitcoin RPC page
analyzepsbtcombinepsbtcombinerawtransactionconverttopsbtcreatemultisigcreatepsbtcreaterawtransactiondecodepsbtdecoderawtransactiondecodescriptderiveaddressesestimatesmartfeefinalizepsbtgetbestblockhashgetblockgetblockchaininfogetblockcountgetblockhashgetblockheadergetblockstatsgetchaintipsgetchaintxstatsgetdeploymentinfogetdescriptorinfogetdifficultygetindexinfogetmempoolancestorsgetmempooldescendantsgetmempoolentrygetmempoolinfogetmininginfogetnetworkhashpsgetrawmempoolgetrawtransactiongettxoutgettxoutproofgettxspendingprevoutjoinpsbtssendrawtransactionsubmitpackagetestmempoolacceptutxoupdatepsbtvalidateaddressverifymessageverifytxoutproof
LTC · bitcoin dialect · 42 methods · Litecoin RPC page
analyzepsbtcombinepsbtcombinerawtransactionconverttopsbtcreatemultisigcreatepsbtcreaterawtransactiondecodepsbtdecoderawtransactiondecodescriptderiveaddressesestimatesmartfeefinalizepsbtgetbestblockhashgetblockgetblockchaininfogetblockcountgetblockhashgetblockheadergetblockstatsgetchaintipsgetchaintxstatsgetdescriptorinfogetdifficultygetindexinfogetmempoolancestorsgetmempooldescendantsgetmempoolentrygetmempoolinfogetmininginfogetnetworkhashpsgetrawmempoolgetrawtransactiongettxoutgettxoutproofjoinpsbtssendrawtransactiontestmempoolacceptutxoupdatepsbtvalidateaddressverifymessageverifytxoutproof
ZEC · bitcoin dialect · 18 methods · zebrad speaks the Bitcoin dialect. Transparent (t-) addresses only: shielded balances are private by design. getaddresstxids on a busy address is slow; at most 16 addresses per call. zebrad has no fee-estimate method (no estimatefee): Zcash uses the ZIP-317 conventional fee, 5,000 zatoshis per logical action with a minimum of 10,000. · Zcash RPC page
getaddressbalancegetaddresstxidsgetaddressutxosgetbestblockhashgetblockgetblockchaininfogetblockcountgetblockhashgetblockheadergetblocksubsidygetdifficultygetmininginfogetnetworksolpsgetrawmempoolgetrawtransactionsendrawtransactionvalidateaddressz_validateaddress
DCR · bitcoin dialect · 47 methods · dcrd, the Bitcoin dialect plus Decred's staking calls (tickets, votes, treasury). No address history index: use existsaddress or ticketsforaddress. · Decred RPC page
createrawtransactiondecoderawtransactiondecodescriptestimatefeeestimatesmartfeeestimatestakediffexistsaddressexistsaddressesexistsliveticketexistsliveticketsexistsmempooltxsgetbestblockgetbestblockhashgetblockgetblockchaininfogetblockcountgetblockhashgetblockheadergetblocksubsidygetcfilterv2getchaintipsgetcoinsupplygetcurrentnetgetdifficultygetheadersgetmempoolinfogetmininginfogetnetworkhashpsgetrawmempoolgetrawtransactiongetstakedifficultygetstakeversioninfogetstakeversionsgetticketpoolvaluegettreasurybalancegettreasuryspendvotesgettxoutgetvoteinfoliveticketssendrawtransactionticketfeeinfoticketsforaddressticketvwaptxfeeinfovalidateaddressverifymessageversion
XMR · monero dialect · 16 methods · monerod JSON-RPC. Only /json_rpc methods are available; monerod's separate binary endpoints (/get_outs, /getblocks.bin) are not, so a light wallet cannot sync through this route. · Monero RPC page
get_alternate_chainsget_blockget_block_countget_block_header_by_hashget_block_header_by_heightget_block_headers_rangeget_coinbase_tx_sumget_fee_estimateget_infoget_last_block_headerget_miner_dataget_output_distributionget_output_histogramget_versionhard_fork_infoon_get_block_hash
Olenza Explorer — REST
Blocks, transactions and addresses as JSON, from the same indexes as the explorer site.
Machine-readable: OpenAPI 3.1 · per-chain reference with live samples: explorer.olenza.io/api
Endpoint
GET https://explorer.olenza.io/api/v1/{chain}/…
Chains: btc, ltc, zec, dcr, xmr. GET, except the one endpoint that takes a secret (outputs/check, a POST); answers are application/json.
Authentication
Send your API key in the X-API-Key header (or Authorization: Bearer). The same key works for Olenza Node. Keys are never accepted in the URL — URLs end up in logs.
Use of the API is covered by the Terms of Service.
curl -H "X-API-Key: $OLENZA_KEY" https://explorer.olenza.io/api/v1/btc/status
Chains do not all work the same way
A Bitcoin transaction consumes outputs and creates new ones. A Monero transaction hides its amounts and recipients on purpose. Forcing both into one shape would mean lying about one of them, so the API has two shapes and /status says which one a chain answers with, in family:
family | Chains | What a transaction looks like | Addresses |
|---|---|---|---|
utxo | btc ltc zec dcr | Inputs and outputs, each with an amount and addresses | Balance, history, unspent outputs |
ring | xmr | Key images, the ring each input hides in, one-time output keys. Amounts appear only where the protocol makes them public | None. A Monero address never appears on the chain |
An endpoint a chain's family does not have answers 404 NOT_ON_THIS_CHAIN and says why. It is a fact about the chain, not a failure.
Basics
- Amounts are strings in the coin's smallest unit. Divide by 10decimals —
decimalsis in/status. Strings, because some totals do not fit a 64-bit integer and JavaScript loses precision above 253. - A field that does not apply to a chain is left out, never
null. - Paging:
pageandpage_size.
Limits and errors
Every call counts as one unit, whatever the endpoint, and once against the per-second rate limit. The Explorer API has its own limits, separate from Olenza Node (see Limits). Every response carries the same X-RateLimit-*, X-Quota-* and X-Request-Id headers as Node (see the Node tab). 5xx the explorer fails to answer are not counted, except 504 UPSTREAM_TIMEOUT, which is counted like any call that runs past the time limit; a 404 for something that does not exist is an answer and is counted.
{"error": {"reason": "NOT_FOUND", "message": "transaction not found"}}
| HTTP | reason | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Malformed height, hash, address or parameter. |
| 401 | MISSING_API_KEY, INVALID_API_KEY | No key, or not a valid key. |
| 403 | KEY_REVOKED, ACCOUNT_SUSPENDED, CHAIN_NOT_IN_PLAN | The key or account cannot use this. |
| 404 | NOT_FOUND | No such block, transaction or address. |
| 404 | CHAIN_NOT_FOUND, ENDPOINT_NOT_FOUND | Unknown chain or path. |
| 404 | NOT_ON_THIS_CHAIN | This chain's family has no such thing — see the table above. |
| 429 | RATE_LIMITED, DAILY_QUOTA_EXCEEDED, MONTHLY_QUOTA_EXCEEDED, KEY_DAILY_QUOTA_EXCEEDED, TOO_MANY_CONCURRENT, TOO_MANY_INVALID_KEYS | Slow down; Retry-After says for how long. |
| 503 | GATEWAY_BUSY | We are at capacity; retry after Retry-After seconds. |
| 502, 503, 504 | UPSTREAM_ERROR, SERVICE_UNAVAILABLE, UPSTREAM_TIMEOUT | Our side; not counted unless the call ran past the time limit. Retry shortly. |
Endpoints
Base https://explorer.olenza.io/api/v1/{chain}/…. Which endpoints a chain answers depends on its family. Try any of them against a chain with your key, or browse the explorer site.
Every chain
| Endpoint | Returns |
|---|---|
GET /{chain}/status | Chain tip, sync state, symbol, decimals, mempool size, and family. |
GET /{chain}/blocks | Latest blocks, newest first (limit, start). |
GET /{chain}/block/{height|hash} | One block's header and transaction count. |
GET /{chain}/block/{height|hash}/txs | A block's transactions. |
GET /{chain}/tx/{hash} | One transaction, in the chain family's shape. |
GET /{chain}/mempool | Transactions waiting to be mined. |
GET /{chain}/search/{query} | What a height, hash or address is. |
utxo chains
| Endpoint | Returns |
|---|---|
GET /{chain}/address/{address} | Balance, total received and sent, transaction count. |
GET /{chain}/address/{address}/txs | An address's transactions, newest first. |
GET /{chain}/address/{address}/utxo | Unspent outputs (largest first; at most 1000, with a count). |
ring chains (Monero)
| Endpoint | Returns |
|---|---|
POST /{chain}/tx/{hash}/outputs/check | Which outputs of a transaction belong to an address — you supply a viewkey or txkey. POST so the key stays out of logs; nothing is stored. |
Monero has no address lookup: an address never appears on the chain.
Example responses
Real answers from Bitcoin, trimmed where a list is long. Other utxo chains answer in the same shape; ring chains add a ring object to /status and use their own transaction shape.
GET /btc/status
{
"chain": "btc", "name": "Bitcoin", "symbol": "BTC", "decimals": 8,
"family": "utxo",
"height": 969857,
"best_hash": "00000000000000000000ead5f66b412664314405c5cbf8eec247f8fb414f050c",
"difficulty": 132716002350731.3,
"in_sync": true,
"node_version": "/Satoshi:27.1.0/",
"mempool_count": 3456
}GET /btc/address/{address}
{
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"balance": "10749121007",
"received": "10749121007",
"sent": "0",
"tx_count": 66717,
"unconfirmed": "42303"
}GET /btc/tx/{hash} (outputs trimmed)
{
"txid": "04453bd51515e7014016d1ea328ee1f731185688e60e274a5058b6e72472ed7d",
"block_hash": "00000000000000000000ead5f66b412664314405c5cbf8eec247f8fb414f050c",
"block_height": 969857,
"confirmations": 1,
"time": 1791121118,
"vsize": 346,
"vin": [
{"n": 0, "txid": "cc628ec46a68300b2d8ad0dafb00897c0a8186c9311919be0d8aa57e9fa9b344",
"vout": 9, "value": "134605279", "addresses": ["1KdCveSZfa6AKqNwod25fWXGhLDs3aLyDD"]}
],
"vout": [
{"n": 0, "value": "55152", "addresses": ["bc1qahz063em92csjdfauvvh7vvmex4sm7kae7t4v4"]},
{"n": 5, "value": "127130057", "addresses": ["1Nb9NUVWpjruzafXh2uKK5v5xxEEL1hPrH"]}
],
"value_in": "134605279",
"value_out": "134598039",
"fee": "7240"
}An error
HTTP/2 404
{"error": {"reason": "NOT_FOUND", "message": "transaction not found"}}