Degoog Docs

Degoog API reference

The endpoints worth calling from outside the browser, and how to authenticate against them.

Basics

Everything lives on the same host and port as the UI, http://localhost:4444 by default. Responses are JSON unless noted. Most of Degoog's HTTP surface is internal plumbing for the web UI; what follows is the part that is genuinely useful to call yourself.

The rate limits you set in Server settings apply to API callers exactly as they do to browsers.

Authentication

By default the search and suggestion endpoints are open. In Settings, Server, API Key you can require authentication on either group independently:

  • Protect search routes covers /api/search, /api/search/stream, and /api/search/retry.
  • Protect suggestion routes covers /api/suggest and /api/suggest/opensearch.

When protection is on, an unauthenticated request gets 401 with:

{ "error": "You shall not pass!" }

External callers authenticate with the instance's API key as a bearer token. Reveal or regenerate it in the same settings section. That section only appears once DEGOOG_SETTINGS_PASSWORDS is set, since otherwise nothing would be protecting the key itself.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "http://localhost:4444/api/search?q=hello"

The web UI does not use that header. It receives a short-lived signed nonce with the page and sends it as x-search-nonce and x-search-sig headers (or searchNonce and searchSig query parameters). Either mechanism satisfies the guard, so turning protection on does not break normal browsing.

Runs a search and returns merged, scored, deduplicated results.

Parameter Description
q Required. The query.
type Search type. Defaults to web. Valid values depend entirely on which engines you have installed. GET /api/search-tabs lists the ones your instance can serve.
page Starts at 1, capped at 10.
time any, hour, day, week, month, year, or custom. With custom, pass dateFrom and dateTo as YYYY-MM-DD.
lang Language code. Overrides DEGOOG_DEFAULT_SEARCH_LANGUAGE for this request.
imgSize, imgColor, imgType, imgLayout Image filters. Ignored unless the engines you are querying support them.
safeMode Safe search level. imgNsfw is accepted as a legacy alias.
Engine ids Pass any engine id as a parameter set to true or false to override which engines run. Omit them all to use the instance defaults. Ids come from GET /api/extensions?type=engine.
curl "http://localhost:4444/api/search?q=rust+lifetimes"

Response:

{
  "results": [
    {
      "title": "...",
      "url": "https://...",
      "snippet": "...",
      "content": "...",
      "source": "Brave",
      "score": 92,
      "sources": ["Brave", "DuckDuckGo"]
    }
  ],
  "query": "rust lifetimes",
  "type": "web",
  "totalTime": 812,
  "engineTimings": [{ "name": "Brave", "time": 540, "resultCount": 10 }],
  "relatedSearches": ["rust lifetime elision"]
}

content mirrors snippet. It exists so that Open WebUI, which expects that field name, works without a custom tool.

SearXNG-shaped responses

Turn on Serve the SearXNG API shape in Settings, Server and /api/search starts honouring a format=json parameter, answering those requests with a SearXNG-shaped document. Requests without the parameter are completely unchanged.

This is what makes clients such as Open WebUI and local-deep-research work with no glue code: they already send format=json.

The toggle is off by default. If a SearXNG-compatible client is getting the wrong response shape from Degoog, this is the switch you are missing.

POST /api/search

Same behaviour with a JSON body, which is easier when you want to restrict a long list of engines. Form-encoded bodies are also accepted.

curl -X POST http://localhost:4444/api/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "rust lifetimes",
    "type": "web",
    "page": 1,
    "lang": "en",
    "engines": ["degoog-org-official-extensions-brave-engine"]
  }'

engines is a list of engine ids to enable; anything not listed is disabled for that request. Omit it entirely to use the instance defaults.

GET /api/search/stream

The server-sent events variant. Same query parameters as GET /api/search. It emits two event types:

  • engine-result fires as each engine answers. Its payload carries engine, that engine's timing, the running merged results list, and retry metadata. Because results is the full merged list each time, a lazy consumer can simply keep the last one.
  • done is the final event, with totalTime, engineTimings, and relatedSearches.
curl -N "http://localhost:4444/api/search/stream?q=hello"

GET and POST /api/search/retry

Re-runs a single engine for a query that already ran. Requires q and engine (or query and engine in a JSON body), and accepts the same type, page, time, and language parameters. This is what the retry links in the results sidebar call.

GET /api/suggest

Autocomplete suggestions merged from every enabled provider. Returns an array of objects, not plain strings:

[
  { "text": "rust lifetimes", "source": "Google Autocomplete" },
  { "text": "rust lifetime elision", "source": "Google Autocomplete" }
]

A rich object is included when the provider supplies an entity card and rich suggestions are enabled for it. POST /api/suggest takes { "query": "..." } and behaves identically.

Returns an empty array when no autocomplete provider is installed, which is the default state.

GET /api/suggest/opensearch

The same suggestions in the OpenSearch format browsers expect, served as application/x-suggestions+json:

["rust", ["rust lifetimes", "rust lifetime elision"]]

GET /api/lucky

Runs a web search for q and redirects straight to the first result. Returns 404 with a JSON error if nothing was found.

GET /api/extensions

Lists what is installed, grouped into engines, plugins, themes, transports, autocomplete, and shortcuts. Each entry includes the id you would use to restrict a search.

Add ?type= to fetch one group: engine, plugin, theme, transport, autocomplete, or shortcut. An unknown type returns 400.

curl "http://localhost:4444/api/extensions?type=engine"

Extension settings are redacted from the response unless the caller is authenticated to the settings area, so you will see the extensions but not their configured API keys.

Other useful endpoints

Endpoint What it returns
GET /api/search-tabs The result tabs this instance can serve, which is the authoritative list of valid type values.
GET /api/tab-search?tab=&q=&page= Results for one specific tab.
GET /api/engines The engine list in the shape the UI uses.
GET /api/commands Every available bang command with its triggers, aliases, natural language phrases, and category.
GET /api/command?q=!uuid Executes a bang command and returns its rendered output.
GET /opensearch.xml The OpenSearch descriptor browsers use to add Degoog as a search engine.
GET /health, /healthz, /ready, /readyz Liveness and readiness checks. All four exist for the lolz.

Wiring Degoog into Open WebUI

  1. In Degoog, enable Serve the SearXNG API shape in Settings, Server.
  2. In Open WebUI, open the Admin Panel, then Settings, then Web Search, and enable it.
  3. Set Web Search Engine to searxng.
  4. Set the SearxNG Query URL to your instance followed by /api/search, for example http://127.0.0.1:4444/api/search.

No custom tool required. If you enabled API key protection for search routes, your client needs to send the Authorization: Bearer header, so check it supports custom headers before turning that on.

Model Context Protocol

degoog-mcp is a small Go sidecar that exposes Degoog to MCP-capable clients over Streamable HTTP at /mcp, listening on port 4443 by default. It offers two tools:

  • search returns model-readable results plus structured URLs, snippets, engine timings, and source overlap.
  • scrape fetches URLs concurrently and returns clean Markdown, with explicit error rows for failures. It accepts only http and https, resolves DNS before dialing, and blocks private and local IP ranges, rechecking on redirects.

It is configured entirely through DEGOOG_MCP_* environment variables, including an optional inbound bearer token, per-call result caps, and an engine allowlist. The mcp.yml compose example runs it alongside Degoog. Full details are in the degoog-mcp README.

degoog-mcp is still in beta and not intended for production use yet.