Skip to the page

OpenDeepSearch

Run OpenDeepSearch's searches on SpecStream's Search API by setting two environment variables. OpenDeepSearch's SearXNG provider stays as it is, so there is no SearXNG instance to host and no Serper account to keep.

SpecStream for OpenDeepSearchAgent frameworks & builders

What you need

  • OpenDeepSearch installed from its repository (pip install -e . and pip install -r requirements.txt), with a LiteLLM model and a reranker, Jina or Infinity, set up as its README describes.
  • A SpecStream key. Get your key on the Search API screen of your SpecStream workspace. New accounts start with $10 of credit, no card.
  1. 1. Set the two SearXNG variables

    Set SEARXNG_INSTANCE_URL to SpecStream's SearXNG address and SEARXNG_API_KEY to your key. Give the address without /search: OpenDeepSearch adds /search itself, and it sends the key in the X-API-Key header, where SpecStream reads it.

    Keep the key in your shell profile or a secrets manager, out of anything you commit.

    Shell
    export SEARXNG_INSTANCE_URL='https://api.specstream.ai/searxng'
    export SEARXNG_API_KEY='YOUR_SPECSTREAM_KEY'
  2. 2. Choose the searxng provider

    OpenDeepSearchTool searches with Serper unless you name another provider. Pass search_provider="searxng" and leave searxng_instance_url out, so the tool reads the two variables when setup() runs:

    Python
    from opendeepsearch import OpenDeepSearchTool
    search_agent = OpenDeepSearchTool(
    model_name="openrouter/google/gemini-2.0-flash-001",
    reranker="jina",
    search_provider="searxng",
    )
    if not search_agent.is_initialized:
    search_agent.setup()
    print(search_agent.forward("What changed in the latest PostgreSQL release?"))
  3. 3. Or start the Gradio demo

    The demo takes the provider as a flag. With the two variables set, --search-provider searxng is enough: the demo falls back to SEARXNG_INSTANCE_URL when --searxng-instance is not given.

    Shell
    python gradio_demo.py --model-name "openrouter/google/gemini-2.0-flash-001" \
    --reranker "jina" --search-provider "searxng"

What changes and what stays

OpenDeepSearch's search client, SearXNGAPI in src/opendeepsearch/serp_search/serp_search.py, is unchanged. It sends GET to the address plus /search with q, format=json and pageno=1, and SpecStream answers in SearXNG's own JSON shape: results[] with title, url and content. OpenDeepSearch turns those into its organic results, with link and snippet, the same shape its Serper client returns.

The rest of the pipeline stays where it is: Crawl4AI reads the pages on your machine, your reranker orders the passages, and your LiteLLM model writes the answer. publishedDate is empty on most results, so the date OpenDeepSearch keeps on a result is usually blank.

Use it in a smolagents agent

The same tool goes into a CodeAgent or ToolCallingAgent as OpenDeepSearch's README shows. Create it with search_provider="searxng", call setup(), and add it to the agent's tools. Every time the agent calls the tool, OpenDeepSearch runs one search through SpecStream.

Why not Serper or a public SearXNG instance

OpenDeepSearch's README offers two ways to search: a Serper key, with 2,500 free credits on sign-up, or a SearXNG instance you host or find. The SpecStream address is a SearXNG address that needs no server of yours and keeps working after the free credits run out.

SpecStream's Search API scores 97.9 F-score on all 1,000 SimpleQA Verified questions and 64.0 item F1 on all 200 WideSearch tasks. Scores and method are on the benchmarks page.

What each search costs

Each OpenDeepSearch search is one GET, so one Search API call on the fast tier: $1 per 1,000 searches of up to 10 results, a fifth of the default search's $5. OpenDeepSearch also sends max_results and an engines list. SpecStream reads neither: each call returns one SearXNG page of up to 10 results, at the base price, from SpecStream's own search.

A search that returns no results costs nothing. Calls come out of your balance with no quote and no approval, and every call, charged or not, is in your account's request log.

Limits and errors

  • When the account has used its calls for the minute, SpecStream answers 429 with Retry-After, and nothing is charged. OpenDeepSearch does not retry: its SearXNG client turns the reply into an error that starts with SearXNG API request failed.
  • A 401 in that error means the key is missing or wrong. Check SEARXNG_API_KEY, or pass searxng_api_key to OpenDeepSearchTool.
  • SEARXNG_INSTANCE_URL environment variable not set means the variable is not in the environment Python starts with.

Go back

Point SEARXNG_INSTANCE_URL at your own SearXNG instance, or drop search_provider to return to Serper. Questions: [email protected].

More

SpecStream for OpenDeepSearch covers what it does in OpenDeepSearch on one page. Every other tool has its guide in Connect your tools. You see the most a request can cost before it starts, and the matches are paid from your balance. Billing has the details. For help, email [email protected].