API keys
Operator-issued API keys sent as X-Tenzro-Api-Key: scopes, key classes, tiers, issuance, self-service revocation and error codes.
An API key is a credential that one node operator issues to a tenant: a developer, a team, an agent or a machine they have an agreement with. It is sent as the X-Tenzro-Api-Key header and grants access to a set of scopes on that operator's node, within a rate budget.
API keys are per operator. Each operator issues, stores and revokes keys on their own node with their own admin token; there is no network-wide key authority. A key from one RPC provider means nothing to another.
You do not need an API key to use Tenzro. Reads are open, owner actions are authorised by your own signature, and paid routes accept per-request payment over HTTP 402. A key is for when you and a provider have agreed terms in advance: a subscription, a private model, tenant storage or a database. See RPC access.
Format
Keys look like tnz_<base64url>. The plaintext is returned once, at creation. The node stores only a SHA-256 digest, compares it in constant time and never logs it.
curl -s https://rpc.tenzro.xyz/v1/chat/completions \
-H 'content-type: application/json' \
-H "X-Tenzro-Api-Key: $TENZRO_API_KEY" \
-d '{"model":"<model id>","messages":[{"role":"user","content":"Hello"}]}'The SDKs and the CLI read the key from TENZRO_API_KEY.
Scopes
A key carries one or more scopes. A key with no scopes is invalid.
| Scope | Grants |
|---|---|
inference | Chat, embeddings and the other model endpoints, when the operator gates inference |
storage | Tenant object storage: /v1/files and the file methods. The key's subject owns every file it uploads. |
database | Managed databases: /v1/databases and the database methods, inside the tenant's own isolation boundary |
evm, svm | Contract calls and program execution, when the operator gates them |
tee | Attestation and proof verification, when the operator gates them |
bridge | Cross-chain dispatch through the operator's relays |
canton | DAML ledger access through a Canton participant the operator runs. See Canton. |
chainlink | Bridge-fee quotes backed by the operator's price feeds |
issuer | Operating a stable unit registered on the node |
storage and database are always enforced, because the key's subject is what makes a tenant the owner of their data. The other scopes are gates an operator can choose to switch on for services they monetise or rate limit.
Publishing to the marketplaces (agents, skills, tools, workflows) needs no key and no approval from any operator.
Classes
The class decides who may revoke a key.
| Class | Revoked by | Use for |
|---|---|---|
subject (default) | The operator, or the key holder themselves | Keys issued to developers and customers |
operator_internal | The operator only | The operator's own automation and monitoring |
operator_protected | Nobody over RPC; rotated by changing the operator's secret and restarting | Keys the node itself depends on. Needs confirm_operator_protected. |
Tiers
The tier decides how much of a reachable surface a key gets over a sliding 60-second window.
| Tier | Budget | Writes |
|---|---|---|
free | Lowest | Refused: read-only evaluation access |
standard | Higher | Allowed |
priority | Highest | Allowed |
A key over budget gets -32005 with retry_after_ms, requests_per_minute and tier in the error data.
Issue a key (operator)
Issuing, listing and revoking keys are admin methods: they need your node's X-Tenzro-Admin-Token.
tenzro admin api-key create \
--label acme-prod \
--subject did:tenzro:human:... \
--scope inference --scope storage \
--tier standard \
--rpc http://127.0.0.1:8545
tenzro admin api-key list
tenzro admin api-key revoke --key-id <key-id>Over JSON-RPC:
curl -s http://127.0.0.1:8545 \
-H 'content-type: application/json' \
-H "X-Tenzro-Admin-Token: $TENZRO_ADMIN_TOKEN" \
-d '{
"jsonrpc": "2.0", "id": 1,
"method": "tenzro_createApiKey",
"params": {
"label": "acme-prod",
"subject": "did:tenzro:human:...",
"scopes": ["inference", "storage"],
"class": "subject",
"tier": "standard"
}
}'The response contains the plaintext key (shown once) and a key_id. With the TypeScript SDK:
const created = await client.apiKey.create({
label: "acme-prod",
subject: "did:tenzro:human:...",
scopes: ["inference", "storage"],
tier: "standard",
});Self-service (key holder)
A holder of a subject key can see and revoke their own keys without asking the operator. Both calls are authorised by the key itself and return only keys with the same subject.
tenzro key list-mine
tenzro key revoke-mine --key-id <key-id>curl -s https://rpc.tenzro.xyz \
-H 'content-type: application/json' \
-H "X-Tenzro-Api-Key: $TENZRO_API_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"tenzro_listMyApiKeys","params":{}}'Each row describes everything the node will enforce for that key: scopes, class, tier, requests_per_minute, allows_write and active. A tenant can answer "what may I do here" without asking.
What keys do not do
- They do not replace signatures. An owner action, such as a transfer, still needs a signature from the paying account; a key only admits the caller to the operator's services.
- They are not network credentials. Validator set, fees and protocol parameters change only through governance, whatever key is presented.
- They are not the admin token, and they are not service keys. A service key (
X-Tenzro-Service-Key) decides whether a caller may reach a private node at all; an API key decides what an admitted caller may do.
Methods
| Method | Access |
|---|---|
tenzro_createApiKey, tenzro_listApiKeys, tenzro_revokeApiKey | Admin |
tenzro_listMyApiKeys, tenzro_revokeMyApiKey | The key holder |
Errors
| Code | Meaning |
|---|---|
-32001 | Admin token missing or wrong |
-32004 | Key missing, unknown or revoked; key lacks the scope; tier is read-only and the method writes; or the key is not yours |
-32005 | Over the tier's rate budget |
-32602 | Invalid parameters, such as an unknown tier, or operator_protected without confirmation |
Running a node that issues keys to customers? See Run an RPC provider.