Files
openserp/docs/openapi.yaml

2131 lines
69 KiB
YAML
Raw Permalink Normal View History

openapi: 3.0.3
info:
title: OpenSERP API
version: 2.2.0
description: >
OpenSERP provides dedicated and multi-engine search endpoints for Google, Yandex,
Baidu, Bing, and DuckDuckGo. Search responses are wrapped in a v2 envelope with
query echo, metadata, normalized results, and pagination. Invalid client input
returns 400 with a machine-readable `reason` code.
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: http://127.0.0.1:7000
description: Local default server
security: []
tags:
- name: Search
description: Dedicated per-engine search endpoints
- name: Mega
description: Cross-engine aggregated search endpoints
- name: Health
description: Health and readiness endpoints
- name: Stats
description: Runtime statistics endpoints
- name: Docs
description: OpenAPI and Swagger UI endpoints
paths:
/{engine}/search:
get:
tags: [Search]
operationId: searchWeb
summary: Search web results from a specific engine
description: >
Engine path values are `google`, `yandex`, `baidu`, `bing`, `duck`, and `ecosia`
(`duck` maps to DuckDuckGo internally). Use `?format=markdown|text|ndjson`
for alternative output formats.
parameters:
- $ref: "#/components/parameters/EnginePath"
- $ref: "#/components/parameters/TextQuery"
- $ref: "#/components/parameters/LangQuery"
- $ref: "#/components/parameters/RegionQuery"
- $ref: "#/components/parameters/DateQuery"
- $ref: "#/components/parameters/FileQuery"
- $ref: "#/components/parameters/SiteQuery"
- $ref: "#/components/parameters/LimitQuery"
- $ref: "#/components/parameters/StartQuery"
- $ref: "#/components/parameters/FilterQuery"
- $ref: "#/components/parameters/FeaturesQuery"
- $ref: "#/components/parameters/ExtractQuery"
- $ref: "#/components/parameters/ExtractModeQuery"
- $ref: "#/components/parameters/MinRunesQuery"
- $ref: "#/components/parameters/FormatQuery"
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
- $ref: "#/components/parameters/ProxyCountryHeader"
- $ref: "#/components/parameters/ProxyClassHeader"
- $ref: "#/components/parameters/ProxyProviderHeader"
- $ref: "#/components/parameters/ProxySessionIDHeader"
- $ref: "#/components/parameters/TenantHeader"
responses:
"200":
description: Search results envelope
headers:
X-Request-ID:
$ref: "#/components/headers/XRequestID"
X-Cache:
$ref: "#/components/headers/XCache"
X-Fallback-Engine:
$ref: "#/components/headers/XFallbackEngine"
X-Proxy-Mode:
$ref: "#/components/headers/XProxyMode"
X-Proxy-Tag:
$ref: "#/components/headers/XProxyTag"
X-Proxy-Used:
$ref: "#/components/headers/XProxyUsed"
X-Network-Bytes:
$ref: "#/components/headers/XNetworkBytes"
X-Browser-Profile-Id:
$ref: "#/components/headers/XBrowserProfileID"
content:
application/json:
schema:
$ref: "#/components/schemas/SearchEnvelope"
examples:
default:
value:
query:
text: golang
lang: EN
region: US
engines_requested: [google]
meta:
request_id: 01HXYZ...
2026-04-26 02:40:08 +03:00
requested_at: "2026-04-24T12:00:00Z"
took_ms: 842
engines_failed: []
version: "2.1"
results:
2026-04-26 02:40:08 +03:00
- id: s_a1b2c3d4e5f6a1b2
rank: 1
type: organic
title: The Go Programming Language
url: https://go.dev/
display_url: go.dev
snippet: Go is an open source programming language...
domain: go.dev
favicon: https://go.dev/favicon.ico
position:
absolute: 1
engine: google
domain_info:
tld: dev
sld: go
category: ""
serp_features:
- id: f_a1b2c3d4e5f6a1b2
engine: google
type: ai_summary
text: Go is an open source programming language used for fast, reliable services.
links:
- title: The Go Programming Language
url: https://go.dev/
source_result_ids: [s_a1b2c3d4e5f6a1b2]
position:
absolute: 1
confidence: 0.95
extracted_at: "2026-04-24T12:00:00Z"
pagination:
page: 1
has_more: true
next_start: 25
text/markdown:
schema:
type: string
text/plain:
schema:
type: string
application/x-ndjson:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequestError"
"403":
$ref: "#/components/responses/ForbiddenError"
"429":
$ref: "#/components/responses/TooManyRequestsError"
"502":
$ref: "#/components/responses/BadGatewayError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
"504":
$ref: "#/components/responses/GatewayTimeoutError"
"404":
$ref: "#/components/responses/NotFoundError"
"500":
$ref: "#/components/responses/InternalServerError"
/{engine}/image:
get:
tags: [Search]
operationId: searchImages
summary: Search image results from a specific engine
parameters:
- $ref: "#/components/parameters/EnginePath"
- $ref: "#/components/parameters/TextQuery"
- $ref: "#/components/parameters/LangQuery"
- $ref: "#/components/parameters/RegionQuery"
- $ref: "#/components/parameters/DateQuery"
- $ref: "#/components/parameters/FileQuery"
- $ref: "#/components/parameters/SiteQuery"
- $ref: "#/components/parameters/LimitQuery"
- $ref: "#/components/parameters/StartQuery"
- $ref: "#/components/parameters/FilterQuery"
- $ref: "#/components/parameters/FeaturesQuery"
- $ref: "#/components/parameters/FormatQuery"
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
- $ref: "#/components/parameters/ProxyCountryHeader"
- $ref: "#/components/parameters/ProxyClassHeader"
- $ref: "#/components/parameters/ProxyProviderHeader"
- $ref: "#/components/parameters/ProxySessionIDHeader"
- $ref: "#/components/parameters/TenantHeader"
responses:
"200":
description: Image search results envelope
headers:
X-Request-ID:
$ref: "#/components/headers/XRequestID"
X-Cache:
$ref: "#/components/headers/XCache"
X-Fallback-Engine:
$ref: "#/components/headers/XFallbackEngine"
X-Proxy-Mode:
$ref: "#/components/headers/XProxyMode"
X-Proxy-Tag:
$ref: "#/components/headers/XProxyTag"
X-Proxy-Used:
$ref: "#/components/headers/XProxyUsed"
X-Network-Bytes:
$ref: "#/components/headers/XNetworkBytes"
X-Browser-Profile-Id:
$ref: "#/components/headers/XBrowserProfileID"
content:
application/json:
schema:
$ref: "#/components/schemas/ImageEnvelope"
"400":
$ref: "#/components/responses/BadRequestError"
"403":
$ref: "#/components/responses/ForbiddenError"
"429":
$ref: "#/components/responses/TooManyRequestsError"
"502":
$ref: "#/components/responses/BadGatewayError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
"504":
$ref: "#/components/responses/GatewayTimeoutError"
"404":
$ref: "#/components/responses/NotFoundError"
"500":
$ref: "#/components/responses/InternalServerError"
/google/parse:
post:
tags: [Search]
operationId: parseGoogleHTML
summary: Parse a Google SERP HTML document into structured results
description: >
Accepts raw Google SERP HTML in the request body and returns a standard
search envelope. Useful when an upstream provider delivers raw HTML
rather than JSON. No browser is used; parsing is done with goquery.
The body size limit is 10 MB.
requestBody:
required: true
content:
text/html:
schema:
type: string
description: Raw Google SERP HTML page
parameters:
- $ref: "#/components/parameters/FormatQuery"
responses:
"200":
description: Parsed search results envelope
content:
application/json:
schema:
$ref: "#/components/schemas/SearchEnvelope"
text/markdown:
schema:
type: string
text/plain:
schema:
type: string
application/x-ndjson:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequestError"
"500":
$ref: "#/components/responses/InternalServerError"
/bing/parse:
post:
tags: [Search]
operationId: parseBingHTML
summary: Parse a Bing SERP HTML document into structured results
description: >
Accepts raw Bing SERP HTML in the request body and returns a standard
search envelope. Useful when an upstream provider delivers raw HTML
rather than JSON. No browser is used; parsing is done with goquery.
The body size limit is 10 MB.
requestBody:
required: true
content:
text/html:
schema:
type: string
description: Raw Bing SERP HTML page
parameters:
- $ref: "#/components/parameters/FormatQuery"
responses:
"200":
description: Parsed search results envelope
content:
application/json:
schema:
$ref: "#/components/schemas/SearchEnvelope"
text/markdown:
schema:
type: string
text/plain:
schema:
type: string
application/x-ndjson:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequestError"
"500":
$ref: "#/components/responses/InternalServerError"
/mega/search:
get:
tags: [Mega]
operationId: megaSearch
summary: Search across multiple engines with selectable execution mode
description: >
Mode controls engine execution strategy: `balanced` (default) queries all
selected engines in parallel, `any` runs engines sequentially in requested
order until first success, and `fast` queries only the fastest engine based
on circuit-breaker average response time stats.
In `balanced` mode, `dedupe` and `merge` tune aggregation behavior.
Partial failures are surfaced in `meta.engines_failed` and
`meta.engine_errors`. If all selected engines fail, the endpoint returns
a 502 with per-engine error details. Use `?format=markdown|text|ndjson`
for alternative output formats.
parameters:
- $ref: "#/components/parameters/TextQuery"
- $ref: "#/components/parameters/LangQuery"
- $ref: "#/components/parameters/RegionQuery"
- $ref: "#/components/parameters/DateQuery"
- $ref: "#/components/parameters/FileQuery"
- $ref: "#/components/parameters/SiteQuery"
- $ref: "#/components/parameters/LimitQuery"
- $ref: "#/components/parameters/StartQuery"
- $ref: "#/components/parameters/FilterQuery"
- $ref: "#/components/parameters/FeaturesQuery"
- $ref: "#/components/parameters/EnginesQuery"
- $ref: "#/components/parameters/MegaModeQuery"
- $ref: "#/components/parameters/MegaDedupeQuery"
- $ref: "#/components/parameters/MegaMergeQuery"
- $ref: "#/components/parameters/ExtractQuery"
- $ref: "#/components/parameters/ExtractModeQuery"
- $ref: "#/components/parameters/MinRunesQuery"
- $ref: "#/components/parameters/FormatQuery"
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
- $ref: "#/components/parameters/ProxyCountryHeader"
- $ref: "#/components/parameters/ProxyClassHeader"
- $ref: "#/components/parameters/ProxyProviderHeader"
- $ref: "#/components/parameters/ProxySessionIDHeader"
- $ref: "#/components/parameters/TenantHeader"
responses:
"200":
description: Aggregated envelope with clusters
headers:
X-Request-ID:
$ref: "#/components/headers/XRequestID"
X-Cache:
$ref: "#/components/headers/XCache"
X-Proxy-Mode:
$ref: "#/components/headers/XProxyMode"
X-Proxy-Tag:
$ref: "#/components/headers/XProxyTag"
X-Proxy-Used:
$ref: "#/components/headers/XProxyUsed"
X-Network-Bytes:
$ref: "#/components/headers/XNetworkBytes"
X-Browser-Profile-Id:
$ref: "#/components/headers/XBrowserProfileID"
content:
application/json:
schema:
$ref: "#/components/schemas/MegaSearchEnvelope"
text/markdown:
schema:
type: string
text/plain:
schema:
type: string
application/x-ndjson:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequestError"
"403":
$ref: "#/components/responses/ForbiddenError"
"429":
$ref: "#/components/responses/TooManyRequestsError"
"502":
$ref: "#/components/responses/BadGatewayError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
"504":
$ref: "#/components/responses/GatewayTimeoutError"
"500":
$ref: "#/components/responses/InternalServerError"
/mega/image:
get:
tags: [Mega]
operationId: megaImageSearch
summary: Image search across multiple engines with selectable execution mode
parameters:
- $ref: "#/components/parameters/TextQuery"
- $ref: "#/components/parameters/LangQuery"
- $ref: "#/components/parameters/RegionQuery"
- $ref: "#/components/parameters/DateQuery"
- $ref: "#/components/parameters/FileQuery"
- $ref: "#/components/parameters/SiteQuery"
- $ref: "#/components/parameters/LimitQuery"
- $ref: "#/components/parameters/StartQuery"
- $ref: "#/components/parameters/FilterQuery"
- $ref: "#/components/parameters/FeaturesQuery"
- $ref: "#/components/parameters/EnginesQuery"
- $ref: "#/components/parameters/MegaModeQuery"
- $ref: "#/components/parameters/MegaDedupeQuery"
- $ref: "#/components/parameters/MegaMergeQuery"
- $ref: "#/components/parameters/FormatQuery"
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
- $ref: "#/components/parameters/ProxyCountryHeader"
- $ref: "#/components/parameters/ProxyClassHeader"
- $ref: "#/components/parameters/ProxyProviderHeader"
- $ref: "#/components/parameters/ProxySessionIDHeader"
- $ref: "#/components/parameters/TenantHeader"
responses:
"200":
description: Aggregated image results envelope
headers:
X-Request-ID:
$ref: "#/components/headers/XRequestID"
X-Cache:
$ref: "#/components/headers/XCache"
X-Proxy-Mode:
$ref: "#/components/headers/XProxyMode"
X-Proxy-Tag:
$ref: "#/components/headers/XProxyTag"
X-Proxy-Used:
$ref: "#/components/headers/XProxyUsed"
X-Network-Bytes:
$ref: "#/components/headers/XNetworkBytes"
X-Browser-Profile-Id:
$ref: "#/components/headers/XBrowserProfileID"
content:
application/json:
schema:
$ref: "#/components/schemas/ImageEnvelope"
"400":
$ref: "#/components/responses/BadRequestError"
"403":
$ref: "#/components/responses/ForbiddenError"
"429":
$ref: "#/components/responses/TooManyRequestsError"
"502":
$ref: "#/components/responses/BadGatewayError"
"503":
$ref: "#/components/responses/ServiceUnavailableError"
"504":
$ref: "#/components/responses/GatewayTimeoutError"
"500":
$ref: "#/components/responses/InternalServerError"
/mega/engines:
get:
tags: [Mega]
operationId: listMegaEngines
summary: List available engines and runtime state
responses:
"200":
description: Engine list
content:
application/json:
schema:
$ref: "#/components/schemas/MegaEnginesResponse"
/extract:
get:
tags: [Search]
operationId: extractURL
summary: Extract clean content from one URL
parameters:
- $ref: "#/components/parameters/URLQuery"
- $ref: "#/components/parameters/ExtractModeShortQuery"
- $ref: "#/components/parameters/MinRunesQuery"
- $ref: "#/components/parameters/LangQuery"
- $ref: "#/components/parameters/CleanQuery"
- $ref: "#/components/parameters/UseLLMSTxtQuery"
- $ref: "#/components/parameters/FormatQuery"
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
responses:
"200":
description: Extracted URL content
content:
application/json:
schema:
$ref: "#/components/schemas/ExtractResult"
text/markdown:
schema:
type: string
text/plain:
schema:
type: string
application/x-ndjson:
schema:
type: string
"400":
$ref: "#/components/responses/BadRequestError"
"502":
$ref: "#/components/responses/BadGatewayError"
post:
tags: [Search]
operationId: extractURLPost
summary: Extract clean content from one URL
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [url]
properties:
url:
type: string
format: uri
mode:
type: string
enum: [auto, fast, rendered]
default: auto
clean:
type: boolean
default: true
description: >
Article-only extraction (default). Set `false` for
whole-readable-body extraction that keeps nav/feature/landing
content trafilatura would otherwise strip.
use_llms_txt:
type: boolean
default: false
description: >
When the URL is a site root, probe `/llms-full.txt` then
`/llms.txt` and return that LLM-optimized markdown instead of
scraping HTML. Falls through to normal extraction when absent.
min_runes:
type: integer
minimum: 0
description: >
Auto-mode escalation floor: if the fast (raw) pass yields fewer
extracted-text runes than this, escalate to a browser render.
`0` (default) uses the built-in floor. Ignored in `fast` and
`rendered` modes.
lang:
type: string
description: >
Language hint sent as `Accept-Language` on the target fetch.
The `lang` query parameter works as a fallback.
responses:
"200":
description: Extracted URL content
content:
application/json:
schema:
$ref: "#/components/schemas/ExtractResult"
"400":
$ref: "#/components/responses/BadRequestError"
"502":
$ref: "#/components/responses/BadGatewayError"
/extract/batch:
post:
tags: [Search]
operationId: extractBatch
2026-07-18 09:49:38 +02:00
summary: Extract content from multiple URLs
description: >
Accepts up to 20 URLs (deduplicated) and returns a bare JSON array of
`{page_content, metadata}` items - the shape Open WebUI's external web
loader expects. A URL that fails validation or extraction yields an
item with `metadata.error` and an empty `page_content` instead of
failing the batch. `400` is reserved for malformed requests: empty or
oversized `urls`, unknown `mode`, invalid proxy headers.
parameters:
- $ref: "#/components/parameters/UseProxyHeader"
- $ref: "#/components/parameters/ProxyURLHeader"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BatchExtractRequest"
responses:
"200":
description: Batch extraction results, one item per unique URL
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/BatchExtractItem"
"400":
$ref: "#/components/responses/BadRequestError"
/health:
get:
tags: [Health]
operationId: healthCheck
summary: Service health status
responses:
"200":
description: Healthy or degraded service
content:
application/json:
schema:
$ref: "#/components/schemas/HealthStatus"
"503":
description: Unhealthy service
content:
application/json:
schema:
$ref: "#/components/schemas/HealthStatus"
/ready:
get:
tags: [Health]
operationId: readinessCheck
summary: Service readiness status
responses:
"200":
description: Instance is ready
content:
application/json:
schema:
$ref: "#/components/schemas/ReadinessStatus"
"503":
description: Instance is draining
content:
application/json:
schema:
$ref: "#/components/schemas/ReadinessStatus"
/stats:
get:
tags: [Stats]
operationId: getStats
summary: Combined cache, proxy, and circuit-breaker stats
responses:
"200":
description: Runtime statistics
content:
application/json:
schema:
$ref: "#/components/schemas/StatsResponse"
/stats/cache:
get:
tags: [Stats]
operationId: getCacheStats
summary: Cache statistics only
responses:
"200":
description: Cache status
content:
application/json:
schema:
$ref: "#/components/schemas/CacheStats"
/stats/proxy:
get:
tags: [Stats]
operationId: getProxyStats
summary: Proxy pool and per-engine proxy policy statistics
responses:
"200":
description: Proxy stats
content:
application/json:
schema:
$ref: "#/components/schemas/ProxyStats"
/stats/cb:
get:
tags: [Stats]
operationId: getCircuitBreakerStats
summary: Circuit breaker state per engine
responses:
"200":
description: Circuit breaker stats
content:
application/json:
schema:
$ref: "#/components/schemas/CircuitBreakerStatsResponse"
/openapi.yaml:
get:
tags: [Docs]
operationId: getOpenAPISpec
summary: Get raw OpenAPI YAML
responses:
"200":
description: OpenAPI YAML
content:
application/yaml:
schema:
type: string
/docs:
get:
tags: [Docs]
operationId: getSwaggerUI
summary: Swagger UI for interactive API docs
responses:
"200":
description: HTML page loading Swagger UI from CDN
content:
text/html:
schema:
type: string
components:
parameters:
EnginePath:
name: engine
in: path
required: true
description: Search engine endpoint alias (`duck` is DuckDuckGo).
schema:
type: string
enum: [google, yandex, baidu, bing, duck, ecosia]
TextQuery:
name: text
in: query
required: false
description: >
Search query text. At least one of `text`, `site`, or `file` must be non-empty.
schema:
type: string
example: golang
LangQuery:
name: lang
in: query
required: false
description: Language code (engine-specific behavior).
schema:
type: string
example: EN
RegionQuery:
name: region
in: query
required: false
description: >
Market/location hint. Country or locale-style values such as `US`,
`DE`, or `en-GB` are shared by engines that support them. Google also
accepts city names such as `Berlin` or `New York` and sends them as
`uule`. Yandex accepts numeric `lr` region IDs such as `213`; those IDs
are engine-specific and are ignored by other engines.
schema:
type: string
examples:
yandex:
value: "213"
country:
value: RU
google_city:
value: Berlin
DateQuery:
name: date
in: query
required: false
description: Date interval in `YYYYMMDD..YYYYMMDD` format.
schema:
type: string
pattern: "^[0-9]{8}\\.\\.[0-9]{8}$"
example: 20250101..20250131
FileQuery:
name: file
in: query
required: false
description: File extension filter (for engines that support it).
schema:
type: string
example: PDF
SiteQuery:
name: site
in: query
required: false
description: Site/domain filter.
schema:
type: string
example: github.com
LimitQuery:
name: limit
in: query
required: false
2026-06-02 21:44:58 +03:00
description: Maximum organic results to return (1-100). Ads may be returned in addition. Omitted or small limits (<=10) parse only the first SERP page; larger limits may paginate when an engine supports it.
schema:
type: integer
minimum: 1
maximum: 100
2026-06-02 21:44:58 +03:00
default: 10
example: 10
StartQuery:
name: start
in: query
required: false
description: Pagination offset (must be >= 0).
schema:
type: integer
minimum: 0
default: 0
example: 20
FilterQuery:
name: filter
in: query
required: false
description: Duplicate filtering flag (primarily used by Google parser behavior).
schema:
type: boolean
default: true
FeaturesQuery:
name: features
in: query
required: false
description: >
Populate the top-level serp_features array (AI summaries, answer boxes,
people-also-ask, related searches) from the live browser search when
supported by the engine.
schema:
type: boolean
2026-06-02 21:44:58 +03:00
default: true
EnginesQuery:
name: engines
in: query
required: false
description: >
Comma-separated engine list for mega endpoints. If omitted, all available engines are used.
schema:
type: string
example: google,bing,duckduckgo
MegaModeQuery:
name: mode
in: query
required: false
description: >
Mega execution mode. `balanced` (default) runs all selected engines in parallel.
`any` runs selected engines sequentially in request order until first success.
`fast` runs only one engine: the fastest by circuit-breaker average response time.
schema:
type: string
enum: [balanced, any, fast]
default: balanced
MegaDedupeQuery:
name: dedupe
in: query
required: false
description: >
Enable deduplication by normalized URL. Default `true`.
schema:
type: boolean
default: true
MegaMergeQuery:
name: merge
in: query
required: false
description: >
Merge results from all successful engines into one flat list. Default `true`.
When `false`, only the first requested engine that returned results is kept.
schema:
type: boolean
default: true
FormatQuery:
name: format
in: query
required: false
description: >
Output format. `json` (default) returns the envelope. `markdown` returns a
Markdown document suitable for Slack/email. `text` returns a minimal plain-text
block optimised for LLM context windows. `ndjson` returns one result object per
line with no envelope. The `Accept` header is also checked
(`text/markdown`, `text/plain`, `application/x-ndjson`).
schema:
type: string
enum: [json, markdown, text, ndjson]
default: json
URLQuery:
name: url
in: query
required: true
description: Absolute URL to fetch and extract.
schema:
type: string
format: uri
ExtractQuery:
name: extract
in: query
required: false
description: >
Fetch and embed cleaned target-page content for the top web results.
Accepts a boolean or an integer depth: `extract=0`/`false` disables
extraction; `extract=true`/`1` enriches the top result; `extract=N`
(1-5) enriches the top N results. The tuning params `extract_mode` and
`min_runes` imply `extract=true` (top 1) when present, unless
`extract=0` is set explicitly.
schema:
oneOf:
- type: boolean
- type: integer
minimum: 0
maximum: 5
default: false
ExtractModeQuery:
name: extract_mode
in: query
required: false
description: >
Extraction strategy for target pages. Its presence implies
`extract=true` unless `extract=0` is set explicitly.
schema:
type: string
enum: [auto, fast, rendered]
default: auto
ExtractModeShortQuery:
name: mode
in: query
required: false
description: Extraction strategy for one URL.
schema:
type: string
enum: [auto, fast, rendered]
default: auto
MinRunesQuery:
name: min_runes
in: query
required: false
description: >
Auto-mode escalation floor: if the fast (raw) pass yields fewer
extracted-text runes than this, escalate to a browser render. `0`
(default) uses the built-in floor. Ignored in `fast` and `rendered`
modes.
schema:
type: integer
minimum: 0
CleanQuery:
name: clean
in: query
required: false
description: >
Article-only extraction (default). Set `false` for whole-readable-body
extraction that keeps nav/feature/landing content trafilatura would
otherwise strip — useful for landing pages, doc indexes, and dashboards.
schema:
type: boolean
default: true
UseLLMSTxtQuery:
name: use_llms_txt
in: query
required: false
description: >
When the URL is a site root, probe `/llms-full.txt` then `/llms.txt` and
return that LLM-optimized markdown instead of scraping HTML
(see https://llmstxt.org/). Falls through to normal extraction when
absent. Ignored for non-root URLs, where it would miss the requested
page's own content.
schema:
type: boolean
default: false
UseProxyHeader:
name: X-Use-Proxy
in: header
required: false
description: >
Request-scoped proxy override. Use `direct` to disable proxy or a tag name to
force a specific proxy pool.
schema:
type: string
examples:
direct:
value: direct
tag:
value: us
ProxyURLHeader:
name: X-Proxy-URL
in: header
required: false
description: >
Per-request proxy URL supplied by an upstream balancer. Honored only when
`proxies.allow_request_proxy_url: true` is set on the worker; otherwise the
request is rejected with `400 bad_request` and `reason=REQUEST_PROXY_URL_DISABLED`.
Authenticated SOCKS proxies are rejected in browser mode
(`reason=UNSUPPORTED_PROXY_SCHEME`). Credentials are never logged or returned.
Precedence: `X-Use-Proxy: direct` > `X-Proxy-URL` > `X-Use-Proxy: <tag>` >
per-engine configured tag > `proxies.global` > direct.
schema:
type: string
example: http://user:pass@proxy.example:8080
ProxyCountryHeader:
name: X-Proxy-Country
in: header
required: false
description: >
Two-letter market country code for the supplied proxy. Used as part of the
cache key so different markets do not share results.
schema:
type: string
example: us
ProxyClassHeader:
name: X-Proxy-Class
in: header
required: false
description: Proxy class identifier (e.g. `datacenter`, `residential`, `mobile`). Part of the cache key.
schema:
type: string
example: residential
ProxyProviderHeader:
name: X-Proxy-Provider
in: header
required: false
description: Upstream proxy provider identifier (e.g. `webshare`, `brightdata`). Part of the cache key.
schema:
type: string
example: webshare
ProxySessionIDHeader:
name: X-Proxy-Session-ID
in: header
required: false
description: >
Sticky session identifier minted by the balancer. Reusing the same value lets
OpenSERP reuse cookies and browser profile for that lane. Lanes are LRU-bounded
by `proxies.lanes.max_lanes`. Rotating the session ID gives a clean lane.
schema:
type: string
example: sid-123
TenantHeader:
name: X-Tenant
in: header
required: false
description: >
Optional tenant scope used to namespace sticky lane state across multi-tenant
deployments. When present, lanes are keyed by `tenant + engine + session_id`.
schema:
type: string
headers:
XRequestID:
description: >
UUID v7 request identifier. Matches `meta.request_id` in the response body and
appears in server logs for correlation.
schema:
type: string
XCache:
description: Cache status when cache is enabled (`HIT`, `MISS`, `BYPASS`).
schema:
type: string
enum: [HIT, MISS, BYPASS]
XFallbackEngine:
description: Engine name used when dedicated endpoint fallback served the response.
schema:
type: string
XProxyMode:
description: >
Effective proxy mode for the request. `request_url` indicates a per-request
`X-Proxy-URL` was honored.
schema:
type: string
enum: [off, tag_pool, request_url]
XProxyTag:
description: >
Effective proxy tag when `X-Proxy-Mode=tag_pool`. Header is omitted when no
tag is in effect (i.e. `X-Proxy-Mode` is `request_url` or `off`).
schema:
type: string
XProxyUsed:
description: >
Effective proxy target used. Values: `direct`, masked `scheme://host:port` URL,
`pooled`, `multiple`, or `mixed`. Credentials are never included.
schema:
type: string
XNetworkBytes:
description: >
Aggregate inbound network bytes consumed while executing the search request.
Single-engine endpoints report that engine's request bytes; mega endpoints
report the sum across selected engines. Cache hits return `0`.
schema:
type: integer
format: int64
minimum: 0
XBrowserProfileID:
description: >
Browser profile ID selected for browser-mode execution. Mega endpoints may
return a comma-separated list when multiple profiles were used.
schema:
type: string
responses:
BadRequestError:
description: Invalid request parameters
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
invalidLimit:
value:
error: bad_request
code: 400
message: "INVALID_LIMIT: limit must be between 1 and 100"
reason: INVALID_LIMIT
emptyQuery:
value:
error: bad_request
code: 400
message: "EMPTY_QUERY: query cannot be empty"
reason: EMPTY_QUERY
requestProxyURLDisabled:
value:
error: bad_request
code: 400
message: "REQUEST_PROXY_URL_DISABLED: X-Proxy-URL is disabled by server configuration"
reason: REQUEST_PROXY_URL_DISABLED
unsupportedProxyScheme:
value:
error: bad_request
code: 400
message: "UNSUPPORTED_PROXY_SCHEME: authenticated SOCKS proxies are not supported in browser mode"
reason: UNSUPPORTED_PROXY_SCHEME
ForbiddenError:
description: The search engine blocked the request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
blocked:
value:
error: blocked
code: 403
message: "search engine blocked the request"
meta:
engine: google
proxy_used: http://proxy.example:8080
proxy_country: us
proxy_class: residential
proxy_provider: webshare
proxy_session_id: sid-123
TooManyRequestsError:
description: Captcha challenge or rate-limit response from the search engine
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
captcha:
value:
error: captcha_detected
code: 429
message: "captcha detected"
meta:
engine: google
proxy_used: http://proxy.example:8080
proxy_session_id: sid-123
upstreamBlocked:
value:
error: blocked
code: 429
message: "search engine blocked the request (HTTP 429)"
meta:
engine: google
proxy_used: http://proxy.example:8080
upstream_status: 429
BadGatewayError:
description: Engine internal failure, parser drift, or all-engine failure when fallback is enabled.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
parserFailure:
value:
error: parser_failure
code: 502
message: "parser failure"
meta:
engine: google
engineInternal:
value:
error: engine_internal
code: 502
message: "engine internal error"
meta:
engine: google
allEnginesFailed:
value:
error: engine_internal
code: 502
message: "all search engines failed"
meta:
engine: google
GatewayTimeoutError:
description: Search timed out waiting for required SERP elements
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
searchTimeout:
value:
error: search_timeout
code: 504
message: "timeout. Cannot find element on page"
meta:
engine: google
ServiceUnavailableError:
description: Proxy-layer failure (no healthy proxy or transport error). The search itself was not produced.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
proxyConnect:
value:
error: proxy_connect
code: 503
message: "proxy connection failed"
meta:
engine: google
proxy_used: http://proxy.example:8080
proxy_country: us
proxyAuth:
value:
error: proxy_auth
code: 503
message: "proxy authentication failed"
meta:
engine: google
proxy_used: http://proxy.example:8080
proxyTimeout:
value:
error: proxy_timeout
code: 503
message: "proxy request timed out"
meta:
engine: google
proxy_used: http://proxy.example:8080
proxyUnavailable:
value:
error: proxy_unavailable
code: 503
message: "proxy unavailable"
meta:
engine: google
NotFoundError:
description: Endpoint not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
InternalServerError:
description: Internal error while handling request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
schemas:
# ── v2 envelope ──────────────────────────────────────────────────
QueryEcho:
type: object
2026-04-26 02:40:08 +03:00
required: [text, engines_requested]
properties:
text:
type: string
example: golang
lang:
type: string
example: EN
region:
type: string
example: US
engines_requested:
type: array
items:
type: string
example: [google]
ResponseMeta:
type: object
2026-04-26 02:40:08 +03:00
required: [request_id, requested_at, took_ms, engines_failed, version]
properties:
request_id:
type: string
example: 01HXYZ...
2026-04-26 02:40:08 +03:00
requested_at:
type: string
format: date-time
example: "2026-04-24T12:00:00Z"
took_ms:
type: integer
example: 842
engines_failed:
type: array
items:
type: string
example: []
engine_errors:
type: array
description: Sanitized per-engine failures for mega endpoints.
items:
$ref: "#/components/schemas/EngineErrorDetail"
version:
type: string
example: "2.1"
EngineErrorDetail:
type: object
required: [engine, error]
properties:
engine:
type: string
example: bing
error:
type: string
example: blocked
message:
type: string
description: Sanitized detail; proxy credentials are never included.
example: "blocked: 403"
Pagination:
type: object
required: [page, has_more, next_start]
properties:
page:
type: integer
minimum: 1
example: 1
has_more:
type: boolean
example: true
next_start:
type: integer
example: 25
# ── Result ───────────────────────────────────────────────────────
Position:
type: object
required: [absolute]
properties:
absolute:
type: integer
description: >
1-based rank in the mixed SERP stream, across both organic and ad blocks.
Always present so SEO callers can plot rank vs. on-page position without
inferring it from result order.
example: 2
DomainInfo:
type: object
required: [category]
properties:
tld:
type: string
example: org
sld:
type: string
example: wikipedia
category:
type: string
description: Empty string when the domain matches no known category.
enum: ["", gov, edu, mil, news, forum, marketplace, social]
Classification:
type: object
properties:
content_type:
type: string
enum: [article, document, video, forum_thread, webpage]
example: article
source_hint:
type: string
example: encyclopedia
ResultType:
type: string
description: >
SERP block type. New values require a minor version bump (`meta.version: "2.1"`).
In v2.1, engines may emit specialized modules such as `people_also_ask`
when a parser can classify them reliably.
enum:
- organic
- ad
- featured_snippet
- knowledge_panel
- people_also_ask
- video
- image
- news
- shopping
- local
- answer_box
- ai_summary
- related_questions
- related_searches
- sitelinks
- videos
- images_inline
- calculator
- weather
- dictionary
Result:
type: object
required:
- id
- rank
- type
- title
- url
- display_url
- snippet
- domain
- favicon
- position
- engine
properties:
id:
type: string
description: >
2026-04-26 02:40:08 +03:00
Stable identifier: `s_` + hex(first 8 bytes of MD5(engine|normalized_url)).
Normalized URL: lowercase scheme+host, trailing slash stripped, utm_*/fbclid/gclid
tracking params removed. Same URL → same ID across requests.
2026-04-26 02:40:08 +03:00
example: s_a1b2c3d4e5f6a1b2
rank:
type: integer
example: 1
type:
$ref: "#/components/schemas/ResultType"
title:
type: string
example: The Go Programming Language
url:
type: string
example: https://go.dev/
display_url:
type: string
description: Breadcrumb form of the URL (e.g. `go.dev doc install`).
example: go.dev
snippet:
type: string
example: Go is an open source programming language...
domain:
type: string
description: Registrable domain with leading `www.` stripped.
example: go.dev
favicon:
type: string
description: Constructed as `https://{domain}/favicon.ico`. Not probed.
example: https://go.dev/favicon.ico
position:
$ref: "#/components/schemas/Position"
engine:
type: string
example: google
domain_info:
$ref: "#/components/schemas/DomainInfo"
classification:
$ref: "#/components/schemas/Classification"
extracted:
$ref: "#/components/schemas/ExtractedContent"
ExtractedContent:
type: object
description: >
One enriched target page. `content` holds a single representation chosen
by the response `format` (plain text for `format=text`, markdown
otherwise), named by `format`. No duplicated markdown/text blobs.
properties:
title:
type: string
format:
type: string
enum: [markdown, text]
content:
type: string
mode_used:
type: string
enum: [fast, rendered, llms_txt]
fetched_at:
type: string
format: date-time
error:
type: string
ExtractResult:
type: object
properties:
url:
type: string
format: uri
title:
type: string
description:
type: string
markdown:
type: string
text:
type: string
headings:
type: array
items:
$ref: "#/components/schemas/ExtractHeading"
links:
type: array
items:
$ref: "#/components/schemas/ExtractLink"
canonical:
type: string
format: uri
lang:
type: string
schema_org:
type: array
items:
type: object
additionalProperties: true
og_tags:
type: object
additionalProperties:
type: string
meta:
$ref: "#/components/schemas/ExtractMeta"
ExtractHeading:
type: object
properties:
level:
type: integer
minimum: 1
maximum: 6
text:
type: string
ExtractLink:
type: object
properties:
text:
type: string
url:
type: string
format: uri
ExtractMeta:
type: object
properties:
mode_used:
type: string
description: >
Extraction strategy that produced the result. `llms_txt` means the
site's LLM-optimized markdown was served from `/llms-full.txt` or
`/llms.txt` instead of scraping HTML.
enum: [fast, rendered, llms_txt]
fetched_at:
type: string
format: date-time
bytes:
type: integer
took_ms:
type: integer
FeatureItem:
type: object
properties:
title:
type: string
example: "What is OpenSERP?"
text:
type: string
example: "OpenSERP is an open-source SERP API."
link:
type: string
example: https://openserp.org/
FeatureLink:
type: object
properties:
title:
type: string
example: OpenSERP
url:
type: string
example: https://openserp.org/
SerpFeature:
type: object
required: [id, engine, type, extracted_at]
properties:
id:
type: string
description: Stable identifier prefixed with `f_`.
example: f_a1b2c3d4e5f6a1b2
engine:
type: string
example: google
type:
$ref: "#/components/schemas/ResultType"
title:
type: string
example: OpenSERP
text:
type: string
description: Primary human-readable feature content.
example: OpenSERP is an open-source SERP API.
items:
type: array
items:
$ref: "#/components/schemas/FeatureItem"
links:
type: array
items:
$ref: "#/components/schemas/FeatureLink"
source_result_ids:
type: array
items:
type: string
example: [s_a1b2c3d4e5f6a1b2]
position:
$ref: "#/components/schemas/Position"
confidence:
type: number
format: float
minimum: 0
maximum: 1
example: 0.95
extracted_at:
type: string
format: date-time
example: "2026-04-24T12:00:00Z"
# ── Image result ─────────────────────────────────────────────────
ImageData:
type: object
required: [url]
properties:
url:
type: string
example: https://example.com/gopher.png
thumbnail:
type: string
example: https://example.com/gopher-thumb.png
width:
type: integer
example: 1200
height:
type: integer
example: 800
ImageSource:
type: object
required: [page_url, domain]
properties:
page_url:
type: string
example: https://example.com/article-about-gophers
domain:
type: string
example: example.com
ImageResult:
type: object
2026-04-26 02:40:08 +03:00
required: [id, rank, type, title, image, source, engine]
properties:
id:
type: string
description: Stable identifier prefixed with `i_`.
2026-04-26 02:40:08 +03:00
example: i_a1b2c3d4e5f6a1b2
rank:
type: integer
example: 1
type:
type: string
enum: [image]
title:
type: string
image:
$ref: "#/components/schemas/ImageData"
source:
$ref: "#/components/schemas/ImageSource"
engine:
type: string
# ── Clusters (mega only) ──────────────────────────────────────────
ClusterOccurrence:
type: object
required: [engine, rank, result_id]
properties:
engine:
type: string
example: google
rank:
type: integer
example: 1
result_id:
type: string
2026-04-26 02:40:08 +03:00
example: s_a1b2c3d4e5f6a1b2
Cluster:
type: object
required: [id, canonical_url, domain, title, occurrences, engines_count, best_rank, score]
properties:
id:
type: string
description: >
2026-04-26 02:40:08 +03:00
Stable identifier: `c_` + hex(first 8 bytes of MD5(normalized_url)).
example: c_a1b2c3d4e5f6a1b2
canonical_url:
type: string
example: https://go.dev/
domain:
type: string
example: go.dev
title:
type: string
example: The Go Programming Language
occurrences:
type: array
items:
$ref: "#/components/schemas/ClusterOccurrence"
engines_count:
type: integer
description: Number of engines this URL appeared in.
example: 3
best_rank:
type: integer
description: Lowest (best) rank seen across all engines.
example: 1
score:
type: number
format: float
description: >
Cross-engine agreement score: sum(1/rank for each occurrence) / engines_queried,
capped at 1.0. Higher is better.
example: 0.92
# ── Envelopes ─────────────────────────────────────────────────────
SearchEnvelope:
type: object
required: [query, meta, results, serp_features, pagination]
properties:
query:
$ref: "#/components/schemas/QueryEcho"
meta:
$ref: "#/components/schemas/ResponseMeta"
results:
type: array
items:
$ref: "#/components/schemas/Result"
serp_features:
type: array
description: >
Non-organic SERP modules such as AI summaries, answer boxes,
related questions, related searches, and knowledge panels.
items:
$ref: "#/components/schemas/SerpFeature"
pagination:
$ref: "#/components/schemas/Pagination"
MegaSearchEnvelope:
allOf:
- $ref: "#/components/schemas/SearchEnvelope"
- type: object
properties:
clusters:
type: array
nullable: true
items:
$ref: "#/components/schemas/Cluster"
description: >
Cross-engine clusters, sorted by score descending. Only present on
/mega/search responses. Absent (not null) on single-engine endpoints.
ImageEnvelope:
type: object
required: [query, meta, results, pagination]
properties:
query:
$ref: "#/components/schemas/QueryEcho"
meta:
$ref: "#/components/schemas/ResponseMeta"
results:
type: array
items:
$ref: "#/components/schemas/ImageResult"
pagination:
$ref: "#/components/schemas/Pagination"
# ── Error ─────────────────────────────────────────────────────────
ErrorResponse:
type: object
required: [error, code]
properties:
error:
type: string
description: >
Stable machine-readable error class. Search-pipeline failures use the
following codes: `captcha_detected`, `blocked`,
`search_timeout`, `proxy_connect`, `proxy_auth`, `proxy_timeout`,
`proxy_unavailable`, `parser_failure`, `engine_internal`,
`all_engines_failed`, `circuit_open`, `request_timeout`,
`request_canceled`. Validation errors use `bad_request`. Other
generic codes (`not_found`, `rate_limited`, `service_unavailable`,
`server_error`, `client_error`, `error`) may appear for non-search
routes.
enum:
- bad_request
- not_found
- rate_limited
- service_unavailable
- server_error
- client_error
- error
- captcha_detected
- blocked
- search_timeout
- proxy_connect
- proxy_auth
- proxy_timeout
- proxy_unavailable
- parser_failure
- engine_internal
- all_engines_failed
- circuit_open
- request_timeout
- request_canceled
example: bad_request
code:
type: integer
example: 400
request_id:
type: string
description: Matches the `X-Request-ID` response header.
example: 01HXYZ...
message:
type: string
example: "INVALID_LIMIT: limit must be between 1 and 100"
reason:
type: string
description: >
Stable client-actionable reason code. Present on 400 errors.
Known values: INVALID_LIMIT, INVALID_START, INVALID_PARAM, EMPTY_QUERY,
NO_ENGINES, UNKNOWN_FORMAT, REQUEST_PROXY_URL_DISABLED,
UNSUPPORTED_PROXY_SCHEME.
example: INVALID_LIMIT
meta:
type: object
description: >
Sanitized context for search-pipeline errors. Credentials are never
included.
additionalProperties: true
properties:
engine:
type: string
example: google
proxy_used:
type: string
description: Masked `scheme://host:port`; never includes credentials.
example: http://proxy.example:8080
proxy_country:
type: string
example: us
proxy_class:
type: string
example: residential
proxy_provider:
type: string
example: webshare
proxy_session_id:
type: string
example: sid-123
error_detail:
type: string
description: Sanitized underlying error detail when available.
example: "proxy_connect: dial tcp proxy.example:8080: connection refused"
engine_errors:
type: array
items:
$ref: "#/components/schemas/EngineErrorDetail"
# ── Health / Stats ────────────────────────────────────────────────
EngineHealth:
type: object
required: [name, initialized, status]
properties:
name:
type: string
example: google
initialized:
type: boolean
example: true
status:
type: string
enum: [ready, not_initialized, circuit_open]
HealthStatus:
type: object
required: [status, uptime, engines, system]
properties:
status:
type: string
enum: [healthy, degraded, unhealthy]
uptime:
type: string
example: 1h12m3s
engines:
type: array
items:
$ref: "#/components/schemas/EngineHealth"
system:
type: object
additionalProperties: true
ReadinessStatus:
type: object
required: [status]
properties:
status:
type: string
enum: [ready, draining]
CacheStatsEnabled:
type: object
required: [status, entries, hits, misses, bypasses, evictions, ttl_seconds, max_size]
properties:
status:
type: boolean
enum: [true]
entries:
type: integer
hits:
type: integer
misses:
type: integer
bypasses:
type: integer
evictions:
type: integer
ttl_seconds:
type: integer
max_size:
type: integer
CacheStatsDisabled:
type: object
required: [status]
properties:
status:
type: boolean
enum: [false]
CacheStats:
oneOf:
- $ref: "#/components/schemas/CacheStatsEnabled"
- $ref: "#/components/schemas/CacheStatsDisabled"
ProxyTagSummary:
type: object
required: [configured, healthy]
properties:
configured:
type: integer
healthy:
type: integer
ProxyStatsEntry:
type: object
required: [proxy, tags, healthy, failures, disabled]
properties:
proxy:
type: string
tags:
type: array
items:
type: string
healthy:
type: boolean
failures:
type: integer
disabled:
type: boolean
ProxyEngineStats:
type: object
required: [selected_proxy]
properties:
tag:
type: string
selected_proxy:
type: string
LaneStats:
type: object
required: [active, evicted_lru, cookies_dropped]
description: Sticky proxy lane state observed by this worker.
properties:
active:
type: integer
description: Number of lanes currently held by the worker.
example: 12
evicted_lru:
type: integer
description: Lanes evicted by the LRU bound since worker start.
example: 7
cookies_dropped:
type: integer
description: Lane cookie drops triggered by captcha/challenge responses.
example: 20
BrowserPoolStats:
type: object
required: [active, max, evicted_lru, evicted_idle]
description: >
Live state of the per-process Chrome pool. Each authenticated upstream
proxy identity (scheme+host+port+username) gets a dedicated Chrome so
Chrome can answer 407 challenges natively. Direct and unauthenticated
proxies share one Chrome with per-BrowserContext proxy override.
properties:
active:
type: integer
description: Number of Chrome processes currently held by the pool.
example: 3
max:
type: integer
description: Configured `app.max_processes` LRU cap.
example: 4
evicted_lru:
type: integer
description: Chrome processes closed because the LRU cap was exceeded.
example: 12
evicted_idle:
type: integer
description: Chrome processes closed by the idle sweeper after `app.idle_ttl`.
example: 5
ProxyStats:
type: object
required:
[
configured_count,
healthy_count,
unhealthy_count,
request_proxy_url_enabled,
lanes,
browser_processes,
tags,
entries,
]
properties:
configured_count:
type: integer
healthy_count:
type: integer
unhealthy_count:
type: integer
request_proxy_url_enabled:
type: boolean
description: Whether `proxies.allow_request_proxy_url` is enabled on this worker.
lanes:
$ref: "#/components/schemas/LaneStats"
browser_processes:
$ref: "#/components/schemas/BrowserPoolStats"
tags:
type: object
additionalProperties:
$ref: "#/components/schemas/ProxyTagSummary"
entries:
type: array
items:
$ref: "#/components/schemas/ProxyStatsEntry"
engines:
type: object
additionalProperties:
$ref: "#/components/schemas/ProxyEngineStats"
CircuitBreakerStat:
type: object
required: [engine, state, failure_count, last_changed]
properties:
engine:
type: string
state:
type: string
enum: [closed, open, half-open]
failure_count:
type: integer
last_changed:
type: string
format: date-time
retry_in:
type: integer
description: Seconds until next half-open attempt (present when state is open).
avg_response_ms:
type: integer
description: Average successful engine response time in milliseconds.
CircuitBreakerStatsResponse:
type: object
required: [circuit_breakers]
properties:
circuit_breakers:
type: array
items:
$ref: "#/components/schemas/CircuitBreakerStat"
StatsResponse:
type: object
required: [cache, proxy, circuit_breakers]
properties:
cache:
$ref: "#/components/schemas/CacheStats"
proxy:
$ref: "#/components/schemas/ProxyStats"
circuit_breakers:
type: array
items:
$ref: "#/components/schemas/CircuitBreakerStat"
MegaEngineInfo:
type: object
required: [name, initialized]
properties:
name:
type: string
initialized:
type: boolean
circuit_state:
type: string
enum: [closed, open, half-open]
MegaEnginesResponse:
type: object
required: [engines, total]
properties:
engines:
type: array
items:
$ref: "#/components/schemas/MegaEngineInfo"
total:
type: integer
2026-07-18 09:49:38 +02:00
# ── Batch extract ─────────────────────────────────────────────────
BatchExtractRequest:
type: object
required: [urls]
properties:
urls:
type: array
items:
type: string
maxItems: 20
description: URLs to extract content from (max 20 after deduplication)
mode:
type: string
enum: [auto, fast, rendered]
default: auto
description: Extraction mode
clean:
type: boolean
default: true
description: >
Article-only extraction (default). Set `false` for
whole-readable-body extraction.
use_llms_txt:
type: boolean
default: false
description: >
Probe `/llms-full.txt` then `/llms.txt` for site-root URLs and use
that markdown instead of scraping HTML.
min_runes:
type: integer
minimum: 0
description: Auto-mode escalation floor, same semantics as `/extract`
lang:
type: string
description: >
Language hint sent as `Accept-Language` on target fetches. The
`lang` query parameter works as a fallback.
BatchExtractItem:
type: object
properties:
page_content:
type: string
description: Extracted markdown content, empty when the item failed
metadata:
type: object
additionalProperties:
type: string
description: >
Page metadata (source, title, lang, canonical, mode_used, etc.).
Failed items carry only `source` and `error`.