/Developers/Proof Station
Swagger
INTEGRATION GUIDE

Proof Station API

ZK proof generation and dust sponsorship for the Midnight network. One API to prove and balance transactions — zero gas costs for your users.

api.1am.xyzapi-preprod.1am.xyzapi-preview.1am.xyz

PROVE

ZK Proof Generation

Halo2 zero-knowledge proofs via native binary. 20x faster than Docker. Results cached 30s.

BALANCE

Dust Sponsorship

Server-managed dust wallets cover all transaction fees. Users never pay gas. UTXOs auto-reclaim after 5 min.

Authentication

All endpoints except /health and /docs require an API key.

HeaderX-API-Key: pk_live_xxx
BearerAuthorization: Bearer pk_live_xxx

Optional: X-Client-ID and X-Client-Name for request tracking.

Contact team@1am.xyz for API key access.

Rate Limiting & Caching

X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when limit resets
Retry-AfterSeconds until retry (on 429)
X-CacheHIT or MISS — proof/verify cached 30s

POST /prove and /verify are cached 30s by body hash.

Integration Flows

Flow 1: Prove + Balance

Send an unproved transaction. Proof Station generates the ZK proof and balances it with dust.

1

Build unproved TX

Use Midnight SDK to create the transaction from your Compact contract call.

2

POST /prove-and-balance

Send serialized TX as binary. Proof Station proves and adds dust from sponsorship wallet.

3

Receive finalized TX

Response includes the proved + balanced TX hex and hash, ready for your client to use.

const res = await fetch('https://api.1am.xyz/prove-and-balance', {
  method: 'POST',
  headers: {
    'X-API-Key': 'pk_live_xxx',
    'Content-Type': 'application/octet-stream',
  },
  body: serializedUnprovedTx,
});
const { tx, txHash } = await res.json();
// tx is proved and balanced — ready to use

Flow 2: Balance Only (Pre-Proven TX)

When you've already generated the proof (e.g. in-browser via 1AM wallet WASM), you only need dust sponsorship.

const res = await fetch('https://api.1am.xyz/balance-only', {
  method: 'POST',
  headers: { 'X-API-Key': 'pk_live_xxx', 'Content-Type': 'application/octet-stream' },
  body: provedTxBytes,
});
const { tx, txHash } = await res.json();
// tx is balanced with dust — ready to use

API Reference

HEALTH & DOCS

PROOF GENERATION

DUST SPONSORSHIP & BALANCE

Error Handling

400Bad RequestCheck serialized TX data is valid binary
401UnauthorizedInclude X-API-Key or Authorization: Bearer header
404Not FoundBalance service not enabled on this server
429Rate LimitedWait Retry-After seconds, then retry
502Bad GatewayUpstream proof server is down
503Service UnavailableWallet still syncing — retry in 30s

All errors return JSON: { "error": "description" }

Server Environments

Productionhttps://api.1am.xyzMainnet
Preprodhttps://api-preprod.1am.xyzPre-production
Previewhttps://api-preview.1am.xyzDevelopment
Localhttp://localhost:8080Local dev

Full Integration Example

import { httpClientProofProvider } from '@midnight-ntwrk/midnight-js-fetch-zk-config-provider';

// 1. Connect to 1AM wallet
const api = await window.midnight['1am'].connect('mainnet');
const config = await api.getConfiguration();
// config.proverServerUri === 'https://api.1am.xyz'

// 2. Set up proof provider pointing to Proof Station
const proofProvider = httpClientProofProvider(config.proverServerUri);

// 3. Build contract transaction
const tx = await contract.callTx.myMethod(args);

// 4. Prove via Proof Station (automatic through SDK)
const provedTx = await proofProvider.proveTx(tx);

// 5. Balance via wallet → calls /balance-only internally
const balanced = await api.balanceUnsealedTransaction(provedTx);
// balanced.tx is the finalized, dust-sponsored transaction