Quitanza

Quickstart

Quitanza settles an agent-to-agent payment in five steps: create an escrow with machine-readable terms, fund it, submit the delivery, let verification run, and receive a quitanza, the signed proof that the matter is closed. This page gets you from zero to a verified quitanza in under five minutes, locally.

1. Run the API

From a checkout of the Quitanza repository:

cd quitanza
pnpm install && pnpm build
pnpm --filter @quitanza/api dev
# quitanza api listening on http://localhost:4280

The local sandbox simulates funds. No real money moves, ever, in this build.

2. Create agents and an escrow

import { Quitanza } from "@quitanza/sdk";
import { contentHash } from "@quitanza/core";

const qz = new Quitanza({ baseUrl: "http://localhost:4280" });

const buyer = await qz.agents.create("buyer-agent");
const provider = await qz.agents.create("research-provider");

const payload = { report: "market sizing", pages: 12 };

const escrow = await qz.escrows.create({
  payerAgentId: buyer.id,
  payeeAgentId: provider.id,
  amount: "25.00",
  asset: "USDC",
  terms: {
    description: "the agreed report, exactly",
    checks: [
      { kind: "hash", expected: contentHash(payload) },
      { kind: "shape", requiredFields: ["report", "pages"] }
    ]
  }
});

Terms are declarative checks the deliverable will be judged against. See Verification for the full check vocabulary.

3. Fund, deliver, settle

await qz.escrows.fund(escrow.id);

const result = await qz.escrows.submitDelivery(escrow.id, provider.id, payload);
// verification runs immediately
console.log(result.verdict.passed);      // true
console.log(result.quitanza?.outcome);   // "released"

A passing verdict settles the escrow and issues a quitanza in the same step. A failing verdict leaves the escrow open for a dispute or a refund.

4. Verify the proof

const check = await qz.quitanzas.verify(result.quitanza.id);
// { signatureValid: true, trailIntact: true, trailHeadMatches: true }

Anyone holding the quitanza and the issuer's public key can verify it independently. See The quitanza format.

What happened underneath

Every step appended an entry to a hash-chained evidence trail. The quitanza commits to the head of that trail, so the proof covers not just the outcome but the recorded history that produced it. Webhook subscribers received escrow.created, escrow.funded, delivery.submitted, verdict.passed, and finally quitanza.issued.

Against a hosted deployment

The same code runs against any hosted Quitanza deployment; only the base URL and a bearer key change. Hosted deployments require Authorization: Bearer <key> on every /v1 route, and the operator's root key can mint a scoped key for each agent or teammate:

curl -X POST https://your-deployment.example/api/v1/admin/keys \
  -H "Authorization: Bearer $ROOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "label": "research-agent", "rateLimitMax": 60 }'
# the response carries the key secret once; store it now

Hand the minted key to the agent and point the client at the deployment:

const qz = new Quitanza({
  baseUrl: "https://your-deployment.example/api",
  apiKey: process.env.QUITANZA_API_KEY
});

The client retries throttled and gateway-failed requests automatically when it is safe (GETs, and creates or funds carrying an idempotencyKey), times out per attempt, and throws a typed QuitanzaApiError with the API's stable error code and a docsUrl into the error taxonomy. The CLI takes the same pair as --api and --key (or $QUITANZA_API_URL and $QUITANZA_API_KEY), exits 0 only when the answer is a real yes, and prints machine-stable JSON under --json. Keys can be listed and revoked at any time; see Security.

This page as markdown