{
  "openapi": "3.1.0",
  "info": {
    "title": "402s.shop API",
    "version": "1.2.0",
    "description": "Pay-per-call HTTP 402 utility API for AI agents. 16 endpoints (QR codes, OG images, screenshots, PDF rendering, web scraping, AI summarization, plus crypto-native: ENS resolve, wallet balance, coin price, gas price). Two payment rails: pre-paid credits (Bearer ap_live_... key, $1=5 calls via NowPayments) or x402 USDC pay-per-call (autonomous, no signup, signed EIP-3009 transferWithAuthorization on Base mainnet via the Coinbase x402 facilitator).",
    "contact": {
      "name": "402s.shop",
      "url": "https://402s.shop"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/402shop/402s-shop/blob/main/LICENSE"
    },
    "termsOfService": "https://402s.shop/docs"
  },
  "externalDocs": {
    "description": "Full docs",
    "url": "https://402s.shop/docs"
  },
  "servers": [
    { "url": "https://402s.shop", "description": "Production" }
  ],
  "components": {
    "securitySchemes": {
      "BearerCredits": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "ap_live_xxxxx",
        "description": "Pre-paid credits rail. Buy credits at https://402s.shop ($1 = 5 calls). 1 credit deducted per successful call; failures don't charge."
      },
      "X402Payment": {
        "type": "apiKey",
        "in": "header",
        "name": "X-PAYMENT",
        "description": "x402 rail. Base64-encoded JSON containing a signed EIP-3009 transferWithAuthorization payload. On first request without this header, server returns 402 with payment requirements (`accepts[]`). Sign offline with your private key, retry with X-PAYMENT. Default price: 0.001 USDC. Settlement via Coinbase CDP facilitator on Base mainnet."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" }
        },
        "required": ["error", "message"]
      },
      "Payment402Bearer": {
        "type": "object",
        "description": "Returned with HTTP 402 on the credits rail when the API key has 0 credits remaining.",
        "properties": {
          "error": { "type": "string", "enum": ["payment_required"] },
          "message": { "type": "string" },
          "topup_url": { "type": "string", "format": "uri" },
          "credits_remaining": { "type": "integer" }
        }
      },
      "Payment402X402": {
        "type": "object",
        "description": "Returned with HTTP 402 on the x402 rail when X-PAYMENT header is missing or invalid. Per x402 spec.",
        "properties": {
          "x402Version": { "type": "integer", "enum": [1] },
          "error": { "type": "string" },
          "accepts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "scheme": { "type": "string", "enum": ["exact"] },
                "network": { "type": "string", "example": "base" },
                "maxAmountRequired": { "type": "string", "description": "Atomic units (USDC has 6 decimals, so '1000' = 0.001 USDC)" },
                "resource": { "type": "string", "format": "uri" },
                "description": { "type": "string" },
                "mimeType": { "type": "string" },
                "payTo": { "type": "string" },
                "maxTimeoutSeconds": { "type": "integer" },
                "asset": { "type": "string", "description": "USDC contract address on the network" },
                "extra": {
                  "type": "object",
                  "properties": {
                    "name": { "type": "string", "example": "USD Coin" },
                    "version": { "type": "string", "example": "2" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "responses": {
      "Error400": { "description": "Invalid request body or missing required fields", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Error401": { "description": "Bearer rail: API key missing or invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Error402Bearer": { "description": "Bearer rail: out of credits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Payment402Bearer" } } } },
      "Error402X402": { "description": "x402 rail: X-PAYMENT header missing or invalid", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Payment402X402" } } } },
      "Error422": { "description": "External resource fetch failed (no charge applied)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  },
  "tags": [
    { "name": "media", "description": "Image/PDF generation: QR codes, OG images, screenshots, PDFs" },
    { "name": "scraping", "description": "Web data extraction: word count, metadata, emails, tech detection" },
    { "name": "domain", "description": "Domain intelligence: WHOIS, availability check" },
    { "name": "ai", "description": "AI-powered: YouTube transcripts, summarization" },
    { "name": "crypto", "description": "Web3-native: prices, ENS, wallet balance, gas" },
    { "name": "purchase", "description": "Buy credits autonomously via x402 (no signup needed)" }
  ],
  "paths": {
    "/api/v1/qr-code": { "post": { "tags": ["media"], "summary": "Generate QR code PNG (credits rail)", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string", "minLength": 1, "maxLength": 2048 }, "size": { "type": "integer", "minimum": 100, "maximum": 1000, "default": 300 } } } } } }, "responses": { "200": { "description": "PNG image", "content": { "image/png": {} } }, "400": { "$ref": "#/components/responses/Error400" }, "401": { "$ref": "#/components/responses/Error401" }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/qr-code": { "post": { "tags": ["media"], "summary": "Generate QR code PNG (x402 rail, 0.001 USDC)", "security": [{ "X402Payment": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" }, "size": { "type": "integer" } } } } } }, "responses": { "200": { "description": "PNG image", "content": { "image/png": {} } }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/og-image": { "post": { "tags": ["media"], "summary": "Generate 1200x630 OG image", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["title"], "properties": { "title": { "type": "string", "maxLength": 200 }, "subtitle": { "type": "string", "maxLength": 300 }, "theme": { "type": "string", "enum": ["dark", "light"], "default": "dark" } } } } } }, "responses": { "200": { "description": "PNG image", "content": { "image/png": {} } }, "400": { "$ref": "#/components/responses/Error400" }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/og-image": { "post": { "tags": ["media"], "summary": "Generate OG image (x402 rail, 0.001 USDC)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "image/png": {} }, "description": "PNG image" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/screenshot": { "post": { "tags": ["media"], "summary": "Headless Chromium screenshot of any URL", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" }, "viewport": { "type": "object", "properties": { "width": { "type": "integer" }, "height": { "type": "integer" } } }, "fullPage": { "type": "boolean", "default": false } } } } } }, "responses": { "200": { "description": "PNG image", "content": { "image/png": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" }, "422": { "$ref": "#/components/responses/Error422" } } } },
    "/api/x402/screenshot": { "post": { "tags": ["media"], "summary": "Screenshot (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "image/png": {} }, "description": "PNG image" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/pdf-from-url": { "post": { "tags": ["media"], "summary": "Render any URL to a print-ready PDF", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" }, "format": { "type": "string", "enum": ["A4", "Letter", "Legal"], "default": "A4" } } } } } }, "responses": { "200": { "description": "PDF file", "content": { "application/pdf": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/pdf-from-url": { "post": { "tags": ["media"], "summary": "URL to PDF (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/pdf": {} }, "description": "PDF file" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/word-count": { "post": { "tags": ["scraping"], "summary": "Count words and reading time on a webpage", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" } } } } } }, "responses": { "200": { "description": "Word count + reading time", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/word-count": { "post": { "tags": ["scraping"], "summary": "Word count (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Word count + reading time" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/extract-metadata": { "post": { "tags": ["scraping"], "summary": "Extract Open Graph + meta tags from any URL", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" } } } } } }, "responses": { "200": { "description": "Metadata object", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/extract-metadata": { "post": { "tags": ["scraping"], "summary": "Metadata (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Metadata object" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/extract-emails": { "post": { "tags": ["scraping"], "summary": "Find emails on a webpage", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" } } } } } }, "responses": { "200": { "description": "Array of emails", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/extract-emails": { "post": { "tags": ["scraping"], "summary": "Emails (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Array of emails" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/website-tech": { "post": { "tags": ["scraping"], "summary": "Detect framework, CMS, analytics", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "format": "uri" } } } } } }, "responses": { "200": { "description": "Tech stack object", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/website-tech": { "post": { "tags": ["scraping"], "summary": "Tech detection (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Tech stack object" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/whois": { "post": { "tags": ["domain"], "summary": "WHOIS lookup with normalized fields", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["domain"], "properties": { "domain": { "type": "string" } } } } } }, "responses": { "200": { "description": "WHOIS object", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/whois": { "post": { "tags": ["domain"], "summary": "WHOIS (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "WHOIS object" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/domain-check": { "post": { "tags": ["domain"], "summary": "Check whether a domain is available", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["domain"], "properties": { "domain": { "type": "string" } } } } } }, "responses": { "200": { "description": "Availability flag", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/domain-check": { "post": { "tags": ["domain"], "summary": "Domain availability (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Availability flag" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/youtube-transcript": { "post": { "tags": ["ai"], "summary": "YouTube video transcript with timestamps", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string" }, "lang": { "type": "string", "default": "en" } } } } } }, "responses": { "200": { "description": "Transcript array", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/youtube-transcript": { "post": { "tags": ["ai"], "summary": "YouTube transcript (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Transcript array" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/summarize": { "post": { "tags": ["ai"], "summary": "AI summary of text or URL (Claude Haiku 4.5)", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "text": { "type": "string" }, "url": { "type": "string" }, "length": { "type": "string", "enum": ["short", "medium", "long"], "default": "medium" } } } } } }, "responses": { "200": { "description": "Summary object", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/summarize": { "post": { "tags": ["ai"], "summary": "AI summary (x402 rail, 0.01 USDC — premium)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Summary object" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/coin-price": { "post": { "tags": ["crypto"], "summary": "Crypto spot prices in USD via CoinGecko", "security": [{ "BearerCredits": [] }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "symbols": { "type": "array", "items": { "type": "string" }, "default": ["BTC", "ETH", "USDC"], "maxItems": 25 } } } } } }, "responses": { "200": { "description": "Prices map", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/coin-price": { "post": { "tags": ["crypto"], "summary": "Coin prices (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Prices map" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/ens-resolve": { "post": { "tags": ["crypto"], "summary": "ENS name to address (or reverse) with avatar", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "example": "vitalik.eth" }, "address": { "type": "string", "example": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" } } } } } }, "responses": { "200": { "description": "Resolution result", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/ens-resolve": { "post": { "tags": ["crypto"], "summary": "ENS resolve (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Resolution result" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/wallet-balance": { "post": { "tags": ["crypto"], "summary": "Native + USDC balance across EVM chains", "security": [{ "BearerCredits": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["address"], "properties": { "address": { "type": "string" }, "chains": { "type": "array", "items": { "type": "string", "enum": ["ethereum", "base", "arbitrum", "optimism", "polygon"] }, "default": ["base", "ethereum"], "maxItems": 5 } } } } } }, "responses": { "200": { "description": "Balances map", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/wallet-balance": { "post": { "tags": ["crypto"], "summary": "Wallet balance (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Balances map" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1/gas-price": { "post": { "tags": ["crypto"], "summary": "Live gas price across EVM chains in gwei", "security": [{ "BearerCredits": [] }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "chains": { "type": "array", "items": { "type": "string", "enum": ["ethereum", "base", "arbitrum", "optimism", "polygon"] }, "default": ["base", "ethereum"], "maxItems": 5 } } } } } }, "responses": { "200": { "description": "Gas map", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402Bearer" } } } },
    "/api/x402/gas-price": { "post": { "tags": ["crypto"], "summary": "Gas price (x402 rail)", "security": [{ "X402Payment": [] }], "responses": { "200": { "content": { "application/json": {} }, "description": "Gas map" }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/buy-credits/small": { "post": { "tags": ["purchase"], "summary": "Buy 5 credits ($1 USDC, autonomous via x402)", "description": "Agent posts an empty body → 402 with x402 payment requirements ($1 USDC) → agent signs EIP-3009 transferWithAuthorization, retries with X-PAYMENT header → server settles on Base mainnet via Coinbase facilitator → returns a fresh ap_live_... API key with 5 credits.", "security": [{ "X402Payment": [] }], "responses": { "200": { "description": "API key with 5 credits", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "api_key": { "type": "string" }, "credits": { "type": "integer", "example": 5 }, "package": { "type": "string", "example": "small" }, "paid_usd": { "type": "number", "example": 1 }, "message": { "type": "string" } } } } } }, "402": { "$ref": "#/components/responses/Error402X402" } } } },
    "/api/buy-credits/medium": { "post": { "tags": ["purchase"], "summary": "Buy 30 credits ($5 USDC, autonomous via x402)", "security": [{ "X402Payment": [] }], "responses": { "200": { "description": "API key with 30 credits", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402X402" } } } },
    "/api/buy-credits/large": { "post": { "tags": ["purchase"], "summary": "Buy 150 credits ($20 USDC, autonomous via x402)", "security": [{ "X402Payment": [] }], "responses": { "200": { "description": "API key with 150 credits", "content": { "application/json": {} } }, "402": { "$ref": "#/components/responses/Error402X402" } } } },

    "/api/v1": { "get": { "summary": "Machine-readable manifest (full endpoint catalog + pricing + auth schemes + discovery + purchase URLs)", "security": [], "responses": { "200": { "description": "Manifest JSON", "content": { "application/json": {} } } } } },
    "/api/health": { "get": { "summary": "Health check (used by uptime monitor)", "security": [], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "ts": { "type": "string", "format": "date-time" } } } } } } } } },
    "/api/mcp": { "post": { "summary": "Hosted MCP (Model Context Protocol) server. JSON-RPC 2.0 over streamable HTTP. Methods: initialize, tools/list, tools/call, resources/list, prompts/list, ping. Use Authorization: Bearer ap_live_... or ?apiKey=ap_live_... query param.", "security": [{ "BearerCredits": [] }], "responses": { "200": { "description": "JSON-RPC response", "content": { "application/json": {} } } } } }
  }
}
