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/suggestand/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.
GET /api/search
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-resultfires as each engine answers. Its payload carriesengine, that engine'stiming, the running mergedresultslist, and retry metadata. Becauseresultsis the full merged list each time, a lazy consumer can simply keep the last one. -
doneis the final event, withtotalTime,engineTimings, andrelatedSearches.
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
- In Degoog, enable Serve the SearXNG API shape in Settings, Server.
- In Open WebUI, open the Admin Panel, then Settings, then Web Search, and enable it.
- Set Web Search Engine to
searxng. -
Set the SearxNG Query URL to your instance followed by
/api/search, for examplehttp://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:
-
searchreturns model-readable results plus structured URLs, snippets, engine timings, and source overlap. -
scrapefetches URLs concurrently and returns clean Markdown, with explicit error rows for failures. It accepts onlyhttpandhttps, 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.