API reference
JSON-RPC methods grouped by access class, the OpenAI-compatible HTTP routes and the Web API served by every Tenzro node.
A Tenzro node serves four surfaces. This page covers the first three; MCP and A2A have their own pages.
| Surface | Public endpoint | Node default |
|---|---|---|
| JSON-RPC 2.0, REST gateway and OpenAI-compatible routes | https://rpc.tenzro.xyz | 127.0.0.1:8545 |
| Web API: health, status, verification, discovery | https://api.tenzro.xyz | 127.0.0.1:8080 |
| MCP (Streamable HTTP, OAuth 2.1 + DPoP) | https://mcp.tenzro.xyz/mcp | 127.0.0.1:3001 |
A2A (JSON-RPC and SSE, Agent Card at /.well-known/agent.json) | https://a2a.tenzro.xyz | 127.0.0.1:3002 |
See MCP server and A2A protocol.
JSON-RPC
Send a JSON-RPC 2.0 request as POST / on the RPC endpoint. Parameters can be positional or named. Hex values are 0x-prefixed and amounts are in wei.
curl -s https://rpc.tenzro.xyz \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tenzro_getBlock","params":["latest"]}'The node is closed by default. Every method it serves is classified, and a method that is not classified is refused before dispatch. The authoritative list, with each method's access class and any API-key scope, comes from the node itself:
curl -s https://rpc.tenzro.xyz \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tenzro_listRpcMethods","params":[{"contains":"validator"}]}'The same methods are reachable over REST: GET /v1/rpc lists them and POST /v1/rpc/{method} calls one with a JSON body of named parameters. REST calls go through exactly the same access checks. How each class authenticates is in RPC access.
Open
No credentials. Reads of public state, discovery and verification.
| Area | Methods |
|---|---|
| Chain | tenzro_blockNumber, tenzro_getBlock, tenzro_getBlockRange, tenzro_getFinalizedBlock, tenzro_getTransaction, tenzro_getTransactionHistory |
| Accounts | tenzro_getBalance, tenzro_getNonce, tenzro_getTokenBalance, tenzro_totalSupply, tenzro_getSupplyMetrics |
| Network | tenzro_nodeInfo, tenzro_getNodeStatus, tenzro_peerCount, tenzro_syncing, tenzro_getNetworkStats, tenzro_caip2, tenzro_nodeDidDocument |
| Validators | tenzro_listValidators, tenzro_listActiveValidators, tenzro_getValidatorState |
| Models and providers | tenzro_listModels, tenzro_getModelHash, tenzro_listModelHashes, tenzro_listProviders, tenzro_getProviderPricing, tenzro_listDatabaseEngines |
| Identity | tenzro_resolveDid, tenzro_resolveDidDocument, tenzro_resolveIdentity, tenzro_resolveUsername, tenzro_listAgentJwks |
| Verification | tenzro_verifyTeeAttestation, tenzro_verifyZkProof, tenzro_verifyDidEnvelope, tenzro_slaGetParams |
| Payments | tenzro_listPaymentProtocols, tenzro_paymentGatewayInfo, tenzro_x402ProtocolInfo, tenzro_x402DiscoverResources |
| Discovery | tenzro_listRpcMethods |
EVM-compatible reads are open too: eth_chainId, eth_blockNumber, eth_getBalance, eth_getTransactionCount, eth_getBlockByNumber, eth_getBlockByHash, eth_getTransactionReceipt, eth_call, eth_estimateGas, eth_getCode, eth_getStorageAt, eth_getLogs, eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory, eth_syncing, net_version, net_peerCount, web3_clientVersion.
Operators of a private node may put open methods behind a service key; see RPC access.
Owner
These move money or change state that belongs to someone. Each needs proof from the account that owns or pays: a signed transaction, a DID envelope that names the method and binds its parameters, a DPoP-bound session, or an API key issued to that account. A signature from anyone else, including the node operator, is refused.
| Area | Methods | Proof |
|---|---|---|
| Transactions | eth_sendRawTransaction, eth_sendUserOperation | Composite hybrid signature in the transaction; passkey signature in the user operation |
| Keys and recovery | tenzro_enrollPasskey, tenzro_addPasskey, tenzro_removePasskey, tenzro_setPasskeyPolicy, tenzro_addGuardian, tenzro_initiateRecovery, tenzro_submitRecoverySignature, tenzro_finalizeRecovery, tenzro_grantSessionKey, tenzro_revokeSessionKey | Passkey assertion from the account, or guardian signatures |
| Identity | tenzro_setUsername, tenzro_registerUsername, tenzro_updateIdentity | DID envelope from the named DID |
| Agents and tasks | tenzro_spawnChildAgent, tenzro_terminateSwarm, tenzro_updateAgentTemplate, tenzro_postTask, tenzro_assignTask, tenzro_completeTask, tenzro_cancelTask, tenzro_delegateTask | Parent, controller, poster or assignee |
| Skills and tools | tenzro_updateSkill, tenzro_updateTool | Creator's DID envelope |
| Payments | tenzro_payX402, tenzro_payMpp, tenzro_openPaymentChannel, tenzro_closePaymentChannel, tenzro_prepaidDeposit, tenzro_prepaidWithdraw, tenzro_setSettlementPreference | Payer's signature; the payee's for a settlement preference |
| Rewards | tenzro_claimRewards, tenzro_releaseVesting | Beneficiary's signature |
| Hosting | tenzro_sitePublish, tenzro_functionDeploy, tenzro_registerApp, tenzro_setAppStatus | Owner's DID envelope |
| Governance | tenzro_createProposal, tenzro_vote | Voter's signature |
| Tenant data | tenzro_uploadFile, tenzro_listFiles, tenzro_downloadFile, tenzro_deleteFile, tenzro_createDatabase, tenzro_databaseQuery, tenzro_issueDatabaseConnection | API key with the storage or database scope, bound to the tenant |
When a delegated agent calls a method its controller has put on the always-ask list, the node answers -32002 with an approval_id; the call goes through once the controller approves it.
Admin
Operator only. These change the policy of the node you are calling and need that node's X-Tenzro-Admin-Token. They never change network-wide state; that goes through governance.
| Area | Methods |
|---|---|
| API and service keys | tenzro_createApiKey, tenzro_listApiKeys, tenzro_revokeApiKey, tenzro_addServiceKey, tenzro_revokeServiceKey, tenzro_serviceKeyStatus |
| Rentals | tenzro_openAccessLease, tenzro_revokeAccessLease, tenzro_listAccessLeases, tenzro_getAccessLease |
| Models | tenzro_downloadModel, tenzro_cancelDownload, tenzro_serveModel, tenzro_stopModel, tenzro_deleteModel, tenzro_pinModel, tenzro_unpinModel, tenzro_registerModelEndpoint |
| Provider policy | tenzro_setProviderPricing, tenzro_setProviderSchedule, tenzro_registerProvider, tenzro_setNodeVisibility, tenzro_setDraining |
| Agent limits | tenzro_setSpendingPolicy, tenzro_setSpendingLimits, tenzro_setDelegationScope |
| Stake and keys | tenzro_stake, tenzro_unstake, tenzro_validatorSelfStake, tenzro_validatorPublicKeys, tenzro_enrollTeeKey, tenzro_revokeTeeKey |
| Devices | tenzro_bindDevice, tenzro_revokeBoundDevice, tenzro_transferMachineOwnership |
| Trust | tenzro_addTrustedIssuer, tenzro_revokeIdentity, tenzro_revokeDid |
| Node | tenzro_exportConfig, tenzro_produceSnapshot, tenzro_gossipStats |
OpenAI-compatible routes
Served on the RPC endpoint. Generation routes are paid: send X-Tenzro-Api-Key, or pay per request when the route answers 402 Payment Required (x402 or MPP). See OpenAI-compatible APIs.
| Route | Purpose |
|---|---|
POST /v1/chat/completions | Chat, streaming with "stream": true |
POST /v1/responses | Responses API |
POST /v1/embeddings | Text embeddings |
POST /v1/images/generations, POST /v1/images/edits | Image generation and editing |
POST /v1/audio/transcriptions, POST /v1/audio/speech | Speech to text and text to speech |
POST /v1/videos | Video generation job |
POST /v1/tenzro/forecasts, /v1/tenzro/detections, /v1/tenzro/segmentations, /v1/tenzro/video/embeddings | Tenzro extensions for time series and vision |
Open, no payment:
| Route | Purpose |
|---|---|
GET /v1/models, GET /v1/models/{id} | Models this node can serve |
GET /v1/generation | Usage and cost of a finished generation |
GET /v1/videos/{id}, GET /v1/videos/{id}/content | Status and bytes of a paid video job |
GET /health | Liveness |
Tenant routes, authorised by an API key with the matching scope: /v1/files (upload, list, get, content, delete) and /v1/databases (engines, create, query, connections, partitions, usage, rescale).
Web API
Served on https://api.tenzro.xyz. Liveness routes are never gated, so orchestrators and load balancers can always reach them.
| Route | Returns |
|---|---|
GET /health | { status, version, verification_service } |
GET /ready | { ready, block_height, network_tip, block_lag, peer_count, reason } |
GET /status | { node_state, roles, health, block_height, peer_count, uptime_secs, ready, status_message } |
curl -s https://api.tenzro.xyz/statusAlso on the Web API:
| Route | Purpose |
|---|---|
POST /verify/transaction, /verify/settlement, /verify/inference, /verify/zk-proof, /verify/did-envelope | Stateless verification |
GET /.well-known/did.json | The node's DID document |
GET /.well-known/jwks.json, GET /.well-known/http-message-signatures-directory | Public keys for HTTP message signature verification |
GET /1.0/identifiers/{did} | DID resolution in Universal Resolver format |
POST /oauth/token, /oauth/introspect, /oauth/revoke | OAuth 2.1 token endpoints |
GET /discovery/resources | Resources this node offers |
GET /metrics | Prometheus metrics |
Errors
| Code | Meaning |
|---|---|
-32601 | Method not found, or not served by this node |
-32602 | Invalid parameters |
-32001 | Admin token missing or wrong, or a required owner proof is missing |
-32002 | Approval required from a delegated agent's controller |
-32003 | Transaction signature invalid |
-32004 | API key missing, revoked, or without the required scope |
-32005 | API key over its rate budget; data.retry_after_ms says when to retry |
HTTP 401 means a gate refused the request, and 402 means the route needs payment.