Free DuckDuckGo Web, News, and Image Search with ddgs
Run free web, news, and image searches through DuckDuckGo using ddgs, with no API key required.
Requirements
- No API key is required, and the web search itself is free.
How to use
Prefer this path when web_search is unavailable or unsuitable, for example when FIRECRAWL_API_KEY is not set; it can also serve as a standalone search path when DuckDuckGo results are specifically desired.
Text search is best for general research, companies, and documentation.
News search is best for current events, breaking news, and latest updates.
Image search is best for visual references, product images, and diagrams.
Video search is best for tutorials, demos, and explainers.
Choose the method by use case: text() for general research and companies (title, href, body), news() for current events and updates (date, title, source, body, url), images() for visuals and diagrams (title, image, thumbnail, url), and videos() for tutorials and demos (title, content, duration, provider).
Then extract the best URL with web_extract or another content-retrieval tool.
DuckDuckGo may throttle after many rapid requests; add a short delay between searches if needed.
The search returns snippets, not full page content — use web_extract, browser tools, or curl for the full article or page.
DuckDuckGo may block requests from some cloud IPs; if searches return empty, try different keywords or wait a few seconds.
Return fields may vary between results or ddgs versions; use .get() for optional fields to avoid KeyError.
A successful ddgs install in the terminal does not automatically mean the Python runtime can import it.
If the CLI error appears, it is likely not installed in the shell environment — install ddgs or use built-in web/browser tools instead; if the Python import error appears, that runtime lacks the package, so do not use Python DDGS there until it is prepared; if search returns nothing, wait a few seconds, retry, or adjust the query; if the CLI works but the runtime import fails, the terminal and the runtime are different environments — keep using the CLI or separately prepare the Python runtime.
Verify whether the ddgs CLI is present in the shell environment.
Check what is actually available before choosing an approach.
# Check CLI availability
command -v ddgs >/dev/null && echo "DDGS_CLI=installed" || echo "DDGS_CLI=missing"
If the ddgs CLI is installed, prefer terminal plus ddgs.
If the ddgs CLI is missing, do not assume the runtime can import ddgs.
If the user wants DuckDuckGo specifically, install ddgs first in the relevant environment.
Otherwise fall back to built-in web/browser tools.
A successful shell install does not guarantee the runtime can import ddgs.
Never assume third-party Python packages are preinstalled inside the runtime.
After installing, verify the CLI works before relying on it.
Install ddgs only when DuckDuckGo search is specifically needed and the runtime does not already provide it.
# Python package + CLI entrypoint
pip install ddgs
# Verify CLI
ddgs --help
If a workflow depends on Python imports, verify that the same runtime can import ddgs before using from ddgs import DDGS.
CLI search covers text, news, image, and video queries, with optional region, time-limit, safe-search, and output-format flags; the query flag is required.
Use the ddgs command via terminal when it exists; this is the preferred path because it avoids assuming the runtime sandbox has the ddgs Python package installed.
# Text search
ddgs text -q "python async programming" -m 5
# News search
ddgs news -q "artificial intelligence" -m 5
# Image search
ddgs images -q "landscape photography" -m 10
# Video search
ddgs videos -q "python tutorial" -m 5
# With region filter
ddgs text -q "best restaurants" -m 5 -r us-en
# Recent results only (d=day, w=week, m=month, y=year)
ddgs text -q "latest AI news" -m 5 -t w
# JSON output for parsing
ddgs text -q "fastapi tutorial" -m 5 -o json
Use the DDGS class in the runtime or another Python runtime only after verifying that ddgs is installed there; do not assume the runtime includes third-party packages by default.
A phrasing such as "use the runtime with ddgs after installing or verifying the package if needed" is accurate.
Do not rely on the assumption that the runtime already includes ddgs.
Do not rely on the assumption that DuckDuckGo search works by default in the runtime.
Important: max_results must always be passed as a keyword argument — positional usage raises an error on all methods.
Text search is best for general research, companies, and documentation.
from ddgs import DDGS
with DDGS() as ddgs:
for r in ddgs.text("python async programming", max_results=5):
print(r["title"])
print(r["href"])
print(r.get("body", "")[:200])
print()
News search is best for current events, breaking news, and latest updates.
from ddgs import DDGS
with DDGS() as ddgs:
for r in ddgs.news("AI regulation 2026", max_results=5):
print(r["date"], "-", r["title"])
print(r.get("source", ""), "|", r["url"])
print(r.get("body", "")[:200])
print()
Image search is best for visual references, product images, and diagrams.
from ddgs import DDGS
with DDGS() as ddgs:
for r in ddgs.images("semiconductor chip", max_results=5):
print(r["title"])
print(r["image"])
print(r.get("thumbnail", ""))
print(r.get("source", ""))
print()
Video search is best for tutorials, demos, and explainers.
from ddgs import DDGS
with DDGS() as ddgs:
for r in ddgs.videos("FastAPI tutorial", max_results=5):
print(r["title"])
print(r.get("content", ""))
print(r.get("duration", ""))
print(r.get("provider", ""))
print(r.get("published", ""))
print()
This workflow is search followed by extraction.
DuckDuckGo returns titles, URLs, and snippets — not full page content. To get full page content, search first and then extract the most relevant URL with web_extract, browser tools, or curl.
ddgs text -q "fastapi deployment guide" -m 3 -o json
The Python example works only after verifying ddgs is installed in that runtime.
from ddgs import DDGS
with DDGS() as ddgs:
results = list(ddgs.text("fastapi deployment guide", max_results=3))
for r in results:
print(r["title"], "->", r["href"])
max_results is keyword-only: positional usage raises an error, so use ddgs.text("query", max_results=5).
Do not assume the CLI exists — check command -v ddgs before using it.
Do not assume the runtime can import ddgs: from ddgs import DDGS may fail with ModuleNotFoundError unless that runtime was prepared separately.
The package is ddgs (previously duckduckgo-search); install with pip install ddgs.
Do not confuse the query flag with the max-results flag: one sets the query, the other sets the result count.
If ddgs returns nothing, it may be rate-limited; wait a few seconds and retry.
Source: nousresearch/hermes-agent and its contributors. License: MIT.
Copyright (c) 2025 Nous Research
Translation and editorial adaptation by ClawCases.
>Resources
>Related Use Cases
Agent Merge-Conflict Arbiter
Resolve a git merge conflict between two agents' branches as an impartial third party: a neutral arbiter that takes both diffs and their stated intents and produces a merged result without overwriting either side.
Autonomous Project Management with Subagents
Coordinate projects autonomously: a main agent delegates work to PM subagents that track tasks in a shared STATE.yaml, update it as they progress, pick up unblocked work in parallel, and keep all task state in version-controlled files.
Set up native A2A agent collaboration in Hermes
When delegating work to an A2A-compliant peer, Hermes filters inbound peer text, blocks remote slash commands, redacts credential-shaped outbound strings, rate-limits callers, and records an audit trail at ~/.hermes/a2a_audit.jsonl.