{"openapi":"3.0.3","info":{"title":"Cleared Protocol API","version":"1.0.0","description":"Versioned API for web users, SDK integrators, and AI agents. See ADR-012.","license":{"name":"UNLICENSED"}},"servers":[{"url":"/v1"}],"components":{"securitySchemes":{"OAuthBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"OAuth bearer token from Privy (for web app)"},"CliOAuthBearer":{"type":"http","scheme":"bearer","bearerFormat":"opaque","description":"Opaque, revocable Cleared CLI OAuth token. Distinct from Privy JWT authentication."},"ClearedHMAC":{"type":"apiKey","in":"header","name":"Authorization","description":"HMAC-SHA256 signature. Requires x-cleared-key, x-cleared-ts, x-cleared-nonce headers."}},"schemas":{"Invoice":{"type":"object","required":["id","chainId","agent","payer","merchant","token","amount","metaHash","tokenURI","status","issuedAt"],"properties":{"id":{"type":"string"},"chainId":{"type":"integer"},"agent":{"type":"string"},"payer":{"type":"string"},"merchant":{"type":"string"},"token":{"type":"string"},"amount":{"type":"string","description":"BigInt as string (e.g., \"1000000\" for 1 USDC)"},"dueAt":{"type":"string"},"metaHash":{"type":"string"},"tokenURI":{"type":"string","format":"uri"},"status":{"type":"string","enum":["Issued","Paid","Canceled"]},"refBps":{"type":"integer"},"referrer":{"type":"string"},"issuedAt":{"type":"string"},"paidAt":{"type":"string"},"canceledAt":{"type":"string"},"quoteId":{"type":"string"},"currency":{"type":"string","example":"USDC"},"amountFormatted":{"type":"string","example":"1.00"},"fee":{"type":"object","description":"Returned by the authenticated GET /v1/invoices/{id}. Paid: settledFee is the fee charged at settlement (never recomputed). Issued: effectiveFeeBps is the current merchant rate for a preview (0 = retail). Null means unavailable, not zero.","required":["settledFee","settledFeeBps","effectiveFeeBps"],"properties":{"settledFee":{"type":"string","nullable":true,"description":"Protocol fee from InvoiceSettled, USDC base units"},"settledFeeBps":{"type":"integer","nullable":true},"effectiveFeeBps":{"type":"integer","nullable":true}}}}},"AccountMetrics":{"type":"object","required":["address","quotesCreated","quotesAccepted","quotesRejected","quotesExpired","invoicesIssued","invoicesPaid","invoicesCanceled","grossVolume","protocolFees","netVolume"],"properties":{"address":{"type":"string"},"quotesCreated":{"type":"integer"},"quotesAccepted":{"type":"integer"},"quotesRejected":{"type":"integer"},"quotesExpired":{"type":"integer"},"invoicesIssued":{"type":"integer"},"invoicesPaid":{"type":"integer"},"invoicesCanceled":{"type":"integer"},"grossVolume":{"type":"string"},"protocolFees":{"type":"string"},"netVolume":{"type":"string"}}},"ProtocolStats":{"type":"object","required":["totalInvoices","totalVolume6d","totalFees6d","chain","token","fees"],"properties":{"totalQuotes":{"type":"integer","description":"Legacy optional total; omitted when unavailable, never defaulted to zero."},"totalQuotesAccepted":{"type":"integer"},"totalQuotesRejected":{"type":"integer"},"totalQuotesExpired":{"type":"integer"},"totalInvoices":{"type":"integer"},"totalInvoicesPaid":{"type":"integer"},"totalInvoicesCanceled":{"type":"integer"},"totalVolume6d":{"type":"string"},"totalFees6d":{"type":"string"},"chain":{"type":"object","required":["id","name","network"],"properties":{"id":{"type":"integer","enum":[8453,84532]},"name":{"type":"string"},"network":{"type":"string","enum":["base","base-sepolia"]}}},"token":{"type":"object","required":["symbol","decimals"],"properties":{"symbol":{"type":"string","enum":["USDC"]},"decimals":{"type":"integer","enum":[6]}}},"fees":{"type":"object","required":["retailBps","retailCap6d","merchantSpecific","description"],"properties":{"retailBps":{"type":"string"},"retailCap6d":{"type":"string"},"merchantSpecific":{"type":"boolean","enum":[true]},"description":{"type":"string"}}},"lastUpdated":{"type":"string"}}},"InvoiceStats":{"type":"object","required":["totalCount","pendingCount","paidCount","canceledCount","totalPaidAmount","totalPendingAmount","coverage","feesPaid","statuses"],"properties":{"totalCount":{"type":"integer","nullable":true},"pendingCount":{"type":"integer","nullable":true},"paidCount":{"type":"integer","nullable":true},"canceledCount":{"type":"integer","nullable":true},"totalPaidAmount":{"type":"string","nullable":true},"totalPendingAmount":{"type":"string","nullable":true},"coverage":{"type":"string","enum":["complete","partial"]},"feesPaid":{"type":"object","description":"Sum of protocol fees actually charged on every Paid invoice of the merchant (from settlement events, never recomputed). partial means at least the shown total (missing settlement events, page ceiling or indexer errors); unavailable means the read failed.","required":["total6d","paymentCount","coverage"],"properties":{"total6d":{"type":"string","nullable":true},"paymentCount":{"type":"integer","nullable":true},"coverage":{"type":"string","enum":["complete","partial","unavailable"]}}},"statuses":{"type":"object","description":"Per-status observed values and provenance. Partial values are not lifetime totals.","additionalProperties":{"type":"object","required":["available","truncated","source","observedCount","observedAmount"],"properties":{"available":{"type":"boolean"},"truncated":{"type":"boolean"},"source":{"type":"string","enum":["indexer","chain","hybrid","unavailable"]},"notes":{"type":"string"},"degraded":{"type":"boolean"},"observedCount":{"type":"integer","nullable":true},"observedAmount":{"type":"string","nullable":true}}}}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]},"requestId":{"type":"string"}},"required":["error"]},"IdempotencyMeta":{"type":"object","description":"Idempotency metadata included in all invoice creation responses when Idempotency-Key is sent.","required":["key","replayed","state"],"properties":{"key":{"type":"string","description":"The caller-provided idempotency key."},"replayed":{"type":"boolean","description":"True if this response is a replay of a previous request with the same key."},"state":{"type":"string","enum":["prepared","submit_pending","confirmed","failed_retryable","failed_terminal"],"description":"Current state of the idempotent request."}}},"ReadMeta":{"type":"object","properties":{"source":{"type":"string","enum":["indexer","chain","hybrid"]},"indexerSyncedBlock":{"type":"integer"},"chainHeadBlock":{"type":"integer"},"reconciled":{"type":"boolean"},"requestId":{"type":"string","format":"uuid"}}},"CliOAuthToken":{"type":"object","required":["access_token","token_type","expires_in","refresh_token","refresh_expires_in","scope","grant_id","user","studio","api_origin","web_origin"],"properties":{"access_token":{"type":"string","pattern":"^clr_oat_"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer","enum":[900]},"refresh_token":{"type":"string","pattern":"^clr_ort_"},"refresh_expires_in":{"type":"integer","maximum":2592000},"scope":{"type":"string"},"grant_id":{"type":"string","format":"uuid"},"user":{"type":"object"},"studio":{"type":"object"},"api_origin":{"type":"string","format":"uri"},"web_origin":{"type":"string","format":"uri"}}},"OAuthError":{"type":"object","required":["error","error_description"],"properties":{"error":{"type":"string","enum":["invalid_request","invalid_client","invalid_grant","invalid_scope","unsupported_grant_type","temporarily_unavailable"]},"error_description":{"type":"string"},"request_id":{"type":"string"}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Caller-provided idempotency key (1-128 visible ASCII chars). Required when INVOICE_CREATE_REQUIRE_IDEMPOTENCY=true. When present, the server deduplicates invoice creation: same key + same payload returns the original result, same key + different payload returns 409 IDEMPOTENCY_CONFLICT.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[\\x21-\\x7E]{1,128}$"}}},"responses":{"IdempotencyConflict":{"description":"Same idempotency key was used with a different payload.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["IDEMPOTENCY_CONFLICT"]},"message":{"type":"string"},"idempotency":{"$ref":"#/components/schemas/IdempotencyMeta"}}}}}},"IdempotencyPrepareRequired":{"description":"Browser submit called without a matching prepared row. Client must call POST /v1/invoices/prepare first.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["IDEMPOTENCY_PREPARE_REQUIRED"]},"message":{"type":"string"}}}}}}}},"paths":{"/oauth/authorize":{"post":{"summary":"Approve or deny CLI authorization","description":"Privy-authenticated browser consent endpoint for the fixed cleared-cli public client. Returns only an exact validated loopback redirect URI; the browser performs navigation.","security":[{"OAuthBearer":[]}],"responses":{"200":{"description":"Exact validated loopback redirect URI"},"400":{"description":"Invalid authorization request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/oauth/token":{"post":{"summary":"Exchange a PKCE code or rotate a refresh token","description":"Public-client endpoint. Accepts authorization_code with S256 verifier and exact redirect URI, or refresh_token. No client secret is accepted.","security":[],"responses":{"200":{"description":"Opaque access and rotating refresh token pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliOAuthToken"}}}},"400":{"description":"Invalid, expired, replayed, or unsupported grant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/oauth/revoke":{"post":{"summary":"Revoke a CLI OAuth grant using refresh-token proof","security":[],"responses":{"200":{"description":"Idempotent revocation result"},"400":{"description":"Malformed request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/oauth/session":{"get":{"summary":"Read redacted CLI OAuth session metadata","security":[{"CliOAuthBearer":[]}],"responses":{"200":{"description":"Grant, identity, studio, scope, and expiry metadata"},"401":{"description":"Invalid, expired, or revoked access token"}}}},"/oauth/revoke/current":{"post":{"summary":"Revoke the current CLI OAuth grant","security":[{"CliOAuthBearer":[]}],"responses":{"200":{"description":"Grant revoked"},"401":{"description":"Invalid, expired, or revoked access token"}}}}},"tags":[]}