{
  "openapi": "3.1.0",
  "info": {
    "title": "SimNoKYC Agent API",
    "version": "1.0.0",
    "description": "Public REST API for AI agents to discover, purchase and manage anonymous virtual phone numbers for SMS verification. Crypto-only, no KYC, no email. Bearer auth (seed). Companion MCP server at https://simnokyc.com/mcp. x402-light supported on /topup via header X-Payment-Mode: x402.\n\nFlow: 1) POST /account → creates user + $75 signup topup invoice. 2) Pay the crypto address. 3) Poll /topup/{id} until completed. 4) POST /numbers to buy a number. 5) Poll /numbers/{id} until sms_code populated.",
    "contact": {"email": "support@simnokyc.com", "url": "https://simnokyc.com/agents"}
  },
  "servers": [{"url": "https://simnokyc.com"}],
  "components": {
    "securitySchemes": {
      "BearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "AAAA-BBBB-CCCC-DDDD"}
    },
    "schemas": {
      "Error": {"type":"object","required":["ok","error","message"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"string"},"message":{"type":"string"}}}
    }
  },
  "paths": {
    "/api/v1/": {"get": {"summary": "API root — recipe + capabilities", "responses": {"200": {"description": "OK"}}}},
    "/api/v1/catalog": {"get": {"summary": "Top (service × country) combinations with prices and stock", "responses": {"200": {"description": "Catalog"}}}},
    "/api/v1/services": {"get": {"summary": "All active services (Google, Telegram, …)", "responses": {"200": {"description": "Services"}}}},
    "/api/v1/countries": {"get": {"summary": "All active countries with available_services count", "responses": {"200": {"description": "Countries"}}}},
    "/api/v1/quote": {
      "post": {
        "summary": "Compute final price for service + country (+ optional operator multiplier)",
        "requestBody": {"required": true, "content": {"application/json": {"example": {"service_id": 1, "country": "US", "operator_id": 0}}}},
        "responses": {"200": {"description": "Quote"}}
      }
    },
    "/api/v1/account": {
      "post": {
        "summary": "Create account AND issue mandatory $75 signup topup invoice",
        "description": "Returns the seed (store it — only credential) and a payment.address. Once the topup completes the user has $75 balance.",
        "requestBody": {"required": true, "content": {"application/json": {"example": {"crypto": "BTC"}}}},
        "responses": {
          "201": {"description": "Account created + topup invoice", "content": {"application/json": {"example": {"ok": true, "account_seed": "AaBb-CcDd-EeFf-GgHh", "topup": {"topup_id": 12345, "amount_usd": 75, "address": "bc1q…", "amount_crypto": "0.00012", "expires_in": 3600}, "status_url": "https://simnokyc.com/api/v1/topup/12345"}}}}
        }
      },
      "get": {
        "summary": "Account info, balance, recent topups + numbers",
        "security": [{"BearerAuth": []}],
        "responses": {"200": {"description": "Account"}}
      }
    },
    "/api/v1/topup": {
      "post": {
        "summary": "Top up an existing account (Bearer required)",
        "description": "Send `X-Payment-Mode: x402` to receive an x402-light 402 with USDC deposit instructions in one round trip.",
        "security": [{"BearerAuth": []}],
        "requestBody": {"required": true, "content": {"application/json": {"example": {"amount_usd": 25, "crypto": "XMR"}}}},
        "responses": {
          "201": {"description": "Topup invoice issued"},
          "402": {"description": "Payment required (x402-light)", "headers": {"X-Payment-Required": {"schema": {"type": "string"}}}}
        }
      }
    },
    "/api/v1/topup/{id}": {
      "get": {
        "summary": "Topup status — poll until status=completed",
        "security": [{"BearerAuth": []}],
        "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}],
        "responses": {"200": {"description": "Topup status"}}
      }
    },
    "/api/v1/numbers": {
      "post": {
        "summary": "Buy a number (debits balance)",
        "security": [{"BearerAuth": []}],
        "requestBody": {"required": true, "content": {"application/json": {"example": {"service_id": 1, "country": "US", "operator_id": 0}}}},
        "responses": {
          "201": {"description": "Number issued — poll for SMS"},
          "402": {"description": "Insufficient balance", "content": {"application/json": {"example": {"error": "insufficient_balance", "need_usd": 0.50, "have_usd": 0.10}}}},
          "409": {"description": "Out of stock"}
        }
      },
      "get": {
        "summary": "List your recent numbers (50 most recent)",
        "security": [{"BearerAuth": []}],
        "responses": {"200": {"description": "Numbers"}}
      }
    },
    "/api/v1/numbers/{id}": {
      "get": {
        "summary": "Poll a number for the SMS code",
        "security": [{"BearerAuth": []}],
        "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}],
        "responses": {"200": {"description": "Number status"}}
      }
    },
    "/api/v1/numbers/{id}/cancel": {
      "post": {
        "summary": "Cancel + refund (only if no SMS received yet)",
        "security": [{"BearerAuth": []}],
        "parameters": [{"name": "id", "in": "path", "required": true, "schema": {"type": "integer"}}],
        "responses": {"200": {"description": "Refunded"}, "409": {"description": "SMS already received"}}
      }
    }
  },
  "x-mcp-server": "https://simnokyc.com/mcp",
  "x-discovery": "https://simnokyc.com/.well-known/agent.json",
  "x-dry-run": {
    "trigger": "Header X-Dry-Run: 1 OR ?dry_run=1 OR body.dry_run=true",
    "behavior": "Synthetic flow. Topup auto-completes in 60s, number returns SMS '123456' after 30s. No FF call, no DB writes."
  }
}
