rsearch

Overview

rsearch is a multi-source search aggregator. It queries multiple independent search providers in adaptive priority order and returns the first successful result set. Provider ordering is determined by a score combining success rate (70%) and response speed (30%).

Web Interface

The root endpoint / serves a backend-rendered HTML page. When no query is provided, a landing page with a search form is shown. When a query is submitted, results are displayed in a structured format with title, URL, description, and optional content preview.

GET Parameters

ParameterDefaultDescription
queryempty Search query string. When empty, the landing page is shown.
count10 Number of results to return (1-100).
contentfalse Set to true to fetch full page content for each result. Content is extracted using trafilatura/BeautifulSoup and displayed as a truncated preview with the full text available in hidden HTML for scrapers.
cachetrue Set to false to bypass all cache layers (page cache, search result cache, content cache). Forces fresh requests to search providers and content URLs.
aifalse Set to true to enable AI mode. The query text serves as a prompt for the AI assistant. See AI Mode section below.

Example URLs

DescriptionURL
Basic search https://rsearch.app.molodetz.nl/?query=python+programming
Search with content extraction https://rsearch.app.molodetz.nl/?query=python+programming&content=true&cache=true
Search with 5 results, no cache https://rsearch.app.molodetz.nl/?query=python+programming&count=5&cache=false
Full options: content + no cache https://rsearch.app.molodetz.nl/?query=what+is+a+cat&content=true&cache=false&count=20
JSON API: basic search https://rsearch.app.molodetz.nl/search?query=python+programming
JSON API: with content https://rsearch.app.molodetz.nl/search?query=python+programming&content=true&count=5
JSON API: AI mode https://rsearch.app.molodetz.nl/search?query=What+is+Python%3F&ai=true
JSON API: no cache https://rsearch.app.molodetz.nl/search?query=python&cache=false
AI mode https://rsearch.app.molodetz.nl/?query=What+is+the+capital+of+France%3F&ai=true
AI mode, no cache https://rsearch.app.molodetz.nl/?query=Explain+quantum+computing&ai=true&cache=false
Deep research https://rsearch.app.molodetz.nl/?query=quantum+computing+breakthroughs+2025&deep=true
Deep research (JSON) https://rsearch.app.molodetz.nl/search?query=python+asyncio+best+practices&deep=true
AI image description https://rsearch.app.molodetz.nl/?query=Describe+this+image:+https%3A%2F%2Fen.wikipedia.org%2Fstatic%2Fimages%2Fproject-logos%2Fenwiki.png&ai=true
AI with search + content https://rsearch.app.molodetz.nl/?query=What+are+the+tallest+buildings+in+the+world%3F&ai=true&content=true
Image search (HTML) https://rsearch.app.molodetz.nl/?query=red+panda&type=images
Image search (JSON) https://rsearch.app.molodetz.nl/search?query=red+panda&type=images&count=20
Health / provider stats https://rsearch.app.molodetz.nl/health
Describe image by URL https://rsearch.app.molodetz.nl/describe?url=https%3A%2F%2Fen.wikipedia.org%2Fstatic%2Fimages%2Fproject-logos%2Fenwiki.png
Chat: basic prompt https://rsearch.app.molodetz.nl/chat?prompt=What+is+the+capital+of+France%3F
Chat: JSON mode https://rsearch.app.molodetz.nl/chat?prompt=List+three+colors&json=true
Chat: no cache https://rsearch.app.molodetz.nl/chat?prompt=Hello+world&cache=false
About page https://rsearch.app.molodetz.nl/about

AI Mode

When ai=true, the system operates differently:

Example with curl:

curl "https://rsearch.app.molodetz.nl/?query=What+is+the+capital+of+France%3F&ai=true"

JSON API

GET /search returns JSON and supports all the same parameters as the web interface: query, count, content, cache, and ai. The behavior is identical. Response format:

{
  "query": "search terms",
  "source": "provider_name",
  "count": 10,
  "results": [
    {
      "title": "Result Title",
      "url": "https://example.com",
      "description": "Result description",
      "source": "provider_name",
      "extra": {},
      "content": "Full page content (when content=true)"
    }
  ],
  "ai_response": "AI answer (when ai=true, null otherwise)",
  "ai_error": null,
  "timestamp": "2026-01-01T00:00:00Z",
  "success": true,
  "error": null
}

When ai=true, the ai_response and ai_error fields are included. If the AI answered without searching, source is "ai" and results is empty. Cache bypass (cache=false) applies to search and content caches identically to the web interface.

Chat Endpoint

The /chat endpoint provides direct access to the configured AI model for chat completions without search integration. Responses are cached for 2 weeks by default. Supports both GET and POST methods. Outer markdown code fences are always stripped from responses automatically.

Configuration

PropertyValue
Max context window 131,072 - 1,048,576 tokens (varies by model)
Max output tokens Dynamic (derived from model context window minus prompt size)
Temperature0.0 (deterministic)
Cache TTL2 weeks

Parameters

ParameterDefaultDescription
promptrequired The text prompt to send to the AI model.
systembuilt-in default Custom system message to control the AI behavior and persona. When omitted, a default instruction is used. Becomes part of the cache key.
jsonfalse Set to true to enforce JSON output. The model is instructed to respond with valid JSON only and any markdown code fences are stripped.
cachetrue Set to false to bypass the chat cache and force a fresh AI call.

GET /chat

Pass parameters as query string values.

curl "https://rsearch.app.molodetz.nl/chat?prompt=What+is+the+capital+of+France%3F"
curl "https://rsearch.app.molodetz.nl/chat?prompt=List+three+programming+languages&json=true"
curl "https://rsearch.app.molodetz.nl/chat?prompt=Hello&cache=false"
curl "https://rsearch.app.molodetz.nl/chat?prompt=Translate+hello+to+French&system=You+are+a+translator"

POST /chat

Send parameters as form data or JSON body.

curl -X POST https://rsearch.app.molodetz.nl/chat -d "prompt=What is the capital of France?"
curl -X POST https://rsearch.app.molodetz.nl/chat -H "Content-Type: application/json" \
  -d '{"prompt": "List three colors", "json": true}'
curl -X POST https://rsearch.app.molodetz.nl/chat -H "Content-Type: application/json" \
  -d '{"prompt": "Summarize quantum computing", "system": "You are a physics professor. Explain concepts clearly."}'

Response Format

{
  "response": "The capital of France is Paris.",
  "prompt": "What is the capital of France?",
  "json_mode": false,
  "max_context_window": "(dynamic, based on model)",
  "max_output_tokens": "(dynamic, context minus prompt)",
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 12,
    "total_tokens": 54,
    "cost_usd": 0.0
  },
  "elapsed": 1.2345,
  "cached": false,
  "timestamp": "2026-01-01T00:00:00Z",
  "error": null
}

Outer markdown code fences are always stripped from responses. When json=true, the response field contains raw JSON (as a string) and the model is additionally instructed to produce valid JSON only. When served from cache, cached is true and token usage reflects the original call. The system parameter is part of the cache key, so different system messages produce separate cache entries.

Image Description Endpoint

The /describe endpoint accepts images for AI vision analysis. Three methods are supported:

GET /describe?url=...

Describe an image by URL. The image is fetched by the vision model directly.

curl "https://rsearch.app.molodetz.nl/describe?url=https://en.wikipedia.org/static/images/project-logos/enwiki.png"

POST /describe (multipart file upload)

Upload an image file. The file is read, MIME type is auto-detected from file headers (PNG, JPEG, GIF, WebP, BMP), converted to a base64 data URI, and sent to the vision model. Maximum size: 10 MB.

curl -X POST https://rsearch.app.molodetz.nl/describe -F "file=@photo.jpg"

POST /describe (raw body)

Send raw image bytes in the request body with the appropriate Content-Type header. If Content-Type is not an image type, MIME detection runs on the raw bytes.

curl -X POST https://rsearch.app.molodetz.nl/describe -H "Content-Type: image/png" --data-binary @photo.png

Response format (all methods):

{
  "description": "A detailed description of the image...",
  "mime_type": "image/png",
  "size": 12345,
  "elapsed": 2.1234,
  "timestamp": "2026-01-01T00:00:00Z"
}

Results are cached for 7 days by content hash (uploaded data) or URL. Auto-detected MIME types: PNG, JPEG, GIF, WebP, BMP.

Health Endpoint

GET /health returns JSON with service status, provider ordering by score, per-provider statistics (success rate, average response time), and cache entry counts.

Caching

All cache layers are filesystem-based under ~/.cache/rsearch/ and shared across all workers:

When cache=false, all layers are bypassed and fresh data is fetched. Results are still stored in cache for subsequent requests. To clear all caches: rm -rf ~/.cache/rsearch/

Scraper Information

HTML responses include structured metadata for automated consumption:

Response Headers

Every HTTP response includes debug headers with AI token usage and cache status:

HeaderDescriptionDefault
X-AI-Prompt-Tokens Input tokens sent to AI model0
X-AI-Completion-Tokens Output tokens from AI model0
X-AI-Total-Tokens Sum of prompt and completion tokens0
X-AI-Cost-USD Total dollar cost for AI calls in this request0.000000
X-Cache-Search Whether search results were served from cachefalse
X-Cache-Page Whether the full HTML page was served from cachefalse
X-Cache-Content Whether fetched page content was served from cachefalse
X-Cache-Vision Whether AI image descriptions were served from cachefalse
X-Cache-Chat Whether chat response was served from cachefalse

Token counts accumulate across all AI calls within a single request (chat rounds, tool calls, vision). Cache headers reflect whether any result of that type was served from cache during the request.

Error Handling

When all search providers fail, a 503 status page is returned with the message "All search providers are currently exhausted." This page is not cached. When content fetching fails for individual results, the HTTP method and status code are displayed (e.g., "Content unavailable (GET 403)").