DuckDuckGo Search API: Is It Free, What Are the Limits, and What to Use Instead

DuckDuckGo has no official web search API. Why the duckduckgo-search (ddgs) library keeps throwing "202 Ratelimit", how to make it hold up, and the free-tier APIs to move an agent onto.

Short answer: DuckDuckGo doesn't offer a web search API. Its only official API, the Instant Answer API, returns topic summaries, not web results. What most people mean by "the DuckDuckGo search API" is the free, unofficial ddgs Python library (formerly duckduckgo-search), which reads DuckDuckGo's result pages the way a browser would. It needs no key. It also has no published limits and no SLA, and it fails with RatelimitException: 202 Ratelimit whenever DuckDuckGo decides you're a bot. Great for a weekend prototype; for an agent in production, move to an API with a real quota.

Option Official? Web results? Limits Cost
DuckDuckGo Instant Answer API Yes No, summaries and definitions only Not published Free
ddgs / duckduckgo-search library No Yes Not published; throttled on bursts Free
browserfoundry Yes Yes, ranked JSON Published per plan: 10 a minute free, up to 200 on paid plans 1,250 free credits a month, then from $30
Brave Search API Yes Yes Published per plan $5 of credit a month, then $5 per 1,000
Serper Yes Yes (Google results) Published 2,500 free queries once, then about $1 per 1,000

Does DuckDuckGo have an API?

It has one, and it's not the one you want. The Instant Answer API at api.duckduckgo.com returns DuckDuckGo's "zero-click" information: an abstract from a source like Wikipedia, a definition, a list of related topics. Ask it for "best python web framework" and you won't get ten blue links, because it was never a web results endpoint.

import requests

r = requests.get("https://api.duckduckgo.com/", params={"q": "python", "format": "json"}, timeout=10)
data = r.json()
print(data["AbstractText"])        # a summary, if DuckDuckGo has one
print(len(data["RelatedTopics"]))  # related topics, not web results

Try a query with no Wikipedia-style answer and you'll get an almost empty JSON object back. That's not a bug; that's the whole product.

DuckDuckGo doesn't sell access to its web results. There's no paid tier, no enterprise plan, no form to fill in.

The library everyone actually uses: ddgs

So the internet did what the internet does and wrote a scraper. To get DuckDuckGo results in code, almost everyone uses the open-source ddgs package:

# pip install ddgs
from ddgs import DDGS

with DDGS() as ddgs:
    for r in ddgs.text("open source llm benchmarks", max_results=10):
        print(r["title"], r["href"], r["body"])

Two things to know:

  • It was renamed. The project was duckduckgo-search until 2025, when it became ddgs. The old package stopped getting updates, so anything pinned to duckduckgo-search==x.y misses every fix for DuckDuckGo's changes since. If your traceback says from duckduckgo_search import DDGS, upgrade before debugging anything else.
  • It is unofficial. It requests DuckDuckGo's pages the way a browser would. DuckDuckGo can change those pages, or slow down traffic it thinks is automated, whenever it likes, and owes you nothing.

LangChain's DuckDuckGoSearchRun and DuckDuckGoSearchResults, and the "free web search" default in plenty of agent frameworks, are built on this library. They inherit every one of its limits.

What are the rate limits?

DuckDuckGo publishes none, so anyone who quotes you a "safe" number is guessing. What developers report in issue threads for Open WebUI, LangChain's OpenGPTs and others is consistent:

  • Bursts get throttled. A few queries in quick succession, or several agents searching at once, trigger the error.
  • Some IPs are throttled almost immediately. Shared cloud IPs and VPN exits can hit 202 Ratelimit on the very first request. Your laptop works; your server doesn't. Classic.
  • Waiting doesn't always clear it. People report the error persisting even with pauses of several seconds between queries.

Why RatelimitException: 202 Ratelimit happens

DuckDuckGo's results load in two steps. The first request returns a per-query token (vqd), and the request that fetches the actual results has to send it back. The library does that handshake for you, so each "search" is really more than one request. When DuckDuckGo decides the traffic looks automated, it answers with HTTP 202 and no results, and the library raises RatelimitException.

It's not a bug in your code, and no setting turns it off. It's DuckDuckGo politely asking you to go away.

Gotcha. In an agent, this error is often swallowed by the framework. The search returns nothing, the model shrugs and answers from memory, and nobody notices that your "web-grounded" agent hasn't touched the web in a week.

How to make ddgs hold up longer

If you're staying on DuckDuckGo for a prototype, these help:

  1. Upgrade to the current ddgs release.
  2. Reuse one DDGS() instance instead of creating a new one per query. Users in the Open WebUI thread found this throttled less.
  3. Search one at a time. Cap your agent at one search in flight.
  4. Back off and retry, with growing waits and some randomness:
import random, time
from ddgs import DDGS
from ddgs.exceptions import RatelimitException

ddgs = DDGS()

def search(query, tries=4):
    for attempt in range(tries):
        try:
            return list(ddgs.text(query, max_results=10))
        except RatelimitException:
            time.sleep(2 ** attempt + random.random())  # 1s, 2s, 4s, 8s, plus jitter
    return []
  1. Cache results. Agents repeat themselves far more than you'd expect. Even a tiny cache helps:
from functools import lru_cache

@lru_cache(maxsize=2048)
def cached_search(query):
    return tuple(search(query))
  1. Proxies spread requests over more IPs, at the price of paying for proxies, more failures and more moving parts. Once you're paying for proxies to scrape a free service, a paid API is almost always cheaper and certainly calmer.

How to tell your agent is silently failing

Add one line of logging and you'll know:

results = search(query)
if not results:
    log.warning("empty search", extra={"query": query})  # alert if this spikes

If empty results go from rare to common, you're being throttled. That's your sign.

When to stop using DuckDuckGo

The moment an agent, or anything a customer depends on, runs on it. Free is great until the cost is wrong answers nobody can trace. A search API gives you a published quota, a key, errors you can monitor, and results designed for software to read.

Situation Stay on ddgs?
Notebook, hackathon, personal script Sure
Internal tool, a few searches a day Probably, with retries and caching
Agent serving users No
Anything running in parallel No
Anything on a cloud server IP Expect pain

Moving an agent to a search API

Replacing ddgs with browserfoundry is a small change:

import os, requests

def search(query, n=10):
    r = requests.post(
        "https://api.keirolabs.cloud/api/v2/search/fast",
        headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
        json={"query": query, "maxResults": n},
        timeout=30,
    )
    r.raise_for_status()
    # same shape as ddgs results: title, href, body
    return [{"title": x["title"], "href": x["url"], "body": x["snippet"]} for x in r.json()["results"]]

The function keeps ddgs's field names (title, href, body), so the rest of your code doesn't change. If you use LangChain, wrap it in a @tool and swap it in where DuckDuckGoSearchRun was.

Real failures now raise real HTTP errors you can catch, retry and alert on, instead of an empty list.

Free tiers, compared

Provider Free allowance Card needed What it covers
browserfoundry 1,250 credits a month (1,250 fast searches) No search, plus extraction and browsers on paid plans
Brave Search API $5 of credit a month (about 1,000 searches) Yes search; attribution required for the credit
Serper 2,500 queries, one time No Google results
SerpApi 250 searches a month No Google and other engines

If you're choosing a search tool for an LLM agent, the other half of the decision is whether to use the model's own built-in search instead: see what web search costs inside the OpenAI, Claude, Gemini and Perplexity APIs. And if you came here from the Google side, Google's Custom Search API is shutting down too.

How we put this together

The library behaviour comes from the ddgs project, DuckDuckGo's own Instant Answer API, and the public issue threads linked above, where developers describe the rate-limit error and what helped. Free tiers and prices come from each provider's published pages in October 2026: Brave Search API, Serper, SerpApi, and browserfoundry's pricing and API docs. DuckDuckGo publishes no limits, so no number in this post is a DuckDuckGo limit.

FAQ

Does DuckDuckGo have a search API?

Not for web results. DuckDuckGo's only official API is the Instant Answer API at api.duckduckgo.com, which returns topic summaries and definitions, not a list of web results. Libraries such as ddgs read DuckDuckGo's result pages instead.

Is the DuckDuckGo search API free?

The ddgs library is free and needs no key, but it is unofficial: DuckDuckGo publishes no limits, offers no SLA, and throttles traffic it sees as automated, which is what the 202 Ratelimit error means.

Why do I get RatelimitException: 202 Ratelimit?

DuckDuckGo is throttling your requests. It happens with bursts of queries, many concurrent agents, shared cloud IPs and VPNs, and sometimes on a single request from a flagged IP.

What is the difference between duckduckgo-search and ddgs?

They are the same project. The package was renamed from duckduckgo-search to ddgs in 2025, and the old package stopped receiving updates, so code pinned to it misses fixes.

What should an agent use instead of DuckDuckGo?

A search API with a published quota. Free tiers include browserfoundry (1,250 credits a month, no card), Brave Search ($5 of credit a month, card required) and Serper (2,500 one-time queries).

Keep reading
Search APIs

Google Custom Search API Is Shutting Down: What to Use Instead

Search APIs

What Web Search Costs in the OpenAI, Claude, Gemini and Perplexity APIs

Extraction

URL to Markdown for LLMs: 7 Ways to Do It, Compared