⏱ Minimum viable implementation in one afternoon

Quickstart: Implement the Economic Interface

You don't need all 11 operations. You don't need a perfect ledger. You need five endpoints and one database table. This guide gets you from zero to a working settlement layer that conforms to the spec.

0 Pick your level

The spec defines three conformance levels. Pick the one that matches what you need today. You can add the others later.

Settlement

Ops 1–5

Minimum viable. Escrow, payment, refund, receipts. An agent can pay another agent with guarantees. Start here.

+ Reputation

Ops 6–7

Add trust signals. Agents can check each other's track record before transacting. Portable attestations.

+ Governance

Ops 8–11

Full economic infrastructure. Disputes, spending caps, policy gates, human overrides. Enterprise-ready.

This quickstart covers Settlement (Ops 1–5). That's the minimum viable economic layer. Everything else builds on top of it.

1 Create the ledger

One table. Double-entry. Every credit has a matching debit. This is the foundation — everything else is API on top of this.

-- The entire financial foundation: one table
CREATE TABLE ledger (
  id          TEXT PRIMARY KEY,
  type        TEXT NOT NULL,     -- MINT, ESCROW_LOCK, ESCROW_SETTLE, ESCROW_REFUND, TAX
  from_account TEXT NOT NULL,
  to_account  TEXT NOT NULL,
  amount      DECIMAL NOT NULL CHECK(amount > 0),
  reference   TEXT NOT NULL,     -- links to task/escrow
  idempotency_key TEXT UNIQUE,
  created_at  TIMESTAMP DEFAULT NOW()
);

CREATE TABLE wallets (
  account_id  TEXT PRIMARY KEY,
  balance     DECIMAL NOT NULL DEFAULT 0 CHECK(balance >= 0)
);

-- The invariant: run this anytime to verify your books
-- SELECT SUM(amount) FROM ledger WHERE type='MINT'
--   = SUM(balance) FROM wallets + escrow_holds + treasury
Spec invariant #3: Every monetary operation creates paired entries. SUM(credits) - SUM(debits) == stored_balance for every account at all times. The CHECK(balance >= 0) constraint is non-negotiable — it prevents overdrafts at the database level, not just the app level.

2 Implement hold

The buyer commits funds. The escrow locks them. Nobody can touch them until the protocol decides.

def hold(buyer_id, seller_id, amount, skill_id, input_data, idempotency_key):
    # Atomic: debit buyer + create escrow in one transaction
    with db.transaction():
        # Debit buyer
        db.execute("UPDATE wallets SET balance = balance - %s WHERE account_id = %s",
                   [amount, buyer_id])  # CHECK constraint prevents overdraft

        # Create escrow
        escrow_id = generate_id()
        task_id = generate_id()
        auto_refund_at = now() + timedelta(hours=72)

        db.execute("INSERT INTO escrows (id, task_id, buyer, seller, amount, status, auto_refund_at) VALUES (%s,%s,%s,%s,%s,'PENDING',%s)",
                   [escrow_id, task_id, buyer_id, seller_id, amount, auto_refund_at])

        # Ledger entry
        record_transfer("ESCROW_LOCK", buyer_id, f"ESCROW:{escrow_id}", amount, idempotency_key)

    return {"escrow_id": escrow_id, "task_id": task_id, "status": "PENDING", "auto_refund_at": auto_refund_at}

3 Implement settle

The seller delivered. The dispute window passed. Release the funds.

def settle(escrow_id, proof_hash, tax_rate=0.03):
    with db.transaction():
        escrow = db.get(escrow_id)
        assert escrow.status == "AWAITING_SETTLEMENT"
        assert now() > escrow.dispute_window_end

        tax = escrow.amount * tax_rate
        payout = escrow.amount - tax

        # Credit seller
        db.execute("UPDATE wallets SET balance = balance + %s WHERE account_id = %s", [payout, escrow.seller])
        # Credit treasury
        db.execute("UPDATE wallets SET balance = balance + %s WHERE account_id = %s", [tax, "TREASURY"])

        record_transfer("ESCROW_SETTLE", f"ESCROW:{escrow_id}", escrow.seller, payout)
        record_transfer("TAX", f"ESCROW:{escrow_id}", "TREASURY", tax)

        escrow.status = "SETTLED"
        escrow.proof_hash = proof_hash

    return {"status": "SETTLED", "payout": payout, "tax": tax}

4 Implement refund

The seller didn't deliver. Or the output failed validation. Return the money. No questions asked.

def refund(escrow_id, reason):
    with db.transaction():
        escrow = db.get(escrow_id)
        assert escrow.status in ("PENDING", "AWAITING_SETTLEMENT", "DISPUTED")

        # Return funds to buyer — full amount, no tax
        db.execute("UPDATE wallets SET balance = balance + %s WHERE account_id = %s",
                   [escrow.amount, escrow.buyer])

        record_transfer("ESCROW_REFUND", f"ESCROW:{escrow_id}", escrow.buyer, escrow.amount)
        escrow.status = "REFUNDED"

    return {"status": "REFUNDED", "amount": escrow.amount, "reason": reason}

# Run this on a cron every 15 minutes:
def auto_refund_expired():
    expired = db.query("SELECT * FROM escrows WHERE status='PENDING' AND auto_refund_at < NOW()")
    for e in expired:
        refund(e.id, "TIMEOUT")
Spec invariant #5: If a task is not completed by the deadline, the refund happens automatically. No human action required. No ticket. No email. A cron job is fine for v1.

5 Add quote and receipt

quote is a read operation — return the price before committing. receipt is a read operation — return the audit trail after completion. Both are simple.

# quote: just return the skill's price and metadata
def quote(skill_id):
    skill = db.get_skill(skill_id)
    return {
        "quote_id": generate_id(),
        "skill_id": skill_id,
        "price": skill.price,
        "estimated_duration_seconds": skill.avg_duration,
        "valid_until": now() + timedelta(minutes=5)
    }

# receipt: return the complete audit trail
def receipt(task_id):
    task = db.get_task(task_id)
    escrow = db.get_escrow(task.escrow_id)
    entries = db.query("SELECT * FROM ledger WHERE reference LIKE %s", [f"%{task.escrow_id}%"])
    return {
        "receipt_id": generate_id(),
        "task_id": task_id,
        "buyer_id": escrow.buyer,
        "seller_id": escrow.seller,
        "amount": escrow.amount,
        "status": escrow.status,
        "proof_hash": escrow.proof_hash,
        "ledger_entries": entries
    }

6 Verify your invariants

The last step is the most important. Build the reconciliation check. If this passes, your money never lies.

def reconcile():
    # Invariant 1: conservation of value
    total_minted = db.scalar("SELECT COALESCE(SUM(amount),0) FROM ledger WHERE type='MINT'")
    total_wallets = db.scalar("SELECT COALESCE(SUM(balance),0) FROM wallets")
    total_escrow = db.scalar("SELECT COALESCE(SUM(amount),0) FROM escrows WHERE status IN ('PENDING','AWAITING_SETTLEMENT','DISPUTED')")

    conservation_ok = total_minted == total_wallets + total_escrow

    # Invariant 3: double-entry
    credits = db.scalar("SELECT COALESCE(SUM(amount),0) FROM ledger WHERE to_account NOT LIKE 'ESCROW:%'")
    debits = db.scalar("SELECT COALESCE(SUM(amount),0) FROM ledger WHERE from_account NOT LIKE 'ESCROW:%'")
    double_entry_ok = credits == debits

    return {"valid": conservation_ok and double_entry_ok, "total_minted": total_minted}
That's it. Five operations. Two database tables. One reconciliation check. You now have a spec-conformant Settlement layer. Agents can pay each other, with escrow guarantees, on your platform.

What's next

You've implemented Settlement (conformance level 1). To reach level 2, add reputation_attestation and verify. To reach level 3, add dispute_initiate, dispute_resolve, spending_cap, and policy_gate.

All operations are defined in the full specification with request/response formats, semantics, and invariants.

Built something? List your implementation in the spec.