Home · Lanes · Router · Docs · Dashboard · Pricing · Control Plane
For Builders — First Paid Run

Quickstart

Your fastest path to a real paid run with routing, receipts, verification, memory, and evidence. Follow the steps below to go from zero to a completed paid receipt in under five minutes.

Two entry paths: This guide uses an X-API-Key for the fastest onboarding. The README also covers the x402 wallet-signed path (@x402/fetch) for agents that pay autonomously on-chain without an API key.

Before you start

You need an Attestify OS API key (atst_…). Get one at /onboarding in under a minute. Once you have a key, add it as X-API-Key on every request to POST /api/run.

🔑 Framework-agnostic — no SDK required. The atst_… key is just an HTTP header on a standard HTTPS request. Use it from curl, fetch(), LangChain, CrewAI, AutoGen, LlamaIndex, or any agent framework. The only integration requirement is:
X-API-Key: atst_…
Content-Type: application/json

1. Pick a lane

Every request goes through POST /api/run. You can let the router choose the lane, or you can steer it.

Router-first (default)
Omit lane_id entirely. The router reads your task and selects the best lane. Best for: unclear task type, mixed workloads.
Direct lane (explicit)
Pass "lane_id": "comedian-v1" at the top level of input. Locks the lane. Best for: test runs, known output type, deterministic execution.
Cheapest first run: use "lane_id": "comedian-v1" to validate the full paid execution loop (wallet, payment, routing, receipts, verification, dashboard) at the lowest cost (0.010 USDC/run) before switching to premium lanes.

2. Make your first request

Copy this curl command, replace YOUR_KEY with your atst_… key, and run it:

curl -X POST https://attestify-os.vercel.app/api/run \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
    "session_id": "quickstart-001",
    "intent": "Tell me a short joke about software developers.",
    "lane_id": "comedian-v1",
    "options": {
      "include_memory": false,
      "write_memory": false,
      "verify": true
    },
    "idempotency_key": "idem-quickstart-001"
  }'
Replace YOUR_KEY. The request will 401 without a valid atst_… key. Get one at /onboarding.

3. Read the response

A successful paid run returns a structured receipt. Here is what to look for:

{
  "loop_id": "loop_abc123",
  "run_id": "run_abc123",
  "status": "success",
  "execution_status": "completed",
  "lane_id": "comedian-v1",
  "agent_id": "comedian-v1",
  "result": { "output": "Why do developers prefer dark mode? Because light attracts bugs." },
  "pricing": {
    "price_usdc": 0.010,
    "base_lane_price_usdc": 0.005,
    "orchestration_price_usdc": 0.005
  },
  "receipt": {
    "loop_id": "loop_abc123",
    "lane_id": "comedian-v1",
    "settled": true,
    "price_usdc": 0.010,
    "tx_hash": "0x33e8a84c..."
  },
  "verification": { "verified": true, "score": 0.82, "grade": "A" },
  "settlement": { "success": true, "transaction": "0x33e8a84c...", "network": "eip155:8453" }
}

4. Verify it worked

  • execution_status: "completed" — the task finished.
  • receipt.settled: true — the payment settled.
  • verification.verified: true — the run passed the quality check.
  • settlement.transaction — on-chain tx hash, verifiable on Basescan.
Open https://attestify-os.vercel.app/receipts/<loop_id> in your browser. It loads a public receipt page with full execution evidence, verification score, and settlement proof. Share it as confirmation that real paid work happened.

5. Check the dashboard

Open /dashboard to see your loop in the live Control Tower view. It shows total runs, paid runs, revenue, success rate, and per-lane performance.

6. Inspect the router response

When using router-first execution (no explicit lane_id), the response includes a routing block:

{
  "routing": {
    "mode": "semantic",
    "recommended_agent_id": "researcher-v2",
    "reason": "Semantic match: researcher-v2 (score=0.612)",
    "confidence": 0.92,
    "preferred_used": false,
    "routing_version": "2026-06-routing-v2"
  }
}
Inspect first
Check routing.mode to see whether your preference was used, what lane was selected, and why. Modes: explicit, preferred, semantic, fallback.
Check pricing
Inspect pricing.price_usdc, pricing.base_lane_price_usdc, and pricing.orchestration_price_usdc instead of inferring cost from lane name alone.
Verify proof
Use receipt.tx_hash, verification, and settlement to confirm the full paid run completed as expected.

7. Canonical request shape

This is the full request object shape sent directly as the POST body. All fields use snake_case. Fields marked optional can be omitted.

{
  "session_id": "",             // your session identifier
  "intent": "",                 // what you want the lane to do (preferred field)
  "task": "",                   // alias for intent — either works
  "lane_id": "",                // optional: pin to a specific lane directly
  "preferences": {
    "preferred_lane_id": ""     // optional: soft-steer the router without pinning
  },
  "constraints": {
    "max_cost_usdc": 0.05,      // optional: reject if lane price exceeds this
    "priority": "quality"       // optional: "quality" | "speed" | "cost"
  },
  "options": {
    "include_memory": true,
    "write_memory": true,
    "verify": true,
    "webhook_url": ""           // optional: POST receipt to this URL after run
  },
  "idempotency_key": ""         // optional: deduplicate retries
}
Field naming: All request and response fields use snake_case throughout — session_id, lane_id, include_memory, write_memory. The response returns both lane_id and agent_id (same value) for compatibility.

8. Optional governance inputs

When you want budget and policy controls, extend the request body with the governance block:

{
  "session_id": "my-session",
  "intent": "Analyse Q2 revenue trends.",
  "preferences": { "preferred_lane_id": "analyst-v1" },
  "constraints": {
    "max_cost_usdc": 0.05,
    "priority": "quality"
  },
  "options": {
    "include_memory": true,
    "write_memory": true,
    "verify": true
  }
}
Enterprise — Payment Governance

How to mandate your agent's payments

Every payment your agent makes can be pre-authorised, autonomously executed, and reported back — with a cryptographic before-and-after record tied to your mandate. This is the 3-call flow.

The mandate works in three legs. The agent never makes a payment without a signed token from Attestify. The payment happens outside Attestify's visibility — on any rail you choose. The agent then reports back, closing the transaction record.

1
Pre-auth — agent requests authorisationBefore payment

Before spending, the agent calls POST /api/pre-auth. Attestify checks the intent against your mandate (daily cap, merchant category, policy ID) and returns a signed token valid for 60 seconds. If the check fails, payment is blocked — before any money moves.

// Step 1: agent calls this before paying
curl -X POST https://attestify-os.vercel.app/api/pre-auth \
  -H "X-API-Key: atst_…" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "my-finance-agent",
    "action": "payment",
    "amount": 120,
    "currency": "USDC",
    "merchant": "AWS",
    "category": "Cloud infrastructure",
    "task_id": "T-991"
  }'
Returns: { "auth_token": "atx_…", "txn_ref": "ATX-0042", "expires_in": 60, "approved": true }
2
Execute — payment runs autonomouslyOutside Attestify

The agent holds the auth_token and proceeds to pay on any rail — Stripe, x402, bank transfer, or crypto. Attestify is not in the money path. The token expires in 60 seconds; if payment isn't initiated within that window, the agent must request a fresh pre-auth.

// Step 2: agent executes payment autonomously
// (example using x402 — any payment rail works)

await paymentRail.charge({
  amount: 120,
  currency: 'USDC',
  merchant: 'AWS',
  reference: 'ATX-0042', // attach txn_ref for reconciliation
  auth_token: 'atx_…',  // proof of pre-auth
});
Attestify never sees card numbers, bank accounts, or wallet keys. It only sees the intent (before) and the outcome (after). The payment rail is entirely your choice.
3
Close — agent reports backAfter payment

After the payment settles, the agent calls POST /api/receipts/close with the actual amount, receipt URL, and status. Attestify links the pre-auth record to the settlement record. If the actual amount differs from what was authorised, a drift flag is raised and you receive an alert.

// Step 3: agent closes the transaction
curl -X POST https://attestify-os.vercel.app/api/receipts/close \
  -H "X-API-Key: atst_…" \
  -H "Content-Type: application/json" \
  -d '{
    "txn_ref": "ATX-0042",
    "actual_amount": 118.50,
    "currency": "USDC",
    "receipt_url": "https://your-payment-rail.com/receipts/r_xyz",
    "timestamp": "2026-06-15T11:30:00Z",
    "status": "settled"
  }'
Returns: { "closed": true, "drift": false, "authorised": 120, "actual": 118.50, "record": "https://attestify-os.vercel.app/receipts/ATX-0042" }
What you get with every mandated payment
Pre-auth receipt
Proof the agent checked before acting — not just that a payment happened.
Intent-to-outcome link
Before + after anchored by one txn_ref — auditable and legally defensible.
Drift detection
If actual spend differs from what was authorised, you get an alert immediately.
Rail-agnostic
Attestify governs the intent — not the money path. Use Stripe, x402, bank transfer, or crypto.
→ Full API docs→ Control Tower→ Spend limits & policies→ Pricing