Automation

Agents & APIs
Private machine-to-machine payments: agents poll one URL, receive standard 402 + JSON, run the same Umbra settlement as a human, then read the unlocked response with structured content. Uses a common x402-style envelope without defining a separate payment protocol.

Resource URL

GET /api/resources/<intent-id>

  • 402 while open: JSON includes x402Version, accepts[], and extra.settlement = umbra-receiver-claimable-utxo so clients route work to the Umbra SDK instead of treating payTo as a plain public SPL send.
  • 200 after the intent is marked settled: JSON includes content (umbra-pay-links.unlocked) as the unlocked machine payload, plus settledAt and receipt fields.

Example 200 body (shape)

Abbreviated; see OpenAPI for full fields. settledAt is written on first confirm; older rows may fall back to createdAt in the resource response only when needed.

{
  "unlocked": true,
  "intentId": "…",
  "label": "Invoice / product name",
  "settledAt": "2026-04-24T12:00:00.000Z",
  "amountAtomic": "1000000",
  "mint": "EPjF…",
  "message": "Payment recorded. This JSON is the unlocked resource…",
  "content": {
    "type": "umbra-pay-links.unlocked",
    "version": 1,
    "title": "Invoice / product name",
    "body": "Access is granted for this intent…",
    "receipt": {
      "settlement": "umbra-receiver-claimable-utxo",
      "amountAtomic": "1000000",
      "mint": "EPjF…"
    }
  }
}

Headless payer

npm run agent:pay runs scripts/agent-pay.mjs: load a keypair, read 402, run the same Umbra + UTXO path as the browser, POST confirm, re-fetch the resource. Environment variables are in README.md and .env.example.

Umbra SDK parity (browser vs agent)

Both paths call getUmbraClient, optional registration, then getPublicBalanceToReceiverClaimableUtxoCreatorFunction with the same browser ZK prover package. The only deliberate difference is the signer: Wallet Standard in React vs private key bytes in Node. Same settlement path, not a server-side fake payment.

OpenAPI

Machine-readable contract: /openapi.json (OpenAPI 3.1). Import into Postman, Insomnia, or codegen tools so your platform can treat intents as first-class resources.

REST surface

Routes are rate-limited per client IP (see README.md). POST /api/intents validates Solana addresses with @solana/kit address().

POST /api/intents
Create intent; returns pay URL and resource URL. Optional webhookUrl for a server POST on first settlement.
GET /api/intents/<id>
Intent fields for the checkout UI.
POST /api/intents/<id>/confirm
Mark settled with an array of transaction signatures. Idempotent if signatures match an already-settled intent. Optional RPC verification when REQUIRE_ONCHAIN_CONFIRM_FOR_SETTLE is enabled.
GET /api/resources/<id>
402 paywall or 200 when paid.

Umbra documentation