RPC reference
The NOXY public /v0 HTTP API: submit transactions, read accounts and activity, fetch transaction proofs, and talk to the EVM lane over eth JSON-RPC.
RPC reference
The public API is a JSON-over-HTTP facade in front of the node. On the testnet it is served at https://test.noxycore.io. A self-hosted noxy-public-api binds to 0.0.0.0:8080 by default and talks to the node's local read (:9360) and submit (:9350) RPC ports.
Every response is JSON. Native account and asset IDs are 64-character lowercase hex; uppercase native IDs are rejected with a 400. EVM addresses (0x + 40 hex) are accepted case-insensitively and echoed lowercase.
Errors
All non-EVM endpoints share one error envelope:
{ "error": "account not found", "variant": "not_found" }
variant is a stable machine-readable string. The ones you will meet most: bad_request, hash, limit, cursor, asset, level, not_found, rate_limit, upstream_busy, unavailable, upstream, internal, preverify, auth, insufficient, nonce_mismatch.
Rate limiting is per client IP: a token bucket refilling at 20 requests/second with a burst of 50, plus a global in-flight cap. Over budget returns 429 with variant: rate_limit; no Retry-After header is sent. A 429 with variant: upstream_busy is different: the node itself is applying backpressure.
Health and identity
curl https://test.noxycore.io/v0/health
# { "status": "ok" }
curl https://test.noxycore.io/v0/node/identity
{
"chain_id": "veylith-testnet-10",
"genesis_hash_hex": "…",
"native_asset_id_hex": "…",
"protocol_version": 4,
"release_version": "0.1.x",
"commit_sha": "…",
"node_role": "…"
}
/v0/health always answers 200 and never touches the node, so it only tells you the facade is up. /v0/economics/summary currently returns just { "native_asset_id_hex": "…" }.
Network stats
curl https://test.noxycore.io/v0/network/stats
{
"chain_id": "veylith-testnet-10",
"genesis_hash_hex": "…",
"protocol_version": 4,
"node_role": "…",
"release_version": "0.1.x",
"checkpoint": {
"height": 84,
"ordered_sequence_end": 12040,
"state_root_hex": "…",
"ordered_log_root_hex": "…"
},
"validators": { "count": 4, "fault_bound": 1, "quorum": 3 },
"evm": {
"chain_id_numeric": 20057,
"window_gas_ceiling": 30000000,
"base_fee_wei": "1000000000",
"time_anchor_unix_secs": 1785173149,
"millis_per_round": 250
}
}
checkpoint is null until the first durable checkpoint. evm is null on a chain without the EVM lane; on the testnet it carries chain_id_numeric, window_gas_ceiling, base_fee_wei (decimal string), time_anchor_unix_secs, and millis_per_round. An indexed object with activity_rows appears when the node has a read-model attached.
Accounts
# Account record — "account" is null if the account does not exist (never 404)
curl https://test.noxycore.io/v0/account/{id_hex}
# { "account": { "account_id_hex": "…", "account_type": "User",
# "status": "Active", "sequence_nonce": 7,
# "primary_key_id_hex": "…" } }
# Next nonce to use — 404 if the account is unknown
curl https://test.noxycore.io/v0/account/{id_hex}/nonce
# { "nonce": 7 }
# Balance of one asset — "0" if the account holds none
curl https://test.noxycore.io/v0/account/{id_hex}/balance/{asset_id_hex}
# { "amount_decimal": "100000000000" }
Balance is a decimal string of base units. The chain is single-asset today: passing any asset ID other than the native one returns 400 with variant: asset.
The same /v0/account/{id} route also serves the EVM side of account duality. Pass a 0x + 40-hex address and the response becomes:
{
"account": {
"domain": "evm",
"address_hex": "0x…",
"balance_wei": "0",
"nonce": 0,
"is_contract": false,
"code_hash_hex": "…"
}
}
A never-seen EVM address returns the zero account rather than 404. The /nonce and /balance sub-routes accept native IDs only.
Activity
curl 'https://test.noxycore.io/v0/account/{id_hex}/activity?limit=25'
{
"account_id_hex": "…",
"limit": 25,
"next_cursor": "…",
"activities": [
{
"cursor": "…",
"tx_hash_hex": "…",
"block_height": 84,
"tx_index": 0,
"tx_type": "Transfer",
"account_role": "sender",
"accepted": true,
"fee_charged_decimal": "1200",
"state_version": 12040,
"events_count": 2,
"transfers": [
{
"direction": "sent",
"counterparty_account_id_hex": "…",
"asset_id_hex": "…",
"amount_decimal": "1000000000"
}
]
}
]
}
limit is 1 to 100 (default 25). Pass next_cursor back as ?cursor= to page; next_cursor is null on the last page. A node without a read-model attached answers 200 with an empty activities array rather than an error.
Submit a transaction
curl -X POST https://test.noxycore.io/v0/tx/submit \
-H 'content-type: application/json' \
-d '{"envelope_bytes_base64":"<base64 canonical TransactionEnvelope>"}'
Success returns 202:
{ "tx_hash_hex": "9f2c…", "relay_status": "queued" }
Failures and their codes:
| Code | variant | Cause |
|---|---|---|
| 400 | preverify | invalid base64, oversized envelope, or an envelope the node rejects as malformed |
| 401 | auth | signature check failed |
| 402 | insufficient | balance below fee or transfer amount |
| 409 | nonce_mismatch | envelope nonce ≠ account sequence nonce |
| 429 | upstream_busy | node is applying backpressure |
| 413 | — | body over the 256 KiB route cap |
Transaction status
curl https://test.noxycore.io/v0/tx/{hash_hex}
{
"status": "done",
"receipt": {
"tx_hash_hex": "9f2c…",
"stage": "…",
"outcome": "…",
"finality": "…",
"display": {
"display_label": "…",
"help_line": "…",
"progress_step": "…",
"is_terminal": true,
"can_user_act": false,
"funds_effect": "…"
},
"dictionary_version": 2
}
}
status is one of sending, processing, done, failed, unknown. An unknown hash answers 200 with { "status": "unknown", "receipt": null }, not 404. The display object is a ready-to-render status line for wallets; failure_reason_class and user_next_action appear only when relevant.
Transaction proofs
Any committed transaction can be proven against the chain with one GET:
curl 'https://test.noxycore.io/v0/tx/{hash_hex}/proof?level=finality'
level is inclusion, finality (default), or checkpoint. The response carries the transaction digest and index, the batch and window Merkle paths (tx_proof_hex, list_proof_hex), and the ordered reference (ordered_ref_hex). At finality and above it adds the checkpoint and its certificate (checkpoint_hex, checkpoint_cert_hex), so the proof chains up to a validator-signed checkpoint.
A transaction with no durable proof yet returns 404 not_found; one that predates the node's bootstrap base returns 404 post_base_only.
EVM lane: eth JSON-RPC
POST /v0/evm speaks standard eth JSON-RPC 2.0 and is live on the testnet (EVM chain id 20057), so EVM wallets and tooling can point at it directly. Supported methods:
eth_chainId, net_version, eth_blockNumber, eth_gasPrice, eth_maxPriorityFeePerGas, eth_getBlockByNumber, eth_getBlockByHash, eth_getBalance, eth_getTransactionCount, eth_getCode, eth_getStorageAt, eth_call, eth_estimateGas, eth_feeHistory, eth_sendRawTransaction, eth_getTransactionByHash, eth_getTransactionReceipt, eth_getLogs
Batches are supported up to 20 requests. eth_getLogs ranges are capped at 100 blocks. Errors always come back as JSON-RPC error objects over HTTP 200 (-32601 for unsupported methods, -32005 for exceeded limits, 3 for execution reverts).
Account names
Name records live on-chain in StateNamespace::AccountNameRecord. Resolution works from state: normalize the labels, derive the name hash, and read the record — the TypeScript SDK and the wallet do this for you. A dedicated public HTTP resolve endpoint is planned but not exposed yet; see Accounts for the record layout and lease semantics.