# zkAPI

> zkAPI is a privacy-preserving protocol for paying for metered API usage with private balances and zero-knowledge proofs, then settling charges from signed usage receipts.

- Canonical URL: https://iq.wiki/wiki/zkapi
- Categories: Projects & Protocols
- Tags: Ethereum, Payments, Infrastructure, Privacy
- Created: 2026-10-16T16:50:32.594Z
- Last updated: 2026-10-16T16:50:32.594Z
- Source: IQ.wiki — the world's largest blockchain and crypto encyclopedia (https://iq.wiki)

---

**zkAPI** is a protocol for paying privately for metered application programming interface (API) usage, including AI inference, using prepaid balances and zero-knowledge proofs rather than an account-linked API key. The [Ethereum](https://iq.wiki/wiki/ethereum) [Foundation](https://iq.wiki/wiki/foundation) and Open Anonymity Project announced it live on Ethereum [Mainnet](https://iq.wiki/wiki/mainnet) on October 1, 2026. The working implementation was built by Open Anonymity Project with the Ethereum Foundation, based on a “ZK API usage credits” design published on Ethereum Research by [Davide Crapis](https://iq.wiki/wiki/davide-crapis) and [Vitalik Buterin](https://iq.wiki/wiki/vitalik-buterin).[[1]](#cite-id-6hfcqnrpba)[[2]](#cite-id-1ukj7wgzif)

zkAPI is designed to separate payment authorization from the content of an API request. In its runtime-key mode, a local client obtains a short-lived, spending-capped API key after proving that a private balance can cover usage. The key is held on the user’s device, and requests go directly from that device to the service provider.[[1]](#cite-id-6hfcqnrpba)[[3]](#cite-id-psnj5l9nml)

## History and Launch

The “ZK API usage credits” design was published on Ethereum Research by [Davide Crapis](https://iq.wiki/wiki/davide-crapis) and [Vitalik Buterin](https://iq.wiki/wiki/vitalik-buterin). Open Anonymity Project developed the client, server, and contracts for the working system in collaboration with the [Ethereum Foundation](https://iq.wiki/wiki/ethereum-foundation-ef)’s [dAI Team](https://iq.wiki/wiki/dai-team).[\[1\]](#cite-id-6hfcqnrpba)​[\[2\]](#cite-id-1ukj7wgzif)​

The Ethereum Foundation announced zkAPI on October 1, 2026, describing it as live on Ethereum [Mainnet](https://iq.wiki/wiki/mainnet). Launch materials described deposits of ETH, [USDC](https://iq.wiki/wiki/usdc), or other assets, and identified a Mainnet vault holding USDC credits, alongside a Sepolia test deployment and OA Chat, a browser-based private AI chat service.[\[1\]](#cite-id-6hfcqnrpba)​[\[2\]](#cite-id-1ukj7wgzif)​

The later v2 protocol documentation describes a native-ETH implementation: the current SDK and vault support native ETH, with amounts denominated in whole [gwei](https://iq.wiki/wiki/gwei). This distinction reflects the documented scope of the v2 implementation and should not be read as a description of every asset mentioned in the initial launch materials.[\[3\]](#cite-id-psnj5l9nml)​[\[4\]](#cite-id-0ih4jv3e87)​

## Privacy and Payment Flow

A user deposits funds into an [Ethereum](https://iq.wiki/wiki/ethereum) vault. The deposit creates a note representing a private balance. To authorize a request, the user’s local software generates a proof that the note is valid and has sufficient funds, without disclosing the note or linking the request publicly to the original deposit. A one-way nullifier prevents the same private state from being spent twice: a valid spend consumes the state, while an attempt to reuse it produces a duplicate nullifier.[[1]](#cite-id-6hfcqnrpba)[[2]](#cite-id-1ukj7wgzif)

In runtime-key mode, an application communicates with the client on the user’s device while continuing to use its usual API interface. The client sends a payment proof to the zkAPI server without sending a prompt or identity information. After verifying the proof, the server issues a short-lived API key capped at a dollar amount; the key is held in device memory, and prompts travel directly from the device to the provider.[[1]](#cite-id-6hfcqnrpba)[[3]](#cite-id-psnj5l9nml)

When a key expires, the provider records usage in a signed receipt. The server settles the actual charge against the user’s private balance, rather than charging the entire reserved cap. One authorization can cover a session of requests. In v2, no funds move on-chain for each request: usage reduces the private balance, while unused capacity remains available.[[1]](#cite-id-6hfcqnrpba)[[3]](#cite-id-psnj5l9nml)

Runtime-key mode divides what the parties can observe. The payment server learns that a valid payment exists and the total dollars charged per session, but not the prompt content. The provider sees prompts and responses, but does not learn the billing identity associated with the key. Ethereum exposes deposits, closes, and withdrawals, but not what the balance paid for.[[1]](#cite-id-6hfcqnrpba)[[2]](#cite-id-1ukj7wgzif)

The alternative proxy mode relays requests through the zkAPI server. Unlike runtime-key mode, the relay can see the request traffic. The local client exposes standard OpenAI-compatible and Ollama APIs through localhost, allowing compatible applications, editors, and chat clients to connect without changing their usual API interface.[[1]](#cite-id-6hfcqnrpba)[[2]](#cite-id-1ukj7wgzif)

## Protocol Design

### Private State and Request Authorization

In zkAPI v2, a wallet samples a secret and derives a registration commitment from it. A deposit inserts a leaf into a depth-32 [Merkle tree](https://iq.wiki/wiki/merkle-tree); the leaf binds the note ID, secret-derived registration, deposit amount, and expiry. The user’s private balance is represented by a commitment that combines the balance, a blinding value, and the note leaf. Binding the commitment to that leaf prevents a signed balance from being transferred to another active note.[[3]](#cite-id-psnj5l9nml)[[5]](#cite-id-kgcqs1j1jn)

For each request, the wallet rerandomizes its private-state commitment and generates a Groth16 proof. The proof establishes membership in an active tree root, validates the note’s initial or server-signed state, checks that the balance meets the required solvency bound and that the note has not expired, and binds authorization to the request ID and payload hash. The server recomputes the hash of the exact payload and request context before accepting the authorization.[[3]](#cite-id-psnj5l9nml)

The protocol’s state-anchor chain links each accepted authorization to a fresh server-signed state. The server applies the charge, updates the private balance and commitment, and signs the new state anchor. The wallet verifies the response, charge, signature, and commitment update before saving the next state. Exact retries use the durable request record for recovery; changing a request does not create a new spendable nullifier for the same state.[[3]](#cite-id-psnj5l9nml)

The v2 circuits use Groth16 proofs over the BN254 curve, Poseidon hashing for commitments and nullifiers, and Schnorr signatures on Baby-JubJub for signed state. The request and withdrawal circuits share the note-bound state design. The protocol’s current circuit revision is named `zkapi-v2-note-bound-v1`.[[3]](#cite-id-psnj5l9nml)[[6]](#cite-id-fur92gw4nh)

### Vault, Indexer, and Settlement

The ZkApiVault contract escrows native ETH and verifies note-bound proofs for deposits and withdrawals. Deposits use whole-gwei units and must send exactly the deposited amount in wei. The contract inserts the note into the [Merkle tree](https://iq.wiki/wiki/merkle-tree) and records its expiry; expiry is rounded up to the vault’s one-day bucket. Its proof adapter and state- and clearance-signing keys are immutable deployment parameters.[[5]](#cite-id-kgcqs1j1jn)[[3]](#cite-id-psnj5l9nml)

The indexer mirrors deposit, close, escape, challenge, finalization, and expiry events from [Ethereum](https://iq.wiki/wiki/ethereum) into a local Merkle tree. It supplies roots and paths that the browser uses to construct proofs and that the server uses to track active state. Clients can retrieve a tree snapshot and reconstruct paths locally, avoiding disclosure of a particular note ID in a path request. The contract and clients recompute roots from supplied paths, so an incorrect or stale path can cause proof generation or a transaction to fail.[[7]](#cite-id-kq50cbpxfg)

A user can close a note through a mutual withdrawal, which requires server clearance and pays the remaining balance to a chosen destination; the remainder of the deposit goes to the treasury. The withdrawal destination can differ from the funding address. On close, the vault pays the user the final balance and the treasury the difference between the original deposit and that balance.[[3]](#cite-id-psnj5l9nml)[[5]](#cite-id-kgcqs1j1jn)

The escape withdrawal path allows a user to initiate withdrawal without server clearance. It removes the note from the active tree and records a pending payout, subject to a challenge period that defaults to 24 hours. Before the deadline, a challenger can use the original request proof and matching nullifier to show that the note had already authorized usage. A successful challenge cancels the payout and restores the note to the active tree; if no challenge succeeds, anyone can finalize the withdrawal after the deadline. An active note that expires without being closed can be claimed for the treasury.[[3]](#cite-id-psnj5l9nml)[[5]](#cite-id-kgcqs1j1jn)

Users can therefore close and withdraw on-chain without depending on the continued operation of the zkAPI server. The browser SDK manages private note state, proof generation, transaction journals, receipt recovery, and settlement, while a host supplies the payment interface and an EIP-1193 wallet provider. The project also includes Rust runtime and proof libraries, [Solidity](https://iq.wiki/wiki/solidity) vault contracts, server and indexer libraries, an indexer and challenge service, and an operator [CLI](https://iq.wiki/wiki/cli).[[4]](#cite-id-0ih4jv3e87)[[2]](#cite-id-1ukj7wgzif)
