Skip to content

AI Assistant API

The AI API manages provider settings and service diagnostics. Authentication follows the same DUMB API authentication behavior as the rest of the backend.

The backend makes provider requests from inside the DUMB container. Use provider URLs that are reachable from that container, not just from your browser.

GET /ai/settings

Returns the active AI settings without exposing the stored API key.

Response includes api_key_configured: true when the active key is stored. It also includes active_profile_id and a profiles array. Each public profile contains provider metadata and api_key_configured, but never the stored api_key.

PUT /ai/settings

Updates the dumb.ai settings block. Omit api_key to keep the existing stored key.

When active_profile_id identifies a saved profile, that profile is authoritative when settings are loaded, and changes to provider, base URL, model, API key, timeout, or temperature are synchronized back into it when settings are saved. Send active_profile_id as an empty string to save the top-level provider fields as an unsaved provider without modifying any saved profile.

Example payload:

{
  "enabled": true,
  "provider": "ollama",
  "base_url": "http://127.0.0.1:11434",
  "model": "llama3.1",
  "max_log_chars": 20000,
  "include_logs": true,
  "include_service_config": true,
  "include_dependency_graph": true
}

Settings fields:

Field Description
enabled Allows non-dry-run provider calls. Dry-run previews work even when this is false.
provider ollama, gemini (or google_gemini), open_webui, openai, openai_compatible, compatible, litellm, anthropic, or claude.
base_url Provider endpoint reachable from the DUMB backend container. For native Gemini, OpenAI, and Anthropic, DUMB ignores custom values and uses the corresponding official endpoint.
model Provider model name.
api_key Optional for local providers; required for Gemini and hosted OpenAI/Anthropic modes. Omit to preserve a stored key.
timeout_sec Provider request timeout, clamped by the backend.
temperature Provider temperature setting where supported. Native Gemini, OpenAI Responses, and Anthropic adapters leave sampling at the model default for compatibility with current models.
max_log_chars Default maximum recent log characters included in diagnostic bundles.
include_logs Default for including redacted service logs.
include_service_config Default for including redacted service config.
include_dependency_graph Default for including dependency graph context.
include_docs_context Default for including selected DUMB_docs snippets in diagnostic bundles.
include_process_list Default for including compact stack status context.
max_docs_chars Maximum documentation characters included across selected docs snippets.
diagnostic_window_hours Default analysis window from 0.25 through 720 hours.
comparison_mode previous_period, since_change, or none.
deep_log_scan Enables bounded scanning of retained and rotated service logs.
max_log_scan_mb Maximum retained-log data read per service request, or shared across targeted stack scans.
include_metrics Includes current-versus-baseline process metrics when history is available.
include_change_history Includes redacted configuration changes saved through DUMB.
include_native_diagnostics Includes allowlisted read-only native service telemetry where supported.

Provider Profile Endpoints

Provider profiles store multiple named AI providers while preserving the existing top-level active-provider fields for backward compatibility. A maximum of 20 profiles can be saved.

Frontend clients should gate this UI with process capability ai_provider_profiles.

POST /ai/profiles

Creates a new profile when id is omitted, or updates an existing profile when its id is supplied. The saved profile becomes active.

{
  "name": "Free Gemini",
  "provider": "gemini",
  "model": "gemini-3.5-flash-lite",
  "api_key": "YOUR_GEMINI_API_KEY",
  "timeout_sec": 60,
  "temperature": 0.2
}

Profile names must be unique and no longer than 80 characters. Omit api_key, or send it blank, to preserve an existing profile key during an update. Native Gemini, OpenAI, and Anthropic profiles always store and use DUMB's managed official endpoints; use the litellm or openai_compatible provider for gateway URLs.

The response is the complete public AI settings object with keys removed and api_key_configured flags added.

POST /ai/profiles/{profile_id}/activate

Activates a saved profile and mirrors its provider-specific values into the top-level active AI settings used by tests, diagnostics, and follow-ups.

DELETE /ai/profiles/{profile_id}

Deletes a saved profile. If the deleted profile was active, DUMB activates the first remaining profile. If none remain, it clears the active profile and restores the default Ollama provider fields.

Profile operations follow the normal DUMB API authentication policy and are recorded in the redacted AI configuration-change ledger.

GET /ai/presets

Returns backend-provided prompt presets grouped under service and stack. Each item contains id, label, and question.

POST /ai/test

Tests the configured provider using a short connectivity prompt. The request can include unsaved provider fields, so the frontend can test current form values before saving them.

This endpoint does not include service logs, service configuration, dependency graph data, or diagnostic bundle content.

Example payload:

{
  "provider": "ollama",
  "base_url": "http://ollama:11434",
  "model": "llama3.1",
  "timeout_sec": 60
}

Response fields:

Field Description
ok True when the provider returned a response.
provider Provider used for the test.
model Model used for the test.
response Provider response text.
usage Best-effort token usage reported by the provider, when available.

POST /ai/models

Lists available models for providers with a compatible model-list endpoint. The request can include unsaved provider fields.

Supported discovery modes:

Provider Endpoint called from the DUMB backend
ollama {base_url}/api/tags
gemini / google_gemini Official Google Gemini /models?pageSize=1000, filtered to generateContent models
anthropic / claude Managed official https://api.anthropic.com/v1/models?limit=1000 endpoint
open_webui {base_url}/api/models
openai Managed official https://api.openai.com/v1/models endpoint
litellm {base_url}/models
openai_compatible / compatible {base_url}/models

Example payload:

{
  "provider": "ollama",
  "base_url": "http://ollama:11434",
  "timeout_sec": 60
}

Example response:

{
  "provider": "ollama",
  "models": [
    {
      "name": "llama3.1:latest",
      "size": 4661224676,
      "modified_at": "2026-06-18T00:00:00Z"
    }
  ]
}

Native Gemini, OpenAI, and Anthropic model entries can include a lifecycle object when the model appears in that provider's published retirement schedule:

{
  "name": "gemini-2.0-flash-lite",
  "source": "external",
  "source_detail": "google",
  "lifecycle": {
    "model": "gemini-2.0-flash-lite",
    "status": "retired",
    "shutdown_date": "2026-06-01",
    "replacement": "gemini-3.1-flash-lite",
    "source_url": "https://ai.google.dev/gemini-api/docs/deprecations"
  }
}

status is deprecated before the published shutdown date and retired on or after that date. DUMB preserves lifecycle-marked entries in discovery results because providers can continue returning shut-down IDs, but calls using a known retired model are rejected with HTTP 400 and replacement guidance before contacting the provider. DUMB's weekly AI model lifecycle workflow compares the maintained catalog with the official Google, OpenAI, and Anthropic tables.

Native provider model entries can also include:

{
  "compatibility": {
    "model": "text-embedding-3-small",
    "status": "unsupported",
    "api_surface": "responses",
    "reason": "This is an embedding or moderation model. DUMB AI Assist requires a model that returns diagnostic text."
  }
}

The frontend marks incompatible entries and disables provider tests/analysis for them. Native OpenAI text and Codex requests use POST https://api.openai.com/v1/responses; Open WebUI, LiteLLM, and generic OpenAI-compatible providers retain /chat/completions.

POST /ai/diagnose

Builds a redacted service diagnostic bundle. If dry_run is true, or if AI is disabled, the endpoint returns the bundle without calling a provider. If AI is enabled and dry_run is false, DUMB sends the bundle to the configured provider and returns the analysis.

Use dry_run: true before enabling provider calls to inspect the exact bundle that would be shared.

Example payload:

{
  "process_name": "Traefik Proxy Admin",
  "question": "Why is this service failing during startup?",
  "dry_run": true,
  "include_logs": true,
  "include_service_config": true,
  "include_dependency_graph": true,
  "include_docs_context": true,
  "max_log_chars": 20000,
  "window_hours": 24,
  "comparison": "previous_period",
  "deep_log_scan": true,
  "max_log_scan_mb": 128,
  "include_metrics": true,
  "include_change_history": true,
  "include_native_diagnostics": true
}

Response fields:

Field Description
enabled Whether provider calls are enabled.
provider Configured provider.
model Configured model.
analysis Provider response, empty for dry runs.
bundle Redacted diagnostic bundle.
usage Best-effort token usage reported by the provider, empty for dry runs or providers that do not return usage.
dry_run True when no provider call was made.
session_id Short-lived in-memory session identifier returned after a provider analysis. Empty for previews.

Diagnostic Bundle Context

The bundle can include docs_context when include_docs_context is enabled. This block contains selected DUMB_docs excerpts with source paths and public documentation URLs. The backend chooses snippets using the service/config key, status, question text, and included logs.

DUMB prefers local Markdown from DUMB_DOCS_PATH, the Markdown-only snapshot bundled in official images at /usr/share/dumb/docs, or common sibling-repo workbench paths. Documentation images and other site assets are not included in the image snapshot.

If local docs are unavailable, DUMB falls back to matching public pages on https://dumbarr.com. The fallback extracts article content and removes navigation, scripts, page chrome, and whitespace-only lines before building excerpts. The raw response is processed in memory and is not cloned or cached to disk.

The bundle also includes DUMB product facts. API clients can use dry-run responses to verify that dumb_product.expansion is Distributed Unlimited Media Bridge before sending a provider request.

Evidence-enabled service bundles may also include:

Field Description
diagnostic_window Current and baseline boundaries plus the selected comparison mode.
log_analysis Bounded retained-log coverage, severity counts, restart markers, error signatures, and cited excerpts.
runtime_metrics Process CPU, RSS, disk activity, PID observations, sample coverage, and calculated changes.
database_health Existing read-only Database Health evidence when available.
change_history Redacted configuration changes recorded when settings are saved through DUMB.
native_diagnostics Allowlisted service-specific evidence. NzbDAV currently includes metrics SQLite and queue-log comparisons.
diagnostic_coverage Source availability and a deterministic confidence hint.
recommendations Review-only deterministic next-action context. No action is applied automatically.

POST /ai/diagnose-stack

Builds a stack-wide diagnostic bundle. Use this when the question is about the whole deployment instead of one service.

If dry_run is true, or if AI is disabled, the endpoint returns the bundle without calling a provider. If AI is enabled and dry_run is false, DUMB sends the stack bundle to the configured provider and returns the analysis.

Example payload:

{
  "question": "What is blocking startup?",
  "dry_run": true,
  "include_logs": true,
  "include_service_config": false,
  "include_dependency_graph": true,
  "include_docs_context": true,
  "include_process_list": true,
  "max_log_chars": 20000,
  "max_docs_chars": 12000,
  "window_hours": 24,
  "comparison": "previous_period",
  "deep_log_scan": true,
  "max_log_scan_mb": 128,
  "include_metrics": true,
  "include_change_history": true,
  "include_native_diagnostics": true
}

Stack bundles include:

Field Description
scope Always stack.
stack_summary Status counts plus services needing attention.
processes Compact process list when enabled.
dumb_service_catalog DUMB-specific workflow guidance used for planning questions such as Usenet service selection.
dependency_graph Aggregated runtime dependency graph across enabled services when enabled.
logs Short targeted log tails for services needing attention when enabled.
service_configs Optional redacted configs for enabled services. Disabled by default for stack requests.
docs_context Selected DUMB_docs snippets when enabled and available.
runtime_metrics One bounded Metrics-history read summarized per enabled process.
log_analysis Bounded retained-log summaries for attention services and services selected by the question.
change_history Redacted stack-wide configuration events in the analysis and baseline windows.
native_diagnostics Available native collector output for enabled supported services.
diagnostic_coverage Counts and availability for the evidence sources used.

When dry_run is false, DUMB compacts stack bundles before sending them to the provider. The API response still includes the full built bundle, but the provider prompt uses shortened docs excerpts, targeted log snippets, capped graph nodes/edges, and omits full service configs with a note. This avoids common context-length failures with local models.

Provider responses include a usage object when the provider reports token or evaluation counts. OpenAI-compatible providers usually return prompt_tokens, completion_tokens, and total_tokens. Ollama native responses return prompt_eval_count and eval_count; DUMB maps those to prompt/completion/total token fields and preserves timing fields such as total_duration.

Native OpenAI Responses usage (input_tokens, output_tokens, and total_tokens) is mapped into the same common fields. DUMB sends store: false and converts system messages to Responses API developer messages.

Gemini native responses expose usageMetadata. DUMB maps promptTokenCount, candidatesTokenCount, and totalTokenCount to the common prompt/completion/total fields and preserves cached/thought-token counts when Google returns them. Gemini requests use POST https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent with the API key in the x-goog-api-key header.

Deterministic Finalizers

For selected stack questions, DUMB may post-process the provider response before returning analysis:

  • Product identity questions such as What does DUMB stand for? return the canonical product fact, Distributed Unlimited Media Bridge, even if the provider invents another acronym expansion.
  • DUMB Usenet planning questions are grounded around Decypharr, NzbDAV, AltMount, Arr apps, Prowlarr, and rclone. If a provider recommends SABnzbd, NZBGet, or NZBHydra as the primary DUMB path, DUMB replaces that with the DUMB-native workflow answer.

The original diagnostic bundle remains available in the response for review. Token usage still reflects the provider request when a provider call was made.

POST /ai/follow-up

Continues a completed provider analysis using the same cached evidence bundle and recent conversation turns.

{
  "session_id": "8d9f5a...",
  "question": "Did the service recover after those errors?"
}

The response contains analysis, usage, provider, model, and the same session_id.

Sessions:

  • Exist in backend memory only
  • Expire after one hour
  • Keep at most eight recent turns
  • Are bounded to 50 active sessions per backend process
  • Are cleared by a backend restart

A follow-up does not rescan logs. Run a new diagnosis when you need a newer time window or additional evidence.

Safety Boundary

The AI provider receives a redacted bundle, not runtime tools. The API does not expose unrestricted shell execution, arbitrary SQL, arbitrary filesystem paths, or configuration mutation to the model.

Retained logs are scanned on demand within the byte budget. The small /config/ai-diagnostics/events.sqlite ledger stores redacted change metadata only; it does not duplicate full logs. NzbDAV native database access opens fixed service databases in SQLite read-only/query-only mode.