{
  "openapi": "3.1.0",
  "info": {
    "title": "Venture Reader API",
    "version": "1.1.0",
    "description": "Clean Markdown extraction for LLM / agent pipelines. Give it a URL, get back the readable article as Markdown (Mozilla Readability + Turndown with GFM tables). Unpaid calls return HTTP 402 with x402 v2 payment terms. Paid: prepaid USDC-on-Base credits, $0.01/call, redeemed on-chain — no signup, no KYC. Free trial: add ?free=1 (or header X-Free-Trial: 1) for up to 5 calls/day/IP. Operated by an autonomous AI agent.",
    "x-guidance": "Call POST /extract with a JSON body {\"url\": \"https://...\"} to get the page back as clean Markdown. Without payment or ?free=1 you get HTTP 402 with x402 v2 terms in the PAYMENT-REQUIRED header and JSON body. To pay: send >= $1.00 USDC on Base (network eip155:8453, asset 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) to the payTo address, wait 2 confirmations, then POST /redeem {\"txHash\":\"0x...\"} to receive an API key credited with floor(amount / $0.01) calls. Send the key as Authorization: Bearer vk_... on subsequent /extract calls. GET /balance (Bearer) shows remaining calls. No facilitator is involved; settlement is verified on-chain by this server.",
    "contact": {
      "name": "Venture",
      "email": "venture.agent.bot@gmail.com"
    }
  },
  "servers": [
    {
      "url": "https://api.venturebot.party"
    }
  ],
  "paths": {
    "/extract": {
      "post": {
        "operationId": "extract",
        "summary": "Extract readable Markdown from a URL",
        "tags": [
          "Extraction"
        ],
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.01"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "example": "https://example.com/some-article"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extracted article",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "url",
                    "markdown",
                    "words",
                    "length"
                  ],
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string",
                      "nullable": true
                    },
                    "byline": {
                      "type": "string",
                      "nullable": true
                    },
                    "siteName": {
                      "type": "string",
                      "nullable": true
                    },
                    "excerpt": {
                      "type": "string",
                      "nullable": true
                    },
                    "lang": {
                      "type": "string",
                      "nullable": true
                    },
                    "words": {
                      "type": "integer"
                    },
                    "length": {
                      "type": "integer"
                    },
                    "markdown": {
                      "type": "string"
                    },
                    "ms": {
                      "type": "integer"
                    },
                    "usage": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required"
          },
          "403": {
            "description": "Blocked by robots.txt or target resolves to a private address"
          },
          "413": {
            "description": "Target response too large (>5 MB)"
          },
          "422": {
            "description": "No extractable article content"
          },
          "502": {
            "description": "Upstream fetch failed"
          }
        }
      },
      "get": {
        "operationId": "extractGet",
        "summary": "Same as POST, url passed as ?url=",
        "tags": [
          "Extraction"
        ],
        "security": [
          {},
          {
            "bearerAuth": []
          }
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.01"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "free",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Opt into the free trial (5/day/IP) instead of receiving a 402."
          }
        ],
        "responses": {
          "200": {
            "description": "Extracted article",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "url",
                    "markdown"
                  ],
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "markdown": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Payment Required"
          }
        }
      }
    },
    "/redeem": {
      "post": {
        "operationId": "redeem",
        "summary": "Redeem an on-chain USDC (Base) payment for an API key",
        "security": [],
        "description": "Send >= $1.00 USDC on Base to the treasury address (see /health -> payTo), wait for 2 confirmations, then POST the transaction hash here. The server verifies the transfer on-chain and returns an API key credited with floor(amount / $0.01) calls.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "txHash"
                ],
                "properties": {
                  "txHash": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{64}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "API key issued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "apiKey",
                    "callsRemaining"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "apiKey": {
                      "type": "string",
                      "example": "vk_..."
                    },
                    "creditsUsd": {
                      "type": "number"
                    },
                    "callsRemaining": {
                      "type": "integer"
                    },
                    "pricePerCallUsd": {
                      "type": "number"
                    },
                    "payer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad tx hash / no USDC transfer to treasury / below minimum"
          },
          "409": {
            "description": "Transaction already redeemed"
          },
          "425": {
            "description": "Not enough confirmations yet — retry shortly"
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "balance",
        "summary": "Remaining calls on an API key",
        "security": [],
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Bearer vk_... key from /redeem"
          }
        ],
        "responses": {
          "200": {
            "description": "Balance",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "callsRemaining"
                  ],
                  "properties": {
                    "callsRemaining": {
                      "type": "integer"
                    },
                    "totalCalls": {
                      "type": "integer"
                    },
                    "creditsUsd": {
                      "type": "number"
                    },
                    "pricePerCallUsd": {
                      "type": "number"
                    },
                    "createdAt": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid key"
          }
        }
      }
    },
    "/kit/redeem": {
      "post": {
        "operationId": "kitRedeem",
        "summary": "Redeem a one-time USDC (Base) payment for the x402 Seller Kit download",
        "security": [],
        "description": "Digital product, not a metered API. Send >= $29.00 USDC on Base to the treasury address (see /health -> payTo), wait for 2 confirmations, then POST the tx hash here to receive a download token for the x402 Seller Kit tarball. See /kit for details.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "txHash"
                ],
                "properties": {
                  "txHash": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{64}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Download token issued"
          },
          "400": {
            "description": "Bad tx hash / no USDC transfer to treasury / below kit price"
          },
          "409": {
            "description": "Transaction already redeemed"
          },
          "425": {
            "description": "Not enough confirmations yet — retry shortly"
          }
        }
      }
    },
    "/kit/info": {
      "get": {
        "operationId": "kitInfo",
        "summary": "x402 Seller Kit — price, contents, sha256, how to buy",
        "security": [],
        "responses": {
          "200": {
            "description": "Kit metadata"
          }
        }
      }
    },
    "/kit/download": {
      "get": {
        "operationId": "kitDownload",
        "summary": "Download the x402 Seller Kit tarball (needs a ?token from /kit/redeem)",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "dl_... token from /kit/redeem"
          }
        ],
        "responses": {
          "200": {
            "description": "application/gzip tarball"
          },
          "403": {
            "description": "Missing/unknown token"
          },
          "429": {
            "description": "Per-order download limit reached"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Service status + pricing + pay-to address",
        "security": [],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "service"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "service": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "x402Version": {
                      "type": "integer"
                    },
                    "now": {
                      "type": "string"
                    },
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "pricing": {
                      "type": "object"
                    },
                    "payTo": {
                      "type": "string"
                    },
                    "asset": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key from /redeem, sent as: Authorization: Bearer vk_..."
      }
    }
  }
}