# x402 Stacks API — Full Reference > Complete documentation for x402.aibtc.com — pay-per-use API on Stacks blockchain. **Production:** https://x402.aibtc.com **Staging:** https://x402.aibtc.dev **Quick-start:** https://x402.aibtc.com/llms.txt **OpenAPI spec:** https://x402.aibtc.com/openapi.json For the full aibtc agent platform, see https://aibtc.com/llms-full.txt ## Payment Architecture x402 v2 is a Coinbase-compatible HTTP payment protocol. The Stacks blockchain is used for payment settlement — STX, sBTC (Bitcoin on Stacks), or USDCx (USDC). ### x402 v2 Headers | Header | Direction | Description | |----------------------|------------------|--------------------------------------------| | payment-required | server → client | base64(PaymentRequiredV2) on 402 response | | payment-signature | client → server | base64(PaymentPayloadV2) on paid request | | payment-response | server → client | base64(PaymentResponseV2) on success | | X-PAYMENT-TOKEN-TYPE | client → server | Token selection: STX, sBTC, USDCx | Legacy headers (still accepted for backward compatibility): - `X-PAYMENT` (replaces payment-signature) - `X-PAYMENT-RESPONSE` (replaces payment-response) ### Canonical Payment Lifecycle ``` requires_payment -> queued -> broadcasting -> mempool -> confirmed | failed | replaced | not_found ``` - `submitted` is internal relay observability only and is never caller-facing - `paymentId` is relay-owned and stays stable while a payment is in-flight - x402-api still uses immediate pay-per-call delivery during this phase, so in-flight payments return retryable payment errors instead of switching to a receipt-only API - `checkStatusUrl` is an additive canonical polling hint when the relay provides it ### PaymentRequiredV2 Structure (base64-decoded) ```json { "x402Version": 2, "resource": { "url": "/hashing/sha256", "description": "x402 API - /hashing/sha256", "mimeType": "application/json" }, "accepts": [ { "scheme": "exact", "network": "stacks:1", "amount": "1000", "asset": "STX", "payTo": "SP1XXXXXXXXX", "maxTimeoutSeconds": 300, "extra": { "pricing": { "type": "fixed", "tier": "standard" } } } ] } ``` ### x402.json Discovery Manifest ``` GET /x402.json ``` Returns machine-readable payment manifest with supported tokens, pricing tiers, relay URL, and payment lifecycle metadata. Use this to auto-configure x402-stacks clients. ## Pricing ### Standard Tier (all paid endpoints except OpenRouter LLM) | Token | Amount | Approximate USD | |-------|---------------|-----------------| | STX | 1000 microSTX | ~$0.0005 | | sBTC | 1 satoshi | ~$0.001 | | USDCx | 1000 micro | ~$0.001 | ### Dynamic Tier (OpenRouter LLM only) OpenRouter cost + 20% margin. Minimum $0.001 USD equivalent. Formula: `(input_tokens * model_prompt_cost + output_tokens * model_completion_cost) * 1.20` The server estimates tokens before the request and charges accordingly. Pricing is pre-verified in the 402 response — clients sign the exact quoted amount. Estimated output tokens = min(max_tokens, input_tokens * 2). ### Token Exchange Rates (approximate, embedded in pricing) | Token | Rate | |-------|-----------| | STX | $0.50 USD | | sBTC | $100,000 USD (1 BTC) | | USDCx | $1.00 USD | ## Free Endpoints (No Payment Required) ``` GET / — Service info JSON GET /health — Health check GET /docs — Swagger UI (interactive docs) GET /openapi.json — OpenAPI 3.1 spec GET /x402.json — x402 payment manifest GET /dashboard — Usage dashboard (HTML) GET /llms.txt — Quick-start guide (this chain) GET /llms-full.txt — Full reference (this document) GET /topics — Topic documentation index GET /topics/:topic — Topic sub-docs GET /.well-known/agent.json — A2A agent card GET /inference/openrouter/models — List available OpenRouter models GET /inference/cloudflare/models — List available Cloudflare AI models ``` ## Inference Endpoints ### OpenRouter LLM (Dynamic Pricing) **List Models (free)** ``` GET /inference/openrouter/models Response: { models: [{ id, name, description, context_length, pricing }] } ``` **Chat Completion (dynamic pricing)** ``` POST /inference/openrouter/chat Content-Type: application/json payment-signature: X-PAYMENT-TOKEN-TYPE: STX (optional, default STX) Request body: { "model": "anthropic/claude-3-haiku", // required "messages": [ // required { "role": "system", "content": "You are helpful." }, { "role": "user", "content": "Hello!" } ], "temperature": 0.7, // optional, 0-2 "max_tokens": 1024, // optional "stream": false, // optional, default false "top_p": 1.0, // optional "frequency_penalty": 0, // optional "presence_penalty": 0, // optional "stop": null // optional, string or array } Response (OpenAI-compatible): { "id": "chatcmpl-xxx", "model": "anthropic/claude-3-haiku", "choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help?" }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 20, "completion_tokens": 12, "total_tokens": 32 } } ``` Pricing is estimated before the request. The 402 response includes the quoted amount. Dynamic models include: openai/gpt-4o, anthropic/claude-opus-4, anthropic/claude-sonnet-4-5, google/gemini-pro, meta-llama/llama-3.1-70b-instruct, mistralai/mistral-7b-instruct, and 100+ more. See /inference/openrouter/models for the full list. ### Cloudflare AI (Standard Pricing) **List Models (free)** ``` GET /inference/cloudflare/models Response: { models: [{ id, name, description }] } ``` **Chat Completion (0.001 STX)** ``` POST /inference/cloudflare/chat Request: same format as OpenRouter (model must be a @cf/ model id) Response: OpenAI-compatible chat completion ``` Topic doc: https://x402.aibtc.com/topics/inference ## Stacks Endpoints (Standard Pricing: 0.001 STX each) ### Address Convert ``` GET /stacks/address/:address Path param: :address — any Stacks or Bitcoin address Response: { "ok": true, "input": "bc1q...", "stxAddress": "SP...", "btcAddress": "bc1q...", "tokenType": "STX" } ``` ### Decode Clarity Value ``` POST /stacks/decode/clarity { "hex": "0x0100000000000000000000000000000001" // Clarity-encoded hex } Response: { "ok": true, "decoded": { "type": "uint", "value": "1" }, "tokenType": "STX" } ``` ### Decode Transaction ``` POST /stacks/decode/transaction { "hex": "0x8080000000040..." // Raw serialized Stacks transaction hex } Response: { "ok": true, "transaction": { ...decoded tx fields }, "tokenType": "STX" } ``` ### Profile Lookup ``` GET /stacks/profile/:address Path param: :address — Stacks address (SP...) Response: { "ok": true, "address": "SP...", "profile": { "name": "...", "description": "..." }, "tokenType": "STX" } ``` ### Verify BIP-137 Message ``` POST /stacks/verify/message { "message": "Hello world", "signature": "...", // BIP-137 Bitcoin signature "address": "bc1q..." // Bitcoin address (optional, for verification) } Response: { "ok": true, "valid": true, "address": "bc1q...", "tokenType": "STX" } ``` ### Verify SIP-018 Structured Data ``` POST /stacks/verify/sip018 { "domain": { "name": "App", "version": "1.0.0", "chainId": 1 }, "message": { "amount": 100 }, "signature": "...", "publicKey": "02..." } Response: { "ok": true, "valid": true, "signer": "SP...", "tokenType": "STX" } ``` ## Hashing Endpoints (Standard Pricing: 0.001 STX each) All hashing endpoints use the same request/response format: ``` POST /hashing/{algorithm} { "data": "hello world", // text, or hex with 0x prefix for binary data "encoding": "hex" // optional: "hex" (default) or "base64" } Response: { "ok": true, "hash": "b94d27b9934d3e08a52e52d7da7dabfac484efe04294e576c4d552b5b03e82a", "algorithm": "SHA-256", "encoding": "hex", "inputLength": 11, "tokenType": "STX" } ``` **Available algorithms:** | Endpoint | Algorithm | Output | Clarity-compatible | |-------------------------|------------|---------|--------------------| | POST /hashing/sha256 | SHA-256 | 32 bytes | Yes (hash160 uses this) | | POST /hashing/sha512 | SHA-512 | 64 bytes | Yes | | POST /hashing/sha512-256| SHA-512/256| 32 bytes | Yes (Stacks tx hashing) | | POST /hashing/keccak256 | Keccak-256 | 32 bytes | Yes | | POST /hashing/hash160 | HASH160 | 20 bytes | Yes (Bitcoin address derivation) | | POST /hashing/ripemd160 | RIPEMD-160 | 20 bytes | Yes | HASH160 = RIPEMD-160(SHA-256(input)) — same as Bitcoin's hash160 used in P2PKH addresses. Topic doc: https://x402.aibtc.com/topics/hashing ## Storage Endpoints (Standard Pricing: 0.001 STX each) All storage is scoped to the paying agent's Stacks address (derived from payment signature). Each payer gets isolated storage in a Durable Object keyed by their Stacks address. ### KV Store ``` POST /storage/kv — Set value GET /storage/kv/:key — Get value DELETE /storage/kv/:key — Delete value GET /storage/kv — List keys POST /storage/kv { "key": "my-key", "value": "my-value", "metadata": {}, "ttl": 3600 } Response: { "ok": true, "key": "my-key", "created": true, "tokenType": "STX" } GET /storage/kv/:key Response: { "ok": true, "key": "my-key", "value": "my-value", "metadata": {}, "tokenType": "STX" } GET /storage/kv Response: { "ok": true, "keys": [{ "key": "...", "metadata": {} }], "tokenType": "STX" } ``` ### Paste Bin ``` POST /storage/paste — Create paste GET /storage/paste/:id — Get paste DELETE /storage/paste/:id — Delete paste POST /storage/paste { "content": "...", "title": "optional", "language": "typescript", "ttl": 86400 } Response: { "ok": true, "id": "paste-uuid", "createdAt": "...", "expiresAt": "...", "tokenType": "STX" } ``` ### SQL Database ``` POST /storage/db/query — Read-only SQL query POST /storage/db/execute — Mutating SQL statement GET /storage/db/schema — Schema introspection POST /storage/db/query { "sql": "SELECT * FROM items WHERE id = ?", "params": [42] } Response: { "ok": true, "rows": [...], "rowCount": 1, "tokenType": "STX" } POST /storage/db/execute { "sql": "INSERT INTO items (name) VALUES (?)", "params": ["test"] } Response: { "ok": true, "rowsAffected": 1, "lastInsertRowid": 1, "tokenType": "STX" } ``` SQLite-compatible. Each payer has their own isolated SQLite database. ### Distributed Sync / Locks ``` POST /storage/sync/lock — Acquire lock POST /storage/sync/unlock — Release lock POST /storage/sync/extend — Extend lock TTL GET /storage/sync/status/:name — Check lock status GET /storage/sync/list — List active locks POST /storage/sync/lock { "name": "my-resource", "ttl": 60 } // ttl: 10-300 seconds, default 60 Response: { "ok": true, "acquired": true, "token": "lock-token-uuid", ... } POST /storage/sync/unlock { "name": "my-resource", "token": "lock-token-uuid" } Response: { "ok": true, "released": true, ... } ``` Used to coordinate concurrent agent processes. Lock tokens prevent unauthorized unlocks. ### Job Queue ``` POST /storage/queue/push — Enqueue job POST /storage/queue/pop — Dequeue job (removes from queue) GET /storage/queue/peek — View next job (does not remove) GET /storage/queue/status — Queue stats POST /storage/queue/clear — Clear all queued jobs POST /storage/queue/push { "data": { "taskId": "abc", "type": "email" }, "priority": 5 } Response: { "ok": true, "id": "job-uuid", "position": 1, ... } POST /storage/queue/pop Response: { "ok": true, "job": { "id": "...", "data": {...} }, ... } ``` ### Vector Memory (Semantic Search) ``` POST /storage/memory/store — Store items with embeddings POST /storage/memory/search — Semantic similarity search POST /storage/memory/delete — Delete items by id GET /storage/memory/list — List stored items POST /storage/memory/clear — Delete all items POST /storage/memory/store { "items": [ { "id": "doc-1", "text": "Paris is the capital of France", "metadata": { "source": "wiki" } } ] } Response: { "ok": true, "stored": 1, "tokenType": "STX" } POST /storage/memory/search { "query": "What is the capital of France?", "topK": 5 } Response: { "ok": true, "results": [{ "id": "doc-1", "text": "...", "score": 0.92 }], ... } ``` Uses Cloudflare AI (BAAI/bge-base-en-v1.5) for embeddings. Cosine similarity search. Topic doc: https://x402.aibtc.com/topics/storage ## Safety Scanning Storage write operations are background-scanned for safety using Cloudflare Workers AI. Scanning does not block writes or affect response time — it runs after the response is sent. ### Scanned Operations | Endpoint | Scanned | |------------------------|---------| | POST /storage/paste | Yes (content field) | | POST /storage/kv | Yes (value field) | | POST /storage/memory/store | Yes (item text fields) | | GET, DELETE operations | No | | /storage/sync/* | No (locks, not content) | | /storage/queue/* | No (job metadata) | ### Scan Behavior - **Fire-and-forget:** scan runs via `waitUntil()` after response is returned - **Flag-first:** content is stored regardless of scan verdict - **Non-blocking:** writes never fail due to safety scan results - **Isolated:** verdicts stored in the agent's own Durable Object (`content_scans` table) ### Flag Categories | Flag | Description | |-----------------------|--------------------------------------------------| | spam | Unsolicited bulk content, repetitive patterns | | harassment | Targeted threats, insults, or intimidation | | hate_speech | Content targeting protected characteristics | | violence | Graphic violence or threats of violence | | adult_content | Explicit sexual content | | malware | Code or links that appear malicious | | pii_exposure | Exposed credentials or real PII (SSNs, keys) | | prompt_injection | Attempts to override AI system instructions | | jailbreak_attempt | Attempts to bypass AI safety controls | **Note:** Developer content (code, configs, example API keys, URLs) is handled with false-positive reduction rules. Storing code snippets or configuration files will not trigger spurious flags in normal circumstances. ### Verdicts Scan verdicts are stored internally in the `content_scans` table of the agent's Durable Object. Verdicts are not currently returned in write operation responses. This is a platform safety measure — not a separate endpoint or billable service. ## Payment Flow Deep-Dive Topic doc: https://x402.aibtc.com/topics/payment-flow ## Topic Documentation | Topic | URL | Contents | |--------------|----------------------------------------------|---------------------------------------------| | inference | https://x402.aibtc.com/topics/inference | OpenRouter + Cloudflare AI, dynamic pricing | | hashing | https://x402.aibtc.com/topics/hashing | All hash endpoints with examples | | storage | https://x402.aibtc.com/topics/storage | KV, paste, db, sync, queue, memory patterns | | payment-flow | https://x402.aibtc.com/topics/payment-flow | x402 v2 challenge/response flow in detail | ## Error Handling All endpoints return structured errors: ```json { "ok": false, "error": "description", "tokenType": "STX" } ``` | Status | Meaning | |--------|--------------------------------------------------| | 400 | Bad request (missing required fields, etc.) | | 402 | Payment required (x402 challenge response) | | 404 | Not found (key, paste, job, lock does not exist) | | 500 | Server error (upstream API, Durable Object, etc) | ### Payment Error Hints All non-200 payment error responses include structured retry hints in both JSON body and the `payment-response` header (base64 JSON, same convention as success path): ```json { "error": "Payment failed in settlement relay", "code": "transaction_failed", "retryable": true, "nextSteps": "rebuild_and_resign", "retryAfter": 30, "paymentId": "pay_abc123", "checkStatusUrl": "https://relay.example.com/payment/pay_abc123" } ``` `nextSteps` is a stable token (not free-form prose) clients can branch on: | Token | Meaning | |------------------------|---------------------------------------------------------------| | `rebuild_and_resign` | Sender nonce issue — build and sign a fresh transaction | | `retry_later` | Transient relay/settlement error — retry after `retryAfter` s | | `start_new_payment` | Payment replaced or identity lost — begin a new x402 flow | | `fix_and_resend` | Invalid transaction payload — correct it before retrying | | `wait_for_confirmation`| Payment confirmed — resource delivery should proceed | The `payment-response` header on error paths carries `base64({ retryable, nextSteps, retryAfter? })` — decode with `atob()` + `JSON.parse()`. `retryAfter` is only present when the hint is `retry_later`. Topic doc: https://x402.aibtc.com/topics/payment-flow ## Related - AIBTC platform hub: https://aibtc.com/llms.txt - x402 protocol spec: https://www.x402.org/ - x402-stacks npm: https://www.npmjs.com/package/x402-stacks - Stacks.js: https://docs.stacks.co/stacks.js