Documentation

Accept shielded Zcash payments. Non-custodial. Set up in minutes.

Agentic Payments

CipherPay enables AI agents and automated clients to pay for API access using shielded Zcash. It supports two open standards — x402 (HTTP 402 Payment Required) and the Machine Payments Protocol (MPP) — plus prepaid sessions for high-frequency agent workflows. All payments are verified via trial decryption using your viewing key.

Supported protocols
PROTOCOLCHALLENGE HEADERCREDENTIAL HEADERFLOW
x402 v2PAYMENT-REQUIREDPAYMENT-SIGNATURECustom x402 headers + JSON body
MPPWWW-Authenticate: PaymentAuthorization: PaymentStandard HTTP auth headers
SessionsAuthorization: Bearer cps_...Prepaid credit, no per-request payment

The @cipherpay/x402 middleware auto-detects which protocol the client is using and handles all three flows transparently. Session tokens are checked first, then MPP headers, then x402 headers.

How it works
1
Agent requests resource
GET /api/data
2
Server returns 402
With price and ZEC address
3
Agent sends ZEC
Shielded transaction
4
Server calls CipherPay
POST /x402/verify
5
CipherPay confirms
Trial decryption + replay check
6
Server grants access
Returns the data

When an unauthenticated request arrives, the middleware responds with HTTP 402 and includes payment terms. For x402, this is a JSON body with the PAYMENT-REQUIRED header. For MPP, the challenge is in the WWW-Authenticate: Payment header. Both contain the same information: price, address, network, and facilitator URL.

NOTE
CipherPay verifies payments using your viewing key (UFVK) via trial decryption — the same mechanism used for invoice detection. The sender's identity remains fully private.
Replay protection

Every transaction ID is tracked per-merchant. Once a txid has been used to verify a payment, it cannot be reused to gain access again. The verify endpoint returns "valid": false with reason "already_used" for duplicate txids.

TIP
Replay protection is automatic — no configuration needed. The middleware handles it transparently.
Why privacy matters for agents

Every AI agent payment on Base, Solana, or Polygon is a public record. Competitors can reconstruct your agent's entire operational strategy — what APIs it calls, what data it buys, how often, and how much it spends. On transparent chains, agent payment metadata is a surveillance goldmine.

With Zcash shielded payments, all of that is invisible. The sender, receiver, amount, and frequency are fully encrypted on-chain. CipherPay verifies payments using your viewing key, but the agent's identity, balance, and activity remain completely private.

Quick start — @cipherpay/x402

The fastest way to accept shielded ZEC payments on your API. One middleware, one line.

npm install @cipherpay/x402
bash
import express from 'express';
import { zcashPaywall } from '@cipherpay/x402/express';

const app = express();

app.use('/api/premium', zcashPaywall({
  amount: 0.001,          // ZEC per request
  address: 'u1abc...',    // Your Zcash Unified Address
  apiKey: 'cpay_sk_...',  // CipherPay API key
}));

app.get('/api/premium/data', (req, res) => {
  res.json({ temperature: 18, conditions: 'partly cloudy' });
});
typescript

The middleware handles all three protocols automatically: returns 402 challenges for x402 and MPP clients, validates session bearer tokens, verifies payment txids, and enforces replay protection.

TIP
For dynamic pricing, use the getAmount option instead of a static amount.
app.use('/api/ai', zcashPaywall({
  address: 'u1abc...',
  apiKey: 'cpay_sk_...',
  amount: 0,
  getAmount: (req) => {
    if (req.url.includes('gpt-4')) return 0.01;
    if (req.url.includes('gpt-3')) return 0.001;
    return 0.0005;
  },
}));
typescript

The SDK also exports a standalone verifyPayment function for custom integrations:

import { verifyPayment } from '@cipherpay/x402';

const result = await verifyPayment(txid, 0.001, 'cpay_sk_...');
if (result.valid) {
  // Payment confirmed — grant access
}
typescript
Prepaid sessions

For agents that make many requests, paying per-call is expensive and slow. Sessions let an agent deposit ZEC once, receive a bearer token, and use it for subsequent requests — with the balance deducted automatically per-request.

1
Agent prepares session
POST /api/sessions/prepare
2
Agent deposits ZEC
Send to the returned address
3
Agent opens session
POST /api/sessions/open with session_request_id
4
CipherPay confirms
Returns bearer token (cps_...)
5
Agent uses token
Authorization: Bearer cps_...
6
Balance deducted
Per-request, atomically

First, call POST /api/sessions/prepare with the merchant's API key to get a unique deposit address and a session_request_id. Send ZEC to that address, then call POST /api/sessions/open with the session_request_id and the txid. Minimum deposit is 10,000 zatoshis (0.0001 ZEC). The bearer token is returned once the deposit is detected, and expires after the configured TTL (default 24h).

IMPORTANT
The legacy memo-based session flow (merchant_id in the open request) is deprecated and will be removed in a future version. Always use session_request_id from the prepare endpoint.
NOTE
Sessions are managed via the MCP server tools (open_session, get_session_status,close_session) or the REST API directly. The middleware validates session tokens automatically.
Setup guide
1Register with CipherPay

If you already have a CipherPay merchant account, use your existing API key. If not, register here with your UFVK. You'll get an API key (cpay_sk_...) to authenticate verification requests.

For agent integrations, mint a restricted key (cpay_rk_...) from Dashboard → Settings → Scoped Keys. Restricted keys can verify x402, manage sessions, and create invoices but cannot change account settings or revoke other keys — much safer to hand to an AI agent. See Reference → API Keys.

2Return 402 from your server

When your API receives a request without valid credentials, respond with HTTP 402. The middleware returns both x402 and MPP headers automatically:

{
  "x402Version": 2,
  "resource": { "url": "/api/data" },
  "accepts": [{
    "scheme": "exact",
    "network": "zcash:mainnet",
    "asset": "ZEC",
    "amount": "100000",
    "payTo": "u1yourpaymentaddress...",
    "maxTimeoutSeconds": 120,
    "extra": {}
  }]
}
json

MPP clients receive the same terms via the WWW-Authenticate: Payment header:

WWW-Authenticate: Payment scheme="exact", network="zcash:mainnet",
  asset="ZEC", amount="100000", payTo="u1yourpaymentaddress...",
  facilitator="https://api.cipherpay.app/api/x402/verify"
text
3Verify the payment

When the agent retries with a payment credential (either PAYMENT-SIGNATURE or Authorization: Payment), call the CipherPay verify endpoint:

curl -X POST https://api.cipherpay.app/api/x402/verify \
  -H "Authorization: Bearer cpay_sk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "txid": "a1b2c3d4e5f6...",
    "expected_amount_zec": 0.001
  }'
bash

Response:

{
  "valid": true,
  "received_zec": 0.001,
  "received_zatoshis": 100000
}
json

If valid is true, the payment is confirmed. If false, the response includes a reason field (insufficient_amount, not_found,already_used, etc.).

Middleware example

A minimal Express.js server with the full agentic payment flow — x402, MPP, sessions, and replay protection:

import express from 'express';
import { zcashPaywall } from '@cipherpay/x402/express';

const app = express();

app.use('/api/premium', zcashPaywall({
  amount: 0.001,
  address: 'u1youraddress...',
  apiKey: process.env.CIPHERPAY_API_KEY,
}));

app.get('/api/premium/data', (req, res) => {
  res.json({ message: 'You paid for this!' });
});
typescript
API reference
METHODENDPOINTAUTHDESCRIPTION
POST/api/x402/verifyAPI KeyVerify a shielded ZEC payment by txid (replay-protected)
GET/api/merchants/me/x402/historyAPI Key / SessionList past payment verifications (x402 + MPP)
POST/api/sessions/prepareNonePrepare a session: get a unique deposit address and session_request_id
POST/api/sessions/openNoneOpen a session after deposit (requires session_request_id + txid)
GET/api/sessions/validateBearer tokenValidate session token and deduct balance (header only, no query tokens)
GET/api/sessions/{id}/statusAPI Key / SessionCheck session balance and usage
POST/api/sessions/{id}/closeAPI Key / SessionClose session, track remaining balance for refund
GET/api/merchants/me/sessionsAPI Key / SessionList all sessions for your merchant
Verification history

All verification calls are logged and accessible via the dashboard (Agentic Payments tab) or the history endpoint. Each entry shows which protocol was used (x402 or MPP), the amount, and the verification result.

curl https://api.cipherpay.app/api/merchants/me/x402/history \
  -H "Authorization: Bearer cpay_sk_YOUR_KEY"
bash

Returns a paginated list with ?limit= and ?offset= query parameters (max 200 per page).

TIP
Payment verification is free. CipherPay makes money from invoice-based payment processing — agentic payment verification is provided to drive Zcash adoption for AI and programmatic payments.
Agent discovery

CipherPay exposes a /.well-known/payment endpoint for agent discovery. AI agents can query this URL to learn that a merchant supports Zcash payments via CipherPay, and which protocols (x402, MPP) are available.

curl https://api.cipherpay.app/.well-known/payment
bash

This follows the emerging pattern of machine-readable payment metadata at well-known paths, letting agents auto-discover payment capabilities without human configuration.

CipherPay — Private Payments for the Internet