{
  "openapi": "3.1.0",
  "info": {
    "title": "NoJunk Web Search",
    "version": "1.0.0",
    "description": "Cheap web search for AI agents: give it a query, get up to 10 live web results back as JSON (rank, title, url, domain, snippet). Optional region (e.g. us-en) and safe-search level. Sources tried in order: DuckDuckGo, Bing, Yahoo. Results link to the live web; pair with a /read service to fetch the pages.",
    "x-guidance": "Cheap web search for AI agents. GET /search?q=your+query (or POST /search with JSON body {\"q\": \"...\", \"count\": 10, \"region\": \"us-en\", \"safe\": \"moderate\"}) returns up to 10 live web results as JSON: for each result its rank, title, url, domain and snippet. Costs $0.002 USDC on Base per request via x402; you are only charged when at least one result is returned (no charge on 400/404/502). Results link to the live web: use a /read service (such as NoJunk Web Read) to fetch and read the pages you pick. Optional region (DuckDuckGo code like us-en, uk-en, de-de) biases results by country/language; safe is moderate by default and can be off or strict. Results come from DuckDuckGo's HTML interface, falling back to Bing and then Yahoo when a source is blocked or empty (the source field says which one answered); upstream pages are cached for 2 minutes per identical query. region/safe apply to DuckDuckGo; fallbacks use English/US defaults. Best for: finding sources, looking up current facts, discovering URLs to read, checking what exists on a topic before answering."
  },
  "servers": [
    {
      "url": "https://nojunk-web-search.mick8511.workers.dev"
    }
  ],
  "paths": {
    "/search": {
      "get": {
        "operationId": "webSearch",
        "summary": "Search the web: up to 10 live results with title, url, domain and snippet as JSON",
        "tags": [
          "Web",
          "Search",
          "Research",
          "Agents"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The search query, 1-400 characters, e.g. 'cloudflare workers pricing'. Plain keywords work best; quotes and site:example.com operators are passed through."
          },
          {
            "name": "count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Maximum number of results to return (1-10, default 10)"
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional DuckDuckGo region code to bias results, e.g. us-en, uk-en, ca-en, de-de, fr-fr, jp-jp, wt-wt (worldwide). Default: none."
          },
          {
            "name": "safe",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Safe-search level: moderate (default), off, or strict"
          }
        ],
        "responses": {
          "200": {
            "description": "Search results (at least one)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "description": "The query that was searched (whitespace normalized)"
                    },
                    "region": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Region code requested, or null (applied by the DuckDuckGo source; fallbacks use en/us defaults)"
                    },
                    "safe": {
                      "type": "string",
                      "enum": [
                        "moderate",
                        "off",
                        "strict"
                      ]
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of results returned (1-10)"
                    },
                    "results": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 10,
                      "items": {
                        "type": "object",
                        "properties": {
                          "rank": {
                            "type": "integer",
                            "description": "1-based position in the result list"
                          },
                          "title": {
                            "type": "string",
                            "description": "Result title, HTML entities decoded"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri",
                            "description": "Absolute http(s) URL of the result page (redirector links resolved to the real destination)"
                          },
                          "domain": {
                            "type": "string",
                            "description": "Hostname of the result without a leading www."
                          },
                          "snippet": {
                            "type": "string",
                            "description": "Short text excerpt from the page as shown by the search engine (may be empty)"
                          }
                        },
                        "required": [
                          "rank",
                          "title",
                          "url",
                          "domain",
                          "snippet"
                        ]
                      }
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "DuckDuckGo",
                        "Bing",
                        "Yahoo"
                      ],
                      "description": "Search engine that served this result set (sources are tried in order until one returns results)"
                    },
                    "fetched_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "query",
                    "region",
                    "safe",
                    "count",
                    "results",
                    "source",
                    "fetched_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid q, count, region or safe (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "404": {
            "description": "The search returned no results (no charge)"
          },
          "413": {
            "description": "Request body too large (no charge)"
          },
          "502": {
            "description": "Every search source failed: unreachable, timed out (8 s each), error status, or bot-challenge page (no charge)"
          }
        }
      },
      "post": {
        "operationId": "webSearchPost",
        "summary": "Search the web: up to 10 live results with title, url, domain and snippet as JSON",
        "tags": [
          "Web",
          "Search",
          "Research",
          "Agents"
        ],
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.002000"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "q": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 400,
                    "description": "The search query, 1-400 characters, e.g. 'cloudflare workers pricing'. Plain keywords work best; quotes and site:example.com operators are passed through."
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 10,
                    "description": "Maximum number of results to return (1-10, default 10)"
                  },
                  "region": {
                    "type": "string",
                    "pattern": "^[a-z]{2,3}-[a-z]{2,3}$",
                    "description": "Optional DuckDuckGo region code to bias results, e.g. us-en, uk-en, ca-en, de-de, fr-fr, jp-jp, wt-wt (worldwide). Default: none."
                  },
                  "safe": {
                    "type": "string",
                    "enum": [
                      "moderate",
                      "off",
                      "strict"
                    ],
                    "default": "moderate",
                    "description": "Safe-search level: moderate (default), off, or strict"
                  }
                },
                "required": [
                  "q"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results (at least one)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "string",
                      "description": "The query that was searched (whitespace normalized)"
                    },
                    "region": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Region code requested, or null (applied by the DuckDuckGo source; fallbacks use en/us defaults)"
                    },
                    "safe": {
                      "type": "string",
                      "enum": [
                        "moderate",
                        "off",
                        "strict"
                      ]
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of results returned (1-10)"
                    },
                    "results": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 10,
                      "items": {
                        "type": "object",
                        "properties": {
                          "rank": {
                            "type": "integer",
                            "description": "1-based position in the result list"
                          },
                          "title": {
                            "type": "string",
                            "description": "Result title, HTML entities decoded"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri",
                            "description": "Absolute http(s) URL of the result page (redirector links resolved to the real destination)"
                          },
                          "domain": {
                            "type": "string",
                            "description": "Hostname of the result without a leading www."
                          },
                          "snippet": {
                            "type": "string",
                            "description": "Short text excerpt from the page as shown by the search engine (may be empty)"
                          }
                        },
                        "required": [
                          "rank",
                          "title",
                          "url",
                          "domain",
                          "snippet"
                        ]
                      }
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "DuckDuckGo",
                        "Bing",
                        "Yahoo"
                      ],
                      "description": "Search engine that served this result set (sources are tried in order until one returns results)"
                    },
                    "fetched_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "query",
                    "region",
                    "safe",
                    "count",
                    "results",
                    "source",
                    "fetched_at"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid q, count, region or safe (no charge)"
          },
          "402": {
            "description": "Payment Required"
          },
          "404": {
            "description": "The search returned no results (no charge)"
          },
          "413": {
            "description": "Request body too large (no charge)"
          },
          "502": {
            "description": "Every search source failed: unreachable, timed out (8 s each), error status, or bot-challenge page (no charge)"
          }
        }
      }
    }
  }
}