# openSERP — full integration reference > Complete public REST and MCP guides, engine reference, OpenAPI definition and MCP tool schemas. Generated from the site documentation on each build. Canonical URL: https://openserp.io/llms-full.txt Quick reference: https://openserp.io/llms.txt REST guide: https://openserp.io/docs MCP guide: https://openserp.io/docs/mcp Live starting prices: https://openserp.io/api/pricing Live source status: https://openserp.io/api/status Examples in eight languages: https://openserp.io/examples Download examples: https://openserp.io/downloads/openserp-examples.zip ## Quick reference > Multi-engine search API with inclusive usage prices, real source health, MCP and optional Markdown fetching. - Generate a free API key without sign-up: https://openserp.io/keys - Canonical origin: https://openserp.io - Full integration reference: https://openserp.io/llms-full.txt - REST documentation: https://openserp.io/docs - OpenAPI: https://openserp.io/openapi.json - Code examples in eight languages: https://openserp.io/examples - Download examples: https://openserp.io/downloads/openserp-examples.zip - Copy-paste Codex / Claude Code / Cursor / VS Code setup: https://openserp.io/mcp-install.md - MCP setup and OAuth: https://openserp.io/docs/mcp - MCP tool schemas: https://openserp.io/mcp-tools.json - MCP Streamable HTTP: https://openserp.io/mcp - OAuth discovery: https://openserp.io/.well-known/oauth-authorization-server - Source health: https://openserp.io/api/status MCP search and quote default to Firehose Lite (endpoint firehose.search, firehoseTier lite). MCP search defaults to results only (pageMarkdown false) and shared cache enabled with a 24-hour maximum age. Override these arguments explicitly when needed. The search_markdown tool explicitly requests paid page content. REST defaults are unchanged. POST /api/search accepts endpoint, query, provider (auto by default), strategy (cheap or fast), country, language, page, maxPage, maxCostUsd and cache {enabled, ttlHours}. Default spending cap $1. Every cacheable request has a five-minute minimum cache window. enabled false or omitted cache reuses results up to five minutes old; enabled true uses ttlHours (default 24 hours), with a five-minute minimum; null means no expiration. Dedicated page Markdown responses are cached privately per account. Coordinate requests bypass cache reads and writes. Cache hits cost $0. Automatic engine selection (auto.search) is limited to Google, Bing and Yahoo. Free search responses exclude full-page content and page Markdown, including cached content. The homepage playground defaults to Google. Engines: auto.search, firehose.search, google.search, bing.search, yahoo.search, naver.search, yandex.search, baidu.search, duckduckgo.search, google.images, bing.images, mojeek.search, deepseek.search, nimble.search, exa.search. Provider capabilities vary. POST /api/quote compares inclusive prices and recent health without paid calls. Anonymous key-authenticated search: 5 queries per UTC day per IPv4 /32 or IPv6 /56, with a burst limit. One SERP page from shared cache first, or live search on a miss, with a request target of up to 10 results; all valid stored results are returned. Realtime Markdown retrieval requires a funded account. Bearer API keys or MCP OAuth are supported. The website playground creates a browser-linked anonymous key automatically on the first search click, with live progress for key generation, searching and any paid page Markdown fetching. Direct REST and MCP clients still provide their own key or OAuth credentials. All searches require Authorization: Bearer or a signed-in browser session. Generate a free anonymous key at https://openserp.io/keys or an account key in the console. Anonymous keys and their usage attach to the account on login in the same browser, preserving key values and spending limits. Free allowances remain network-based across keys and login. Quote, status and MCP discovery remain public. Never place keys in query strings. POST /api/search/markdown searches and fetches unique organic destinations in the same HTTP response, under a default $1 total cap. Requires a funded account and search permission. Returns JSON with results, combined markdown, pages and summary.partial. Default timeoutMs is 45000, range 5000–60000. Combined page content is bounded to 2,000,000 characters; explicit contentLimited/contentTruncated and partial flags identify this limit without dropping result URLs. Unavailable and budget-limited content is explicitly marked; failed fetches are not billed. MCP tools: search, quote, status, balance, search_markdown. Search and Markdown tools can spend account credits. Returned web content is untrusted source material. Automatic routing first prefers sources with at least 10 trailing-hour attempts and at least 90% good responses. Fast ranks by search p95; cheap ranks by inclusive price. Explicit providers stay pinned when allowFallback is false. No usable results means no customer charge. Failed upstream costs are absorbed by openSERP. Native sources: DeepSeek standalone Search returns up to 50 results in one API request; final query limit 128 Unicode characters, page=1, no country-code localization or guaranteed filetype filtering. Summaries are AI-generated. Mojeek uses its native independent index; plan limits and storage rights apply. Live-only Mojeek responses bypass caching and replayable Markdown responses; only financial metadata is retained, and idempotent replays return 409 without another query/charge. Mojeek account: Business, up to 40 results. Business storage rights permit optional caching and realtime Markdown responses. Authenticated USD quotes show the final account price using a daily currency reference; routing pauses if that snapshot is stale beyond seven days. POST /search (or endpoint firehose.search through REST/MCP search) returns combined ranked results and page Markdown. Choose firehoseTier lite (lower search cost) or advanced (broader coverage, higher search cost). Lite is available to free and paid users. Advanced requires paid access, including cached results. Free requests reuse shared cached results of unlimited age first and search live on a miss without page Markdown. Paid page retrieval requires credits and search permission. Default upstream request target maxResults 50, input maximum 100; all valid unique received results are returned, including extras. timeoutMs 5000–30000; defaults to 25000 (cheap) or 15000 (fast). Provider auto only. Quote a maximum inclusive price before spending. Source composition is managed internally. Partial coverage and per-result contentStatus explicitly identify unavailable content; source content limits may apply. Free queries may choose any engine, including Firehose Lite, with provider auto and automatic routing. Provider selection and fast/cheap routing preferences require credits; free routing preferences are ignored. Inline site:, filetype: and mime: operators restrict Firehose routing to sources that support every requested feature. File-type aliases are translated to each eligible source’s syntax; negated and combined filters are preserved. Unsupported MIME types or a lack of compatible sources return an explicit error before paid searches. Operators inside quoted phrases remain literal text. Pricing: pay as you go with prepaid credits from USD 5. No monthly commitment, subscription or minimum monthly spend. Auto-recharge is optional and off by default. Successful searches and page fetches use the final customer price for the authenticated account. Public listings show standard prices. Authenticate quotes and price feeds to see your own price before spending. Non-paid accounts may choose any engine, including Firehose Lite and auto.search, with provider auto. Routing is automatic and fast/cheap preferences are ignored. Shared caching is always enabled with no maximum age. Client cache settings cannot bypass this policy. Matching cached results cost $0; a cache miss runs a live search within the free allowance. Coordinate searches and page Markdown require credits. The existing network-based daily allowance still applies. Query normalization is shared by REST, MCP, Firehose and realtime Markdown before cache and idempotency hashing: trim and collapse whitespace, remove null/control characters, decode nested percent-encoded UTF-8 and HTML entities, normalize typographic quotes and Unicode NFC. Literal + signs, international joiners/emoji, and percent escapes in visible URLs are preserved. Encoded input may contain up to 24,000 characters; the cleaned query limit is 2,000 characters (128 final Unicode characters for DeepSeek). Empty or excessively nested encoded input returns 400 before upstream work. Active filetype: filters become mime: on Yandex; supported file-type aliases become filetype: on Google and DuckDuckGo. Quoted operators remain literal. Source status and pricing expose trailing-hour search-only medianMs and p90Ms (milliseconds), latencySamples and timeouts. Page Markdown fetching is excluded. Firehose timing stops after search and result merging, before page retrieval. Older combined timings are excluded from percentiles while their outcome history remains. Response meta.latencyMs and meta.searchLatencyMs describe search; pageFetchLatencyMs and totalLatencyMs separately report page retrieval and overall work. Cached Firehose results have null search latency; old combined receipts return null search timing with latencyUnavailableReason legacy_combined_timing. Median averages the middle pair for even sample counts; p90 uses nearest rank ceil(0.9*n). All completed outcomes, including errors and timeouts, are measured; cache hits are excluded. Missing samples are null. Standalone source attempts are capped at 20000 ms within a shared 25000 ms web-search budget or 50000 ms image-search budget. Automatic fallbacks divide the remaining budget. Firehose includes search and Markdown within 25000 ms default, 15000 ms fast, configurable 5000–30000 ms. Realtime Markdown defaults to 45000 ms, configurable 5000–60000 ms, with search up to 25000 ms and each page up to 15000 ms within the remaining deadline. Validation, storage, settlement and response delivery may add HTTP overhead. Timeout documentation: https://openserp.io/docs#timeouts Clear PDF files are retained as search results but excluded from Markdown retrieval. Detection uses URL paths, encoded PDF filenames, download filename parameters and explicit PDF type metadata, without extra target probes. contentStatus skipped_pdf and summary/meta.skippedPdfCount explain exclusions. Known PDFs consume no page-fetch budget or charge, and intentional PDF skips do not make a response partial. Search charges still apply. Full-page Markdown is paid-only, including page content returned from caches or replayed receipts. Anonymous and unfunded accounts cannot use search_markdown or POST /api/search/markdown, and Firehose page Markdown remains paid-only. Free searches return cached SERP results and snippets with full-page Markdown/HTML/text content removed. Sign-in alone does not grant paid access; fresh page fetches require credits and search permission. Result completeness: maxResults is an upstream request target, not a response cap. All valid unique received results and their full titles/snippets are returned, even beyond that target. Firehose returns every merged result; paid page retrieval respects the quoted allowance, deadline and spending cap. Realtime Markdown retains every returned URL with explicit per-page outcomes. Free searches return every result stored in the matching cache, without paid page content. History exports: GET /api/account/exports/payments.csv and GET /api/account/exports/daily-spend.csv stream CSV for the authenticated account only. Requires a browser session or API key with balance permission. All history by default; optional from/to YYYY-MM-DD inclusive UTC dates. Daily spend uses actual wallet debits across all projects/keys, includes zero-spend dates, and retains history beyond the 35-day analytics window. Today is partial through export time. Payments include status, credit reversal amounts and net credited amounts; manual grants are not payments. Responses are private/no-store. Advanced inputs: country/language accept recognized names, native names and codes, normalized before routing/cache/idempotency. USA/U.S./United States of America -> us; GBR/United Kingdom -> gb; English/eng -> en; Français/fra -> fr. Unknown values and conflicting aliases return 400. Common aliases include country_code/gl, language_code/hl, safe_search, time_period, siteSearch, exact_terms, exclude_terms and structured mime. phone -> mobile; past week -> week; on/true Safe Search -> strict. Provider-specific wire formats are applied by adapters, including DDG uk-en and Yandex mime:. Status offerings expose inputCapabilities; routing excludes unsupported source/option combinations. Engine-dependent controls are available in the playground. DataForSEO Google pricing: site:, filetype: and documented keyword operators incur one 5x multiplier per task, including structured filters and combined operators. Quotes multiply the requested depth; actual reported source cost settles within that ceiling. Google Images uses 100-image buckets and its own operator set, including related:. Null or absent source costs use the operator-aware estimate. The Google operator multiplier does not apply to Bing or Yahoo. See /docs#dataforseo-pricing. GET /api/pricing returns public starting prices per search and per 1,000 searches in USD. Authenticated requests use account-specific prices. Prices use the lowest active, configured, verified base source rate. Engine cards and pages show these prices; options, result depth and health routing can increase costs. Firehose uses the minimum combined request, including a page-retrieval allowance; its source composition is private. No connected provider means pricing unavailable. API keys support maxCostUsd per request (default $1, maximum $10), optional dailyLimitUsd and optional totalLimitUsd. Daily and total limits default to null (unlimited); blank/null removes a limit and 0 blocks new paid spending. Daily limits reset at 00:00 UTC and use the settlement day. Lifetime spend persists across limit changes and chart retention. Limits use final actual customer charges. Active reservations count against both allowances, including across midnight, so concurrent requests cannot overspend. Unused reservations are released. Free cache hits, failed work and completed idempotent replays consume no spend; combined search and page retrieval are counted once. Edits apply to new approvals; already approved requests may finish. Existing keys retain unlimited daily/total limits until edited. With balance permission, GET /api/account and MCP balance return the current key’s keyLimits: limits, actual spend, reserved amount, remaining allowances and dailyResetsAt. Insufficient allowance returns 402 key_daily_spend_limit or key_total_spend_limit before paid source calls. Lower maxCostUsd or update the key allowance before retrying. Prices show final customer costs for the authenticated account. Existing completed receipts retain their original charges. Console playground: https://openserp.io/dashboard/playground (signed-in account). Google by default, current balance, supported advanced controls, separate free quotes and paid execution, realtime Markdown, per-request deadlines and idempotency keys. Copy cURL, JavaScript, TypeScript, Python, Go, PHP, Ruby, C#, JSON or MCP samples from current settings. Samples contain environment-based API key placeholders and no session credentials. Console session requests have a $1 maximum; free accounts keep cache-first automatic routing and the free daily allowance. Automatic source selection (provider: auto) always retries other sources within the chosen engine using the cheap or fast strategy, even when allowFallback is false. It never switches engines after selection. auto.search initially chooses Google, Bing or Yahoo, then keeps that engine. With an explicit provider/offering, allowFallback false pins one source and one attempt; true (default) permits other sources and compatible engines, preferring viable same-engine sources. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Up to three attempts share the deadline and spending cap; operators, locale and output constraints stay enforced. Compatible web alternatives are Google, Bing and Yahoo; images stay on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with same-engine source retries. Failed work is absorbed; only successful delivered work is charged. Quotes report the effective allowFallback policy, maximumAttempts and eligible routes. Responses report requestedEngine, requestedProvider, actual engine/provider, fallbackUsed and fallbackReason. Existing completed idempotent receipts keep their original results and charges. Firehose tiers: firehoseTier is lite or advanced, with lite used when omitted. Lite is available to free and paid accounts. Advanced requires paid access, including cached results. Lite is the lower search-cost combination; Advanced retains broader coverage at higher search cost. Tier caches and quotes are separate. GET /api/pricing includes a tiers array with both starting rates; source composition stays private. Free Firehose supports a request target up to 100 (default 50), while other free engines use up to 10. All stored results are delivered. Firehose ranking: Lite is the default coverage tier. Results are re-ranked against the input query using title/snippet relevance, weighted source priority, cross-source agreement and domain diversity. Advanced adds coverage. Composition and weights are private. The legacy firehoseTier value default remains an alias for lite. New combinations use fresh cache identities; completed older requests retain their original idempotent receipts without another charge. Playground defaults: results only, shared cache enabled, 24-hour cache TTL for paid searches. Firehose supports pageMarkdown:false to skip page fetching and page charges; pageMarkdown:true adds paid full-page Markdown, cost and response time. Omitted paid Firehose API requests include Markdown for compatibility. Free requests exclude page content and use unlimited-age shared cache. All published REST and MCP search, quote and Markdown examples explicitly send cache {enabled:true, ttlHours:24}, matching the playground’s checked cache option. Free-account requests retain unlimited-age shared caching. Result URLs: advertising click destinations are excluded from organic results. Known campaign/click parameters are removed before merging and delivery; functional parameters, signed URLs and application hash routes are preserved. Trailing slash variants deduplicate. Equivalent destinations are grouped across sources and returned as alternate_urls. The same cleanup applies to shared caches and completed replays without a new query or charge. Payment-exempt accounts need no credits and cannot start checkout or auto-recharge. Responses distinguish usageValueUsd (normal service value), chargedUsd (actual deduction) and waivedUsd. Successful exempt live work is valued but charged $0. Cache hits add no value; idempotent replays count once. Key spend limits use actual charges. Older unvalued requests are identified explicitly. Daily spend CSV appends usage_value_usd, waived_value_usd and unvalued_requests. Firehose status and pricing use separate Lite and Advanced entries in GET /api/status. Each tier has its own final starting query price, seven-day outcome chart, trailing-hour success rate, search-only median and p90 latency, and timeout policy. Authenticate for account-specific prices. Historical responses without an explicitly recorded tier are excluded from tier metrics and counted separately; page fetching and cache hits do not inflate search measurements. Bing organic result quality: responses containing at least 10 valid unique results are rejected as invalid when none of their titles, snippets or URLs match any meaningful positive query keyword. Matching ignores case and accents, common words and filter operators. Failed responses are not billed; allowFallback can try another compatible source or engine. Cached Bing responses undergo the same check before reuse. See the reliability notice at https://openserp.io/bing. Late cache recovery: Already-started paid source calls may continue up to 25000 ms beyond their foreground deadline or client disconnect. Valid late search results use the shared cache; page Markdown stays private to the account. No extra customer charge or usage value. No new source or page work starts after disconnect. Empty/invalid/failing responses, coordinates and storage-restricted sources are not cached. Retry with a new idempotency key; original receipts remain unchanged. Status keeps foreground timeout outcome/latency and records source expense once. No queued search jobs. Anonymous retention: Unclaimed browser accounts and API keys expire 30 days after the first key is created. Additional keys do not extend expiry. Sign in in the original browser before expiry to retain keys and attach usage history. expiresAt is a millisecond timestamp in anonymous account/key responses. Expired keys return 401. Cleanup removes accounts, key hashes, sessions, projects and private receipts; aggregate usage and source expense remain under the read-only Historic anonymous usage account. Claimed and signed-in accounts retain their keys and history. Shared-cache and network free-quota policies are unchanged. Opaque /goto links are retained as successful search results, including responses containing only those links. They do not count as invalid results and use the normal query charge. Readable redirect destinations are still unwrapped; advertising and unsafe URLs remain filtered. MCP installation: At https://openserp.io/docs/mcp, Copy setup and Copy agent instructions automatically generate and include an API key. Signed-in users receive an account key. Anonymous browser keys and usage attach after login/account creation in that browser within 30 days of the first key; key values and limits remain valid. Repeated copies on the same page validate ownership and reuse the key. New setup keys: search/balance scopes, $1 per request, $5 daily, $20 lifetime; manage at /keys. Static downloads use YOUR_API_KEY placeholders. Setup keys stay in page memory only, never URLs or persistent browser storage. ## REST integration guide Source: https://openserp.io/docs ### Make a search request Send JSON to `POST https://openserp.io/api/search`. Generate a free API key at [openserp.io/keys](https://openserp.io/keys) without signing up, and send it as `Authorization: Bearer YOUR_API_KEY`. All search requests require a key or a signed-in browser session. The website playground creates and connects an anonymous key automatically on your first Run click; there is no manual setup before searching. Your anonymous keys, projects and usage attach automatically when you sign in in the same browser; the key stays valid and its spending limits are preserved. Choose any engine, including Firehose Lite and `auto.search`, with `provider: auto` for the free allowance. Routing is automatic; free requests ignore fast/cheap preferences. Shared caching is always enabled with no maximum age. Client cache settings cannot bypass this policy. Matching cached results cost $0; a cache miss runs a live search within the free allowance. Coordinate searches and page Markdown require credits. The existing network-based daily allowance still applies. Provider selection and fast/cheap routing preferences require a funded account. Free live searches use the daily allowance. Keep keys server-side in your applications. Quotes, status and MCP tool discovery remain public. ``` curl https://openserp.io/api/search \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Idempotency-Key: my-search-001' \ -d '{"endpoint":"google.search","query":"Cloudflare Workers","strategy":"cheap","maxCostUsd":"1","cache":{"enabled":true,"ttlHours":24}}' ``` `auto.search` selects only Google, Bing or Yahoo, using compatible sources and the same health and routing preferences. Free responses include search metadata and snippets; full-page content and page Markdown are excluded, including content already in shared cache. The homepage playground starts with Google. #### Search parameters | Parameter | Meaning | | --- | --- | | endpoint / engine | auto.search, firehose.search, google.search, bing.search, yahoo.search, naver.search, yandex.search, baidu.search, duckduckgo.search, google.images, bing.images, mojeek.search, deepseek.search, nimble.search, exa.search | | query / q | Search text, up to 2,000 characters | | provider | auto, provider ID or exact offering ID | | strategy | cheap or fast; eligible healthy sources preferred | | country / language | Source-supported locale parameters | | page / maxPage | Bounded pagination, from 1 to 10 | | maxCostUsd | Hard customer spending cap; default 1 USD | | cache | API and MCP examples send enabled: true with ttlHours: 24. Every cacheable request has a five-minute reuse window, including enabled: false and omitted cache. Enable caching to reuse older results up to ttlHours; values below five minutes use five minutes. Dedicated full-page Markdown response caches are private to the account. Use ttlHours: null for no expiration. Free accounts always use shared cache at unlimited age | Use each engine page for source-specific options. Unsupported parameter combinations are rejected before a provider is called. Requests containing coordinates bypass cache reads and writes. ### Result URLs and alternatives Opaque /goto links are retained as successful search results, including responses containing only those links. They do not count as invalid results and use the normal query charge. Readable redirect destinations are still unwrapped; advertising and unsafe URLs remain filtered. Organic results exclude advertising click URLs, including DuckDuckGo sponsored redirects. Known campaign and click-tracking parameters are removed before merging and delivery. Functional parameters, repeated query values, signed URLs and application hash routes are preserved. Trailing-slash variants are treated as the same destination when merging. When a source supplies equivalent destinations, results include an `alternate_urls` array of cleaned alternatives. Equivalences are used across engines, including transitive groups, while unrelated pages remain separate. Cached results and completed replays receive the same cleanup without another source request or change to the recorded charge. ### Bing result quality Bing may return unrelated results across providers despite a successful upstream response. Organic lists of 10 or more valid unique results are rejected when no title, snippet or URL matches a meaningful positive query keyword. Common words, filter syntax and excluded terms do not satisfy the check; case and accents are normalized. These responses count as invalid source failures, are not billed, and can trigger compatible fallback when enabled. Cached Bing results undergo the same check before reuse. See the [Bing reliability notice](https://openserp.io/bing#bing-quality-notice). ### Query normalization REST, MCP, Firehose and realtime Markdown requests share query cleanup before routing, cache lookup and idempotency checks. Leading and trailing whitespace is trimmed, whitespace runs become spaces, control and null characters are removed, HTML entities and percent-encoded UTF-8 are decoded, and typographic quotes become straight quotes. International text, emoji, literal plus signs and percent escapes within visible URLs are preserved. For example, `Cloudflare%2520%26quot%3BWorkers%26quot%3B` becomes `Cloudflare "Workers"`. Active `filetype:pdf` becomes `mime:pdf` on Yandex. Supported file-type aliases use `filetype:` on Google and DuckDuckGo. Full MIME types such as `application/pdf` are mapped to extensions. Operators inside quoted phrases remain literal text. The final cleaned query is limited to 2,000 characters; encoded input may contain up to 24,000 characters. Up to four nested encoding layers are cleaned. Empty queries, excessive encoding depth, unsupported file-type operators and oversized cleaned queries return a 400 error before upstream work. Native source limits still apply. Equivalent cleaned queries share cache and idempotency semantics. ### Firehose: Lite and Advanced The playground defaults to results only, with shared caching enabled and a 24-hour maximum cache age for paid searches. Select page Markdown to fetch full result pages; this increases cost and response time. On Firehose, send `pageMarkdown: false` for results only or `pageMarkdown: true` for paid page Markdown. Omitted paid API requests retain page Markdown. Free requests always exclude page content and use unlimited-age shared cache. Set `firehoseTier` to `lite` (the default, lower search cost) or `advanced` (broader coverage at higher search cost). Lite is available to free and paid users. Advanced requires paid access, including cached results. Free requests reuse shared cached results of any age first, then search live on a miss without page Markdown. Each tier has separate cache entries and starting prices. Your agent’s intelligence shouldn’t be limited by access to information. Send `POST /search`, or use `endpoint: firehose.search` with `/api/search` or the MCP search tool. Firehose Lite is available to free users; Advanced requires paid access, including cached results. Live searches are included in the free allowance; page Markdown requires credits and search permission. Firehose combines parallel searches, deduplicates destinations and ranks by relevance, agreement and domain diversity. Its source composition is managed internally. Firehose returns `organicResults`, combined `markdown`, per-result `contentStatus` and an explicit `partial` flag. The default upstream request target is 50, with an input maximum of 100. Every valid unique result received is returned, including extras above this target. The default deadline is 25 seconds, or 15 seconds with fast routing. Set `timeoutMs` between 5,000 and 30,000. Extra results remain in the response even when the quoted page-fetch allowance is exhausted; their content status is explicit. Use a quote and a sufficient `maxCostUsd` before starting. Firehose manages routing; provider pinning and pagination are unsupported. Firehose Lite and Advanced have separate source-status entries, starting query prices, seven-day outcome charts and trailing-hour search-only median/p90 latency. Authenticate to see your account’s final prices. Earlier responses without an explicitly recorded tier are excluded from the tier charts and counted separately. #### Search operators Inline site:, filetype: and mime: operators restrict Firehose routing to sources that support every requested feature. File-type aliases are translated to each eligible source’s syntax; negated and combined filters are preserved. Unsupported MIME types or a lack of compatible sources return an explicit error before paid searches. Operators inside quoted phrases remain literal text. ### Console playground Open [Playground](https://openserp.io/dashboard/playground) beside Sign out in the console. It uses your signed-in account and current balance, with Google selected initially. Build a request with supported advanced controls, compare inclusive prices without a paid search, and run results or realtime Markdown. Copy the current request as cURL, JavaScript, TypeScript, Python, Go, PHP, Ruby, C#, JSON or an MCP tool call. Samples use your own API key through an environment variable; account cookies and key secrets are never embedded. Console searches are limited to $1 per request. View results, JSON and Markdown, and copy or download responses. Editing request settings generates a fresh idempotency key; repeating an unchanged request replays the completed response without another charge. A new request ID starts new work. Advanced controls, region defaults, Markdown access and source routing follow the chosen engine and your account access. ### Account access and fallback Search pages and both playgrounds recognize your signed-in session and show your account balance. Funded accounts can select a source, routing preference and full-page Markdown; successful live work is charged to that account. Account state refreshes when returning from sign-in or a top-up, restoring a page, changing tabs and before submitting a request. Unfunded accounts retain cache-first search with live results on a miss. Automatic source selection (`provider: auto`) always retries other sources within the chosen engine, preserving the cheap or fast strategy. It never changes engines after selection, even if `allowFallback` is false. `auto.search` chooses its initial engine from Google, Bing or Yahoo, then keeps all retries on that engine. With a specific provider or offering selected, `allowFallback: false` makes one attempt on that source. With `allowFallback: true` (the default), other sources and compatible engines are eligible; viable sources on the same engine come first. Sources with at least ten attempts and less than 90% success in the trailing hour remain deprioritized. Up to three attempts share the deadline; filters, operators, locale and spending caps stay enforced. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. The playground’s fallback checkbox applies when a specific source is selected. Automatic cheap/fast routing and Firehose always retry sources within each selected engine. Free requests reuse shared cache first and search live on a miss with the same managed source retry policy. Quotes mark fallback candidates. Responses identify the requested and actual engine/source with `requestedEngine`, `requestedProvider`, `fallbackUsed` and `fallbackReason`. Failed work is absorbed; only a successful delivered response is charged, under the request and API-key limits. Cache hits remain free. Default-true requests preserve existing receipt and shared-cache identities. ### Engine-dependent advanced inputs The playground’s Advanced search options reflect the chosen engine and source. Depending on support, choose interface language, result language, country restriction, location, search domain, device, Safe Search, freshness, pagination, result target, site, exact phrase, excluded phrase and file type. Automatic routing excludes sources that cannot honor every selected option; unsupported values are rejected before spending. Country names, native names and ISO codes normalize to one country code: `USA`, `U.S.`, `United States` and `United States of America` become `us`. `GBR` and `United Kingdom` become `gb`; `Deutschland` becomes `de`. The old fallback that silently replaced unrecognized countries with the US is removed from validated searches. `English` and `eng` become `en`; `French`, `Français` and `fra` become `fr`. Regional spellings such as `en-US` use the base language; Simplified and Traditional Chinese retain `zh-cn`/`zh-tw` when supported. Locale inputs use a pinned Unicode CLDR name/code snapshot, with no external lookup per request. Aliases such as `country_code`/`gl`, `language_code`/`hl`, `safe_search`, `time_period`, `siteSearch`, `exact_terms`, `exclude_terms` and structured `mime` map to canonical inputs. `phone` becomes `mobile`, `past week` becomes `week`, and `on`/`true` becomes strict Safe Search. Conflicting aliases return 400. Structured file types accept extensions or supported MIME types and use each engine’s query syntax. Native limits still apply, including DeepSeek’s final query length and engines that cannot accept locale or advanced filters. ### Compare prices before spending `POST /api/quote` accepts the same parameters and returns eligible offerings, inclusive prices, source timeouts, median latency and p90 latency. A quote itself makes no paid search request. Cache hits are free. Live quotes show the final customer price for the authenticated account. Sign in or send your API key to obtain your account’s prices; unauthenticated price listings show standard prices. Completed requests keep their original recorded value and charge. ### DataForSEO operator pricing Standard-account DataForSEO Google searches start at $0.00256 per requested results page at the configured Live rate. Keyword operators such as `site:`, `filetype:`, `inurl:` and `intitle:` multiply that rate by five, once per task, including queries that combine operators. Structured site/file-type inputs and normalized encodings use the same pricing rule. For a standard account, one page with these operators quotes $0.0128; three pages quote a maximum of $0.0384. Account-specific prices may differ; authenticate when requesting a quote. Plain queries retain the base rate even when the rich-result adapter is selected. Google Images has its own operator rules and bills in 100-image depth buckets. Its `related:` operator also incurs the surcharge; unsupported `cache:` image queries are excluded before dispatch. The Google operator surcharge is not applied to Bing or Yahoo. Quotes and responses expose `operatorMultiplier`, `surchargeOperators` and the pricing policy version. Settlement uses DataForSEO’s reported task cost, including lower actual depth costs, with the quote as a hard ceiling. A missing or null reported cost uses the same operator-aware estimate as the quote. No usable result means no customer charge. [DataForSEO Google Live documentation](https://docs.dataforseo.com/v3/serp/google/organic/live/advanced/) and [Google Images documentation](https://docs.dataforseo.com/v3/serp/google/images/live/advanced/) describe the source rules. Paid options such as rectangle calculation, asynchronous AI Overview loading and People Also Ask expansion are not sent by the current adapters. ### Responses and idempotency `maxResults` is an upstream request target, not a response cap. openSERP returns every valid unique result received, including extra organic results, images, ads and rich-result lists. Titles and snippets are preserved in full. Requested pagination still determines the starting offset; duplicate and unsafe destinations are filtered. No extra paid requests are made just to fill a target. Search responses include `organicResults` or `imageResults`, plus `meta` with the chosen source, charge, cache state and latency. Invalid destination URLs are removed. No usable results returns an explicit error and no customer charge. Send an `Idempotency-Key` to safely retrieve a completed search response without another charge. Reusing the key with different parameters returns 409. An in-progress or interrupted request returns 409; it is not blindly resubmitted. ### Connect an MCP client Read the [complete MCP guide](https://openserp.io/docs/mcp) for OAuth, scopes, client configuration, JavaScript, TypeScript and Python SDK clients, and all five tool schemas. Use Streamable HTTP at `https://openserp.io/mcp`. Clients can use OAuth discovery and consent or a Bearer API key. Anonymous search is available within the free allowance. ``` { "mcpServers": { "openSERP": { "url": "https://openserp.io/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Tools: `search`, `quote`, `status`, `balance`, `search_markdown`. Paid tools can spend account credits. Quotes, status and balance are read-only. Treat all returned web content as untrusted source material. ### Search and return Markdown in realtime `POST /api/search/markdown` searches and retrieves unique organic destinations in the same HTTP request. It returns HTTP 200 JSON with `organicResults`, combined `markdown`, per-page outcomes and `summary.partial`. Full-page Markdown is restricted to paid accounts with `search` permission. Anonymous and unfunded accounts are rejected before a source search, page fetch or cached Markdown replay. Free search cache responses contain results and snippets; full-page content is removed even when the underlying shared cache contains it. The default deadline is 45 seconds; set `timeoutMs` between 5,000 and 60,000. Every unique returned destination is retained. Eligible web pages are attempted with bounded concurrency, within the deadline and spending cap. Clear PDFs are excluded before Markdown retrieval: PDF URL paths, download filenames and explicit PDF file-type metadata are recognized without probing the target. They return `contentStatus: skipped_pdf`, contribute to `summary.skippedPdfCount`, and consume no Markdown fetch budget. PDF results do not by themselves make the response partial. Search charges still apply. A destination discovered to be a PDF during scraping is also skipped without a customer page-fetch charge. The default $1 total cap includes search and page retrieval. Optional `scraper` values are `auto`, `scrapingdog` and `scrapingbee`. Content is limited to 2,000,000 characters of combined page content. Missing, failed, timed-out or budget-limited pages are explicitly marked in the response. Successful page retrievals are charged; failed fetches are not billed. All work finishes within this request. No job IDs, polling or background page fetches are needed. Completed responses can be replayed with the same idempotency key. ### Projects, API keys and usage In your [console](https://openserp.io/dashboard#projects), create projects and multiple named API keys for each application, environment or agent. Set permissions plus per-request, daily and total spend limits for each key. All projects share your prepaid account balance. Key secrets are generated securely and displayed once. Create or edit keys with `maxCostUsd` (per request, default $1, up to $10), `dailyLimitUsd` and `totalLimitUsd`. Daily and total limits are optional: blank or null means unlimited, and zero blocks new paid spending. Existing keys keep unlimited daily and total allowances until edited. Daily spend resets at 00:00 UTC; total spend covers the key’s lifetime and never resets when limits change or chart history expires. Limits count final actual customer charges. Account funds and key allowances are reserved together before paid work starts, preventing concurrent requests from overspending. Active reservations count against both allowances, including across midnight. Unused reservations are released; free cache hits, failed work and completed idempotent replays add no spend. Daily charges count on the UTC day of settlement. A limit edit applies to new approvals; already approved requests can finish. Search and page retrieval share one combined limit for Markdown and Firehose. The key list shows daily/lifetime usage and reserved spending. An API key with balance permission can inspect its own limits, spend, remaining allowance and next UTC reset through `GET /api/account` or MCP `balance` in `keyLimits`. Insufficient daily or total allowance returns 402 with `key_daily_spend_limit` or `key_total_spend_limit` before any paid source call. Lower the request cap or adjust the key’s allowance before retrying. Compare searches, actual charges and unsuccessful results across keys over 24 hours, seven days or 30 days. Filter by project or one key. Cache hits count once and cost zero; upstream retries and idempotent replays do not add queries. Search and Markdown requests keep their originating key attribution. Revoked keys remain in usage history. Per-key tracking starts when this feature was enabled; older requests are not retroactively attributed. REST and MCP both use the project associated with the supplied API key. Project names do not need to be added to search requests. Key and project management and account-wide analytics require a signed-in console session. ### Anonymous account retention Anonymous browser accounts and their keys expire 30 days after the first key. Sign in in the original browser before expiry to claim the keys and usage history. Creating extra keys does not reset the deadline. Anonymous account/key responses expose `expiresAt` in milliseconds since epoch. Unclaimed expired keys return 401; the playground can automatically create a new browser key within the existing network issuance and search quotas. Scheduled cleanup removes the old account, keys and private receipts while retaining anonymous aggregate statistics under Historic anonymous usage. Claimed and signed-in account keys keep their existing lifetimes. ### Authentication and credits Sign in with Google or GitHub. Generate API keys in your console; raw keys appear once. Keys use search and balance scopes with per-request, daily and lifetime spending controls. Revoke keys and OAuth connections from your account. Credit purchases start at $5. A successful, verified Stripe webhook updates your balance; the browser’s success redirect never does. Refunds and disputes reconcile the credited amount. Negative balances pause paid usage. Auto-recharge is optional and requires explicit consent. ### Native Mojeek and DeepSeek searches Use `mojeek.search` or `deepseek.search` with the normal REST or MCP search interface. DeepSeek returns up to 50 results for one source request, with a 128-character final query limit and no pagination or country-code filter. Its summaries are AI-generated and may contain errors. Mojeek Business returns up to 40 results; country and language parameters boost results. USD prices use a dated currency reference, refreshed daily. Request a quote for your account’s final price. Unsupported native parameters are rejected before a paid call. Mojeek accounts without verified storage rights bypass result caches and retain only financial metadata. Idempotent replays return 409 without another query or charge; replayable Markdown responses require verified storage rights. Source status shows any pricing still awaiting account verification. ### Payment and daily spend exports In your [account dashboard](https://openserp.io/dashboard), use **Export your history** to download payment history or daily spend as CSV. All history is included by default; turn off All history to choose inclusive UTC dates. `GET /api/account/exports/payments.csv` includes top-ups, auto-recharges, recorded payment status, credit reversals and net credited amounts. `GET /api/account/exports/daily-spend.csv` totals actual wallet charges by UTC day across every project and key, including zero-spend dates. Wallet history remains available beyond the 35-day operational analytics window. Credits, reservations and upstream expenses are excluded from daily spend; today is partial through the export timestamp. Both endpoints accept optional `from=YYYY-MM-DD` and `to=YYYY-MM-DD`. They require a signed-in account or an API key with `balance` permission and always export that account only. CSV downloads stream in the current request and use private, no-store responses. ### Timeouts & latency Source status and pricing charts publish the current work budgets alongside measured median and p90 search latency. Page Markdown fetching is excluded from these measurements. REST quotes and MCP status/quote responses expose the same values in milliseconds. | Operation | Work budget | How it applies | | --- | --- | --- | | Standalone source attempt | Up to 20 seconds | Automatic fallback attempts share the remaining search budget and can receive a shorter limit. | | Web search | 25 seconds | Shared by source attempts and pagination; selecting a provider does not reset the budget. | | Image search | 50 seconds | Shared by source attempts and image pagination; each standalone attempt still has a 20-second cap. | | Firehose search + Markdown | 25 seconds default; 15 seconds for fast routing | Set timeoutMs from 5,000 to 30,000. Search and page retrieval share one deadline. A content phase is reserved from this budget; partial coverage is explicit. | | Realtime Markdown | 45 seconds default | Set timeoutMs from 5,000 to 60,000. Search gets up to 25 seconds and each page fetch up to 15 seconds, always within the remaining deadline. | Budgets cover upstream work. Input validation, account checks, storage, settlement and response delivery can add overhead to total HTTP duration. Cached requests make no source call. Failed or timed-out attempts do not produce a customer charge unless other successful work is delivered; costs stay within the quoted cap. After the response deadline or a client disconnect, already-started paid source calls may continue for up to 25 additional seconds. Valid late search results populate the shared cache; late page Markdown is cached privately per account. No new search or page calls are started after disconnect, and late work adds no customer charge or usage value. Invalid, empty and failed results are not cached. Coordinate queries and source storage restrictions remain excluded. Retries use a new idempotency key to read newly cached results; the original response and receipt remain unchanged. This uses bounded background completion, with no search jobs or polling. Status retains the foreground timeout outcome and latency while recording the actual source expense once. Search latency uses completed search attempts in the trailing hour, including good, error, empty and invalid responses. Cache hits and client validation errors are excluded. Median is the middle value, or the mean of the middle pair for an even sample count. P90 uses the nearest rank, ceil(0.9 × sample count); 90% of samples are at or below it. No samples are shown as an em dash in charts and null in JSON. Firehose search timing stops after parallel searches finish and results are merged, before page retrieval. Older combined timings are excluded from percentiles while their outcome history is retained. The `latencySamples` count can therefore differ from the outcome count. Response `meta.latencyMs` and `meta.searchLatencyMs` report search only; `meta.pageFetchLatencyMs` and `meta.totalLatencyMs` describe page retrieval and the overall operation separately. Cached Firehose results have no live search latency. Older combined receipts expose null search timing with `latencyUnavailableReason: legacy_combined_timing`. The seven-day bars remain hourly outcome counts. Realtime Markdown retains every result and URL even when page retrieval is incomplete. The old 20,000-character per-page cutoff is removed. Individual scraper responses are bounded to 2 MB and combined Markdown page content to 2,000,000 characters. `contentTruncated`, `contentStatus: response_size_limit`, `summary.contentLimited` and `summary.partial` identify a size limit explicitly. These content safeguards never shorten the result list. ### Source health `GET /api/status?engine=google.search` returns 168 hourly buckets, trailing-hour medianMs and p90Ms, sample counts and published timeout policies. p95Ms remains available for existing clients. Good, error, empty and invalid outcomes refer to completed upstream attempts. Healthy requires at least ten samples and at least 90% good results. Fast mode ranks sources by search-only p95 latency, using configured baseline latency when no timing sample is available; cheap mode ranks by the final user price. Explicit provider selection remains pinned when `allowFallback: false`. Automatic retries use separate provider accounts and share the request deadline. Healthy sources are attempted first; if preferred sources fail, a degraded fallback can return results with an explicit routing warning. ### Payment-exempt accounts and usage value Payment-exempt accounts have full search access without credit purchases or automatic payments. Successful live work records its service value at its account price in `meta.usageValueUsd`, the amount charged in `meta.chargedUsd`, and the waived amount in `meta.waivedUsd`. Their wallet charge is $0. Cached results have zero new usage value; idempotent replays preserve the original value without adding it again. Failed work is absorbed. Usage value follows the account price in effect when the request was approved. Key spend limits and balances continue to measure actual charges. The console and admin account list show service value beside actual charges; daily CSV exports append usage_value_usd, waived_value_usd and unvalued_requests. Older values without enough original pricing evidence are marked incomplete rather than estimated. ### Realtime playground progress The playground automatically connects a browser key on the first search click and displays key generation, searching and page Markdown fetching when applicable. Search requests may opt into `Accept: application/x-ndjson` for progress frames and one final `type: result` frame containing the ordinary response in `data`. A terminal `type: error` frame includes `status`, `error` and `message`; an error after streaming starts cannot change the HTTP status. Key authentication and browser origin checks still happen before streaming. JSON remains the default. There are no queued search jobs or progress-polling requests. ### Errors 400: invalid input; 401: sign-in or valid key required; 402: insufficient balance or spending cap; 403: missing permission; 409: idempotency conflict; 429: quota or burst limit; 503: no eligible source or incomplete setup. Financial and private responses use no-store caching. ## Copy-paste MCP client setup # Install openSERP MCP Open https://openserp.io/docs/mcp, choose your client and click **Copy setup**. The website generates and includes your key automatically, linked to your signed-in account or attached when you sign in or create an account in the same browser within 30 days of your first key. Repeated copies on the page reuse the key. New setup keys have search/balance permissions and $1 per-request, $5 daily and $20 total limits; manage these at https://openserp.io/keys. The static configurations below use placeholders. Search and quote default to **Firehose Lite**, results only, with **shared cache enabled and a 24-hour maximum age**. Free searches use unlimited-age cache first and search live on a miss. Existing key limits and network allowances apply. ## Codex CLI Paste into your terminal and start Codex from that terminal. Replace YOUR_API_KEY with your key. ```sh export OPENSERP_API_KEY='YOUR_API_KEY' codex mcp add openSERP --url https://openserp.io/mcp --bearer-token-env-var OPENSERP_API_KEY codex ``` In Codex, run /mcp and check that openSERP is connected. Official docs: https://developers.openai.com/codex/mcp ## Codex app / IDE Merge this table into ~/.codex/config.toml. Keep other settings, then reload your MCP connections or restart the app. Replace YOUR_API_KEY with your key. ```toml [mcp_servers.openSERP] url = "https://openserp.io/mcp" http_headers = { Authorization = "Bearer YOUR_API_KEY" } tool_timeout_sec = 65 ``` Open MCP settings and check that openSERP is connected. Official docs: https://developers.openai.com/codex/mcp ## Claude Code Paste into your terminal. The command adds openSERP to your private user configuration for all projects. Replace YOUR_API_KEY with your key. ```sh claude mcp add --transport http --scope user openSERP https://openserp.io/mcp \ --header 'Authorization: Bearer YOUR_API_KEY' ``` Start a new Claude Code session and run /mcp to check openSERP. Official docs: https://code.claude.com/docs/en/mcp ## Cursor Merge this entry into ~/.cursor/mcp.json. Keep any existing mcpServers entries. Replace YOUR_API_KEY with your key. ```json { "mcpServers": { "openSERP": { "url": "https://openserp.io/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Open Cursor Settings → Tools & MCP (or Customize → MCP), enable openSERP and check its tools. Official docs: https://cursor.com/docs/mcp ## VS Code Merge this entry into your VS Code user MCP configuration. Run MCP: Open User Configuration from the Command Palette, then add the entry. Replace YOUR_API_KEY with your key. ```json { "servers": { "openSERP": { "type": "http", "url": "https://openserp.io/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Run MCP: List Servers and start openSERP. Official docs: https://code.visualstudio.com/docs/agents/reference/mcp-configuration For Codex CLI, make OPENSERP_API_KEY available each time you launch it. For GUI clients, use the client’s local configuration above. Merge entries with existing settings. Keep key-containing configurations private. ## Test the connection Use openSERP to quote a search for “Cloudflare Workers documentation”. Use the default Firehose Lite, results only, with shared cache enabled for 24 hours. Show the quote without running a search. ## Ask your agent to install Connect openSERP to this MCP client using Streamable HTTP at https://openserp.io/mcp. Name the server openSERP and preserve my existing MCP servers and settings. Read https://openserp.io/docs/mcp for this client’s configuration. Search defaults to Firehose Lite, results only, with shared cache enabled for 24 hours. Use my openSERP API key through the client’s local credential configuration; do not ask me to paste the key into chat. If I need a key, direct me to https://openserp.io/keys. Verify MCP initialization and tools/list, then call quote for “Cloudflare Workers documentation” without a paid search. Do not switch to Advanced or fetch page Markdown unless I ask. ## MCP integration guide Source: https://openserp.io/docs/mcp ### Ready-to-use defaults MCP search and quote default to **Firehose Lite** (`firehose.search`, `firehoseTier: lite`). Search returns results and snippets without fetching full pages. Shared cache is enabled by default with a 24-hour maximum age for paid accounts; free accounts use unlimited-age cache and search live on a miss. Choose an engine, Advanced, or paid page Markdown explicitly when you need them. [Download all client configurations](https://openserp.io/downloads/openserp-examples.zip) in the examples bundle under `mcp/configs`, or [read the copy-paste installation guide](https://openserp.io/mcp-install.md). ### Your key is included Click **Copy setup** above to generate an API key and include it in your client configuration automatically. Signed-in visitors get an account key. Without a login, the key is linked to this browser; sign in or create an account here within 30 days of your first key to attach your keys and usage. The same key keeps working after login. Repeated copies on this page reuse the key after checking its ownership. New setup keys have search and balance permissions with a $1 per-request, $5 daily and $20 total spending limit. Manage or revoke keys and change limits at [openserp.io/keys](https://openserp.io/keys). The preview hides your key; keep copied configurations private. Search tools require a key or account OAuth. Public quote, status and tool discovery need no credentials. Firehose accepts `firehoseTier: lite` for lower search cost or `firehoseTier: advanced` for broader coverage at higher search cost. Lite is available to free and paid accounts. Advanced requires paid access, including cached results. Page Markdown requires credits. Free live searches use the daily allowance. Choose any engine, including Firehose Lite and `auto.search`, with `provider: auto` for free shared cached queries with unlimited age. Routing is automatic; free requests ignore fast/cheap preferences. Cache misses run a live search within the free allowance. Provider selection and routing preferences require a funded account. Free live searches use the daily allowance. `firehose.search` returns combined ranked results within one deadline and spending cap; add page Markdown explicitly for paid content retrieval. Its source composition is managed internally. `auto.search` selects only Google, Bing or Yahoo, using compatible sources and the same health and routing preferences. Free responses include search metadata and snippets; full-page content and page Markdown are excluded, including content already in shared cache. The homepage playground starts with Google. ### Other MCP clients and OAuth Server URL: `https://openserp.io/mcp`. Add a remote HTTP server in your MCP client. Use its OAuth sign-in flow or a Bearer API key stored with the client’s secret/environment mechanism. ``` { "mcpServers": { "openSERP": { "type": "http", "url": "https://openserp.io/mcp" } } } ``` This configuration uses the portable `mcpServers` format supported by compatible Copilot clients. VS Code’s Local harness uses `servers` instead. The bundle includes both formats and an environment-based API-key variant. Other clients have their own schemas. Start with `quote` or `status`. Search and Markdown tools can spend prepaid credits. Pass `maxCostUsd` explicitly and use a scoped key with suitable per-request, daily and lifetime limits. Examples use a $0.01 cap; the service default when omitted is $1. ### Five tools | Tool | Purpose | Access and cost | | --- | --- | --- | | `quote` | Compare prices, median/p90 search latency and source timeouts | Public; free | | `status` | Hourly outcomes, median/p90 search latency and timeouts | Public; free | | `search` | Synchronous organic or image search | API key required; free allowance or prepaid balance | | `balance` | Read balance and key spending allowances | balance scope; read-only | | `search_markdown` | Fetch full-page Markdown in realtime · paid only | Funded account, search scope; may charge | Discover current inputs with `tools/list`. Search arguments include `endpoint`, `query`, `provider`, `strategy`, `maxResults`, `maxCostUsd` and cache options. Use engine identifiers such as `bing.search`. Status accepts an optional engine. ### Search with shared cache The MCP examples enable shared caching with a 24-hour maximum age, matching the playground default. Free accounts use unlimited-age shared cache. All cacheable requests have a five-minute minimum reuse window. Setting `cache.enabled: false` limits reuse to five minutes; shorter TTLs also use five minutes. Complete dedicated page Markdown responses are cached privately for the account. Cache hits cost $0. ``` { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "search", "arguments": { "endpoint": "firehose.search", "firehoseTier": "lite", "pageMarkdown": false, "query": "Cloudflare Workers", "maxCostUsd": "0.01", "cache": { "enabled": true, "ttlHours": 24 } } } } ``` ### JavaScript and TypeScript Unpack the [examples bundle](https://openserp.io/downloads/openserp-examples.zip) and run from its root with Node.js 24 or later. It pins the MCP client SDK and includes TypeScript source plus generated JavaScript. ``` npm ci node mcp/client.mjs list node mcp/client.mjs quote node mcp/client.ts search --dry-run ``` ### Python The optional Python MCP client uses a separate environment and Python 3.11 or later. ``` python3 -m venv .venv .venv/bin/python -m pip install -r mcp/requirements.txt .venv/bin/python mcp/client.py list .venv/bin/python mcp/client.py quote ``` Set `OPENSERP_API_KEY` for scoped paid/private access. An already authorized client can instead supply `OPENSERP_MCP_ACCESS_TOKEN`. The SDK examples default to a free quote and never automatically repeat a paid request. ### OAuth discovery and scopes Protected resource: `https://openserp.io/mcp`. Resource metadata is available at [/.well-known/oauth-protected-resource/mcp](https://openserp.io/.well-known/oauth-protected-resource/mcp); authorization metadata is at [/.well-known/oauth-authorization-server](https://openserp.io/.well-known/oauth-authorization-server). The issuer is `https://openserp.io`. Clients can register at `/oauth/register`, authorize at `/authorize` with S256 PKCE, and exchange/refresh tokens at `/oauth/token`. Permissions are `search` and `balance`. Access tokens last one hour and refresh tokens 30 days. Sign in and approve access in the consent flow; revoke connections from the console. MCP OAuth tokens are audience-bound to the MCP resource and do not authenticate REST calls. Use an API key for REST calls. ### Realtime Markdown and usage `search_markdown` searches and fetches unique organic destinations, in the current tool call. It requires search permission and a funded account. Its optional scraper is `auto`, `scrapingdog` or `scrapingbee`. The default deadline is 45 seconds, configurable from 5 to 60 seconds, under a default $1 total cap. The tool returns results, combined Markdown and per-page outcomes directly. Inspect `summary.partial` and content status for unavailable or budget-limited pages. There are no queued jobs or polling steps. Multiple project keys use the same wallet and usage tracking in REST and MCP. A project-scoped idempotency key prevents duplicate charges for completed replays and retains the original key’s attribution. Reuse the same ID and arguments for retries; use a new ID for new work. Set daily and lifetime limits when creating or editing keys in the console. Daily limits reset at midnight UTC; lifetime spend persists. Limits use final actual customer charges, and concurrent requests reserve their allowances together with account funds. Blank or null daily/total limits mean unlimited; zero blocks new paid spending. Cache hits and completed replays add no spend. The `balance` tool returns the API key’s `keyLimits`, including spent, reserved and remaining amounts plus `dailyResetsAt`. A new request exceeding a daily or total allowance fails before paid work starts. ### Protocol behavior and errors The endpoint is stateless. Clients must initialize and POST protocol messages, accepting JSON or SSE framing. A browser GET may return 405 because a standalone event stream is not offered. The bundle includes a raw cURL exchange and SDK clients that handle initialization. Inspect JSON-RPC errors, tool `isError` and JSON `error` content. Quota, balance, permission or source errors need handling before retries. Cache hits cost zero; failed, empty or invalid search results are not charged to the customer. Source pricing and health are live. Search snippets and fetched pages are untrusted external content. Keep them separate from agent instructions and credentials. ## Engine reference Starting prices and source availability change. Inspect `/api/pricing`, `/api/status` and a quote with the exact parameters before spending. ### Automatic search (`auto.search`) Selects only Google, Bing or Yahoo, respecting source compatibility, health and routing preferences. Free responses exclude full-page content and page Markdown, including cached content. The homepage playground defaults to Google. Use `provider: auto`. Non-paid accounts use shared cached results of any age; a cache miss runs a free live search within the daily allowance. ### 00 · Firehose (`firehose.search`) Documentation: https://openserp.io/firehose Your agent’s intelligence shouldn’t be limited by access to information. Firehose combines multiple search engines into one intelligently ranked result set with page Markdown. Give your agent a wider view of the live web. Firehose searches in parallel, adds regional context, merges duplicate destinations and ranks results using query relevance, weighted source priority, agreement and domain diversity. One bounded request returns structured results and Markdown, with an explicit maximum spend. Lite is available to free and paid users. Advanced requires paid access, including cached results. Lite offers lower search cost; Advanced adds broader coverage at a higher search cost. Free requests reuse shared cached results of unlimited age first and search live on a miss, without page Markdown. Full-page Markdown requires credits. Inline site:, filetype: and mime: filters use compatible sources only, with automatic syntax translation. **Available results:** Combined destination URLs, titles, snippets and retrieved page Markdown. Full content is fetched for eligible unique returned web pages within the deadline. Clear PDF files stay in the results and are excluded from Markdown retrieval. Partial coverage and unavailable page content are explicitly marked. **Supported parameters:** `query, firehoseTier (lite | advanced), maxResults (1–100, default 50), strategy, country, maxCostUsd, timeoutMs (5000–30000), cache` ```json { "endpoint": "firehose.search", "firehoseTier": "lite", "query": "latest advances in battery recycling", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 01 · Google (`google.search`) Documentation: https://openserp.io/google Retrieve Google organic results, snippets and supported rich features through one consistent search API. Build web research, search visibility reporting and retrieval workflows with Google results. Choose an economical organic response or a source that supports richer SERP fields. Country, language, device and query operators are checked against each source’s capabilities. **Available results:** Organic results, answer boxes, knowledge panels, related searches and questions depend on the selected offering. **Supported parameters:** `country, language, device, page, maxPage, site, filetype, safe, timePeriod` ```json { "endpoint": "google.search", "query": "Cloudflare Workers documentation", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 02 · Bing (`bing.search`) Documentation: https://openserp.io/bing Search Bing organic results with normalized URLs, source health and transparent per-query pricing. Use Bing to expand research coverage and compare rankings across search engines. Bright Data, ScrapingDog, DataForSEO, SearchApi and SerpWow integrations provide different capabilities; routing selects among eligible sources. **Available results:** Organic results and available snippets. Rich features vary by provider. **Supported parameters:** `country, language, page, maxPage, safe` ```json { "endpoint": "bing.search", "query": "renewable energy research", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 03 · Yahoo (`yahoo.search`) Documentation: https://openserp.io/yahoo Access Yahoo search results through a consistent JSON API with validated destination URLs. Add Yahoo coverage without building another response parser. openSERP validates destination links, removes unresolved redirect wrappers and records empty, invalid and error responses separately. **Available results:** Organic titles, destination URLs and snippets when returned by the source. **Supported parameters:** `country, language, page, maxPage` ```json { "endpoint": "yahoo.search", "query": "open source databases", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 04 · Naver (`naver.search`) Documentation: https://openserp.io/naver Search Naver with Korean market context, normalized results and live source health. Naver is useful for research focused on South Korea. Use Korean queries and the correct locale. Requests return in realtime from eligible connected sources; check the status chart for current availability. **Available results:** Normalized organic results. Vertical and rich result coverage varies by source. **Supported parameters:** `query, provider, page, maxPage` ```json { "endpoint": "naver.search", "query": "클라우드 컴퓨팅", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 05 · Yandex (`yandex.search`) Documentation: https://openserp.io/yandex Retrieve Yandex organic search results through openSERP’s provider routing and normalized response format. Use Yandex for regional and language-specific web research. Request a specific source to keep comparisons consistent, or let openSERP choose an eligible source using price, latency and recent success. **Available results:** Organic results with URLs and descriptions supplied by the selected provider. **Supported parameters:** `country, language, page, maxPage` ```json { "endpoint": "yandex.search", "query": "облачные технологии", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 06 · Baidu (`baidu.search`) Documentation: https://openserp.io/baidu Search Baidu with China-focused defaults and a unified API for organic results and source monitoring. Baidu searches default to China. Use Chinese queries for local research and compare supported offerings before running a batch. Only sources that return results in the current request are eligible. **Available results:** Organic titles, URLs and available snippets; provider capability checks apply. **Supported parameters:** `page, maxPage, provider` ```json { "endpoint": "baidu.search", "query": "云计算 文档", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 07 · DuckDuckGo (`duckduckgo.search`) Documentation: https://openserp.io/duckduckgo Retrieve DuckDuckGo search results with locale support, bounded pagination and validated links. Extend web research with DuckDuckGo results from ScrapingDog. Continuation tokens are handled by the adapter, with page limits and duplicate detection to prevent repeated paid fetches. **Available results:** Organic results and supported locale filters. **Supported parameters:** `country, language, page, maxPage, safe, timePeriod` ```json { "endpoint": "duckduckgo.search", "query": "privacy preserving analytics", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 12 · Mojeek (`mojeek.search`) Documentation: https://openserp.io/mojeek Search Mojeek’s independent web index through openSERP with structured results, native API access, transparent pricing and source health. Mojeek returns web results from its own index. Use country and language boosting, site operators and safe search. The connected Business plan returns up to forty results per native request per request. Authenticated USD quotes show your final query price. Business storage rights enable optional result caching and replayable Markdown responses. The existing credential returned ten results in verification requests for forty; see the source status note for this observed limit. **Available results:** Organic titles, destination URLs and snippets. A single native API call retrieves the requested result window; maxPage must equal page. **Supported parameters:** `query, maxResults (1–40), page, country boost, language boost, site, exactTerms, excludeTerms, safe` ```json { "endpoint": "mojeek.search", "query": "Cloudflare Workers documentation", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 13 · DeepSeek (`deepseek.search`) Documentation: https://openserp.io/deepseek Use DeepSeek’s native Search API through openSERP for ranked web results, AI-generated summaries, source metadata and MCP workflows. This integration calls DeepSeek’s standalone Search API. Retrieve up to fifty results in one request, including titles, snippets, longer summaries, dates and relevance scores when available. Summaries are generated by AI and may contain errors or omissions. Queries, including added operators, are limited to 128 Unicode characters. Full page content is fetched separately through a budgeted realtime Markdown request. **Available results:** Organic destination URLs, snippets, AI-generated summaries, site names, publication dates, relevance scores and authority tiers when returned. Country-code localization, filetype guarantees and pagination are not supported. **Supported parameters:** `query, maxResults (1–50), language, site, exactTerms, excludeTerms; page=1` ```json { "endpoint": "deepseek.search", "query": "Cloudflare Workers documentation", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 14 · Nimble (`nimble.search`) Documentation: https://openserp.io/nimble Search the live web with Nimble’s native API, normalized results and openSERP spending controls. Start with Nimble Lite for titles, destination URLs and snippets. Standard-account Lite pricing starts at $1.188 per 1,000 searches. When fallback is enabled, Standard Search handles failures or unusable results within your spending cap at a starting price of $5.40 per 1,000 searches. Authenticate quotes for your account’s final price. Only a successful search is charged. No monthly commitment. The connected Pay As You Go plan was verified on November 5, 2026; full-page retrieval costs extra. **Available results:** Organic titles, validated URLs and descriptions. Full-page Markdown is available separately with a budgeted realtime request. **Supported parameters:** `query, maxResults (1–25), strategy, allowFallback, maxCostUsd, cache` ```json { "endpoint": "nimble.search", "query": "Cloudflare Workers documentation", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ### 16 · Exa (`exa.search`) Documentation: https://openserp.io/exa Retrieve Exa search results and available page text through openSERP’s consistent JSON and MCP interface. Exa Lite returns ranked web results and available page text from its index. The base source price covers ten results, with a per-result charge above ten. The source-reported cost is recorded for each request. No generated page summaries or additional research calls are requested. **Available results:** Titles, destination URLs and available page content as Markdown-compatible text. Missing content is left explicit, and optional realtime Markdown responses can fetch destination pages. **Supported parameters:** `query, maxResults (1–25), strategy, country (where supported), maxCostUsd, cache` ```json { "endpoint": "exa.search", "query": "Cloudflare Workers documentation", "strategy": "cheap", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } ``` ## OpenAPI definition Source: https://openserp.io/openapi.json ```json { "openapi": "3.1.0", "info": { "title": "openSERP API", "version": "2.0.0", "description": "Multi-engine search returning all valid unique received results, with inclusive prices, source health, stateless MCP and realtime Markdown retrieval. Paid actions spend prepaid account credits." }, "servers": [ { "url": "https://openserp.io" } ], "components": { "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "description": "Scoped API key from the console. OAuth access tokens are audience-bound to /mcp and cannot call these REST routes." }, "SessionAuth": { "type": "apiKey", "in": "cookie", "name": "__Host-openserp", "description": "Secure console session obtained with Google or GitHub sign-in. Scoped API keys cannot manage account projects or keys." }, "VisitorAuth": { "type": "apiKey", "in": "cookie", "name": "__Host-openserp-visitor", "description": "Anonymous browser linkage issued only when generating a key on the website. Restricted to free search; invalidated when keys attach on login." } }, "schemas": { "SearchRequest": { "type": "object", "required": [ "query" ], "properties": { "endpoint": { "default": "auto.search", "description": "auto.search selects only Google, Bing or Yahoo. Firehose Advanced requires paid access, including cached results. Free accounts may choose engines, including Firehose Lite, using unlimited-age shared cache with automatic routing and provider auto. Free responses exclude full-page content and page Markdown, including cached content. Cache misses run a free live search within the daily allowance. Provider selection and routing preferences require a funded account. Free live searches use the daily allowance.", "type": "string", "maxLength": 80, "enum": [ "auto.search", "firehose.search", "google.search", "bing.search", "yahoo.search", "naver.search", "yandex.search", "baidu.search", "duckduckgo.search", "google.images", "bing.images", "mojeek.search", "deepseek.search", "nimble.search", "exa.search" ] }, "query": { "description": "Search text, at most 2,000 characters after normalization (24,000 encoded input characters). Whitespace, control characters, percent/HTML encoding and typographic quotes are normalized. File-type aliases use each engine’s syntax; quoted operators remain literal. Firehose routes operators only to compatible sources. DeepSeek limits the final query to 128 Unicode characters.", "type": "string", "maxLength": 24000 }, "pageMarkdown": { "description": "Firehose only: false returns search results without fetching page content, reducing cost and response time. true includes page Markdown and requires credits. Omitted paid API requests retain page Markdown; the playground defaults to false.", "type": "boolean" }, "provider": { "default": "auto", "description": "Provider or offering selection requires a funded account. With allowFallback true this is a preference; set false to pin one route. Free searches require auto.", "type": "string", "maxLength": 100 }, "strategy": { "default": "cheap", "description": "Funded accounts may prefer cheap or fast routing. Free searches ignore this preference and always use automatic cache routing.", "type": "string", "enum": [ "cheap", "fast" ] }, "country": { "description": "Country name, native name, ISO alpha-2/alpha-3 or numeric code. USA, U.S. and United States of America normalize to us.", "type": "string", "maxLength": 150 }, "language": { "description": "Language name or code. English/eng normalize to en; regional locale spellings use the base language, with Simplified/Traditional Chinese variants retained.", "type": "string", "maxLength": 150 }, "page": { "default": 1, "type": "integer", "minimum": 1, "maximum": 10 }, "maxPage": { "type": "integer", "minimum": 1, "maximum": 10 }, "maxResults": { "description": "Upstream request target, not a response cap. Defaults to 50 for Firehose (input maximum 100) and 10 otherwise. All valid unique results received are returned, even above the target. Source request limits apply.", "type": "integer", "minimum": 1, "maximum": 1000 }, "timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 30000, "description": "Firehose overall deadline. Default 15000 for fast, 25000 for cheap." }, "maxCostUsd": { "type": [ "string", "number" ] }, "cache": { "default": { "enabled": false, "ttlHours": 24 }, "description": "All cacheable searches reuse results for at least five minutes. enabled false or omitted cache uses a five-minute maximum age; enabled true uses ttlHours, with a five-minute minimum. null means no expiration. Coordinate requests and provider retention restrictions still bypass caching. Cache hits cost zero; free searches reuse shared results of unlimited age. Dedicated page Markdown response caching is private to the account.", "examples": [ { "enabled": true, "ttlHours": 24 } ], "type": "object", "properties": { "enabled": { "default": false, "type": "boolean" }, "ttlHours": { "default": 24, "anyOf": [ { "type": "number", "exclusiveMinimum": 0, "maximum": 87600 }, { "type": "null" } ] } } }, "firehoseTier": { "description": "Firehose coverage tier. Omitted means lite, the lower search-cost combination. default is a backward-compatible alias for lite. Advanced adds broader coverage at higher search cost. Results use query relevance, weighted source priority and agreement. Lite is available to free and paid users; Advanced requires paid access, including cached results. Free Lite requests reuse shared cache first and search live on a miss, without page Markdown. Applies only to firehose.search.", "type": "string", "enum": [ "lite", "default", "advanced" ] }, "engine": { "type": "string", "maxLength": 40 }, "q": { "type": "string", "maxLength": 24000 }, "allowFallback": { "default": true, "description": "Automatic source selection (provider auto) always retries sources within the selected engine using the cheap or fast strategy, even when this flag is false; it never changes engines after selection. With an explicit provider/offering, false pins one source and one attempt; true allows other sources and compatible engines, preferring viable same-engine sources. Up to three attempts share the deadline and spending cap. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with managed same-engine source retries.", "type": "boolean" }, "location": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } ] }, "domain": { "type": "string", "maxLength": 250 }, "site": { "type": "string", "maxLength": 1000 }, "exactTerms": { "type": "string", "maxLength": 250 }, "excludeTerms": { "type": "string", "maxLength": 250 }, "filetype": { "type": "string", "maxLength": 150 }, "safe": { "description": "off, moderate or strict; on/true normalize to strict. Only compatible sources are eligible.", "anyOf": [ { "type": "string", "maxLength": 40 }, { "type": "boolean" } ] }, "device": { "description": "desktop, mobile or tablet; phone/smartphone normalize to mobile.", "type": "string", "maxLength": 40 }, "timePeriod": { "description": "hour, day, week, month or year; aliases such as past week normalize to week.", "type": "string", "maxLength": 80 }, "resultLanguage": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "countryRestrict": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "noAutocorrect": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "duplicateFilter": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] } }, "additionalProperties": true }, "MarkdownRequest": { "type": "object", "required": [ "query" ], "properties": { "endpoint": { "default": "auto.search", "description": "auto.search selects only Google, Bing or Yahoo. Firehose Advanced requires paid access, including cached results. Free accounts may choose engines, including Firehose Lite, using unlimited-age shared cache with automatic routing and provider auto. Free responses exclude full-page content and page Markdown, including cached content. Cache misses run a free live search within the daily allowance. Provider selection and routing preferences require a funded account. Free live searches use the daily allowance.", "type": "string", "maxLength": 80, "enum": [ "auto.search", "firehose.search", "google.search", "bing.search", "yahoo.search", "naver.search", "yandex.search", "baidu.search", "duckduckgo.search", "google.images", "bing.images", "mojeek.search", "deepseek.search", "nimble.search", "exa.search" ] }, "query": { "description": "Search text, at most 2,000 characters after normalization (24,000 encoded input characters). Whitespace, control characters, percent/HTML encoding and typographic quotes are normalized. File-type aliases use each engine’s syntax; quoted operators remain literal. Firehose routes operators only to compatible sources. DeepSeek limits the final query to 128 Unicode characters.", "type": "string", "maxLength": 24000 }, "pageMarkdown": { "description": "Firehose only: false returns search results without fetching page content, reducing cost and response time. true includes page Markdown and requires credits. Omitted paid API requests retain page Markdown; the playground defaults to false.", "type": "boolean" }, "provider": { "default": "auto", "description": "Provider or offering selection requires a funded account. With allowFallback true this is a preference; set false to pin one route. Free searches require auto.", "type": "string", "maxLength": 100 }, "strategy": { "default": "cheap", "description": "Funded accounts may prefer cheap or fast routing. Free searches ignore this preference and always use automatic cache routing.", "type": "string", "enum": [ "cheap", "fast" ] }, "country": { "description": "Country name, native name, ISO alpha-2/alpha-3 or numeric code. USA, U.S. and United States of America normalize to us.", "type": "string", "maxLength": 150 }, "language": { "description": "Language name or code. English/eng normalize to en; regional locale spellings use the base language, with Simplified/Traditional Chinese variants retained.", "type": "string", "maxLength": 150 }, "page": { "default": 1, "type": "integer", "minimum": 1, "maximum": 10 }, "maxPage": { "type": "integer", "minimum": 1, "maximum": 10 }, "maxResults": { "description": "Upstream request target, not a response cap. Defaults to 50 for Firehose (input maximum 100) and 10 otherwise. All valid unique results received are returned, even above the target. Source request limits apply.", "type": "integer", "minimum": 1, "maximum": 1000 }, "timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 60000, "default": 45000, "description": "Overall deadline for realtime search and page retrieval. Search gets up to 25000 ms and each page fetch up to 15000 ms within the remaining deadline. Partial results are returned when content is unavailable or the cap is reached." }, "maxCostUsd": { "type": [ "string", "number" ] }, "cache": { "default": { "enabled": false, "ttlHours": 24 }, "description": "All cacheable searches reuse results for at least five minutes. enabled false or omitted cache uses a five-minute maximum age; enabled true uses ttlHours, with a five-minute minimum. null means no expiration. Coordinate requests and provider retention restrictions still bypass caching. Cache hits cost zero; free searches reuse shared results of unlimited age. Dedicated page Markdown response caching is private to the account.", "examples": [ { "enabled": true, "ttlHours": 24 } ], "type": "object", "properties": { "enabled": { "default": false, "type": "boolean" }, "ttlHours": { "default": 24, "anyOf": [ { "type": "number", "exclusiveMinimum": 0, "maximum": 87600 }, { "type": "null" } ] } } }, "firehoseTier": { "description": "Firehose coverage tier. Omitted means lite, the lower search-cost combination. default is a backward-compatible alias for lite. Advanced adds broader coverage at higher search cost. Results use query relevance, weighted source priority and agreement. Lite is available to free and paid users; Advanced requires paid access, including cached results. Free Lite requests reuse shared cache first and search live on a miss, without page Markdown. Applies only to firehose.search.", "type": "string", "enum": [ "lite", "default", "advanced" ] }, "engine": { "type": "string", "maxLength": 40 }, "q": { "type": "string", "maxLength": 24000 }, "allowFallback": { "default": true, "description": "Automatic source selection (provider auto) always retries sources within the selected engine using the cheap or fast strategy, even when this flag is false; it never changes engines after selection. With an explicit provider/offering, false pins one source and one attempt; true allows other sources and compatible engines, preferring viable same-engine sources. Up to three attempts share the deadline and spending cap. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with managed same-engine source retries.", "type": "boolean" }, "location": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } ] }, "domain": { "type": "string", "maxLength": 250 }, "site": { "type": "string", "maxLength": 1000 }, "exactTerms": { "type": "string", "maxLength": 250 }, "excludeTerms": { "type": "string", "maxLength": 250 }, "filetype": { "type": "string", "maxLength": 150 }, "safe": { "description": "off, moderate or strict; on/true normalize to strict. Only compatible sources are eligible.", "anyOf": [ { "type": "string", "maxLength": 40 }, { "type": "boolean" } ] }, "device": { "description": "desktop, mobile or tablet; phone/smartphone normalize to mobile.", "type": "string", "maxLength": 40 }, "timePeriod": { "description": "hour, day, week, month or year; aliases such as past week normalize to week.", "type": "string", "maxLength": 80 }, "resultLanguage": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "countryRestrict": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "noAutocorrect": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "duplicateFilter": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "scraper": { "type": "string", "enum": [ "auto", "scrapingdog", "scrapingbee" ], "default": "auto" } }, "additionalProperties": true } } }, "paths": { "/search": { "post": { "summary": "Firehose: free cached or live Lite results. Advanced and page Markdown require paid access.", "operationId": "firehose", "security": [ { "BearerAuth": [] }, { "SessionAuth": [] }, { "VisitorAuth": [] } ], "parameters": [ { "in": "header", "name": "Idempotency-Key", "schema": { "type": "string", "maxLength": 120 }, "description": "Reusing a completed request key returns its stored result; different inputs return 409." }, { "in": "header", "name": "Accept", "schema": { "type": "string" }, "description": "application/json by default. The website uses application/x-ndjson for realtime progress and a final result in the same request." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" }, "example": { "endpoint": "firehose.search", "query": "Cloudflare Workers", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } }, "application/x-ndjson": { "schema": { "type": "string" }, "example": "{\"type\":\"progress\",\"phase\":\"searching\"}\n{\"type\":\"result\",\"data\":{}}\n" } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "402": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "410": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "503": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/search": { "post": { "summary": "Search a selected engine; free queries use shared cache with automatic routing and provider auto", "operationId": "search", "security": [ { "BearerAuth": [] }, { "SessionAuth": [] }, { "VisitorAuth": [] } ], "parameters": [ { "in": "header", "name": "Idempotency-Key", "schema": { "type": "string", "maxLength": 120 }, "description": "Reusing a completed request key returns its stored result; different inputs return 409." }, { "in": "header", "name": "Accept", "schema": { "type": "string" }, "description": "application/json by default. The website uses application/x-ndjson for realtime progress and a final result in the same request." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" }, "example": { "endpoint": "google.search", "query": "Cloudflare Workers", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } }, "application/x-ndjson": { "schema": { "type": "string" }, "example": "{\"type\":\"progress\",\"phase\":\"searching\"}\n{\"type\":\"result\",\"data\":{}}\n" } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "402": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "410": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "503": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/quote": { "post": { "summary": "Compare inclusive prices, median/p90 search latency and source timeouts without paid calls", "operationId": "quote", "security": [ { "BearerAuth": [] }, {} ], "parameters": [ { "in": "header", "name": "Idempotency-Key", "schema": { "type": "string", "maxLength": 120 }, "description": "Reusing a completed request key returns its stored result; different inputs return 409." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" }, "example": { "endpoint": "google.search", "query": "Cloudflare Workers", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "402": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "410": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "503": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/search/markdown": { "post": { "summary": "Fetch full-page Markdown in realtime. Paid accounts and search permission only", "operationId": "searchMarkdown", "security": [ { "BearerAuth": [] }, { "SessionAuth": [] }, { "VisitorAuth": [] } ], "parameters": [ { "in": "header", "name": "Idempotency-Key", "schema": { "type": "string", "maxLength": 120 }, "description": "Reusing a completed request key returns its stored result; different inputs return 409." }, { "in": "header", "name": "Accept", "schema": { "type": "string" }, "description": "application/json by default. The website uses application/x-ndjson for realtime progress and a final result in the same request." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarkdownRequest" }, "example": { "endpoint": "google.search", "query": "Cloudflare Workers", "maxCostUsd": "1", "cache": { "enabled": true, "ttlHours": 24 } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } }, "application/x-ndjson": { "schema": { "type": "string" }, "example": "{\"type\":\"progress\",\"phase\":\"searching\"}\n{\"type\":\"result\",\"data\":{}}\n" } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "402": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "410": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "503": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/pricing": { "get": { "summary": "Final starting query prices per 1,000 searches; authenticated requests use account-specific pricing", "operationId": "startingPrices", "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/status": { "get": { "summary": "Seven-day hourly source history, trailing-hour median/p90 search latency and timeout policies", "operationId": "status", "parameters": [ { "in": "query", "name": "engine", "schema": { "type": "string" } } ], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/account": { "get": { "summary": "Account balance and the authenticated API key’s limits, spend, reservations and remaining allowances", "operationId": "account", "security": [ { "BearerAuth": [] } ], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/anonymous/keys": { "post": { "x-browser-only": true, "summary": "Generate or automatically reuse an anonymous key on the website; keys and usage attach on login", "description": "Same-origin browser POST only. The playground calls this on the first Run click. reuseExisting true reconnects a valid existing browser key without issuing or revealing another secret. Generates a secret once, with per-request, daily and total spending limits; sets a Secure HttpOnly visitor cookie. At most three active keys per visitor and network-limited issuance. Search quota is shared by network across keys and login. Sign in in the original browser within 30 days of the first key to keep keys and history. Unclaimed accounts and keys expire after 30 days; responses report expiresAt in milliseconds. Creating more keys does not extend expiry. Use the signed-in console for account keys.", "operationId": "createAnonymousKey", "parameters": [ { "in": "header", "name": "Origin", "required": true, "schema": { "type": "string", "const": "https://openserp.io" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 80 }, "projectId": { "type": "string", "description": "Project owned by the signed-in account; defaults to the Default project on creation and cannot be changed on an existing key." }, "scopes": { "type": "array", "minItems": 1, "items": { "type": "string", "enum": [ "search", "balance" ] } }, "maxCostUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "exclusiveMinimum": 0, "maximum": 10 } ], "default": "1", "description": "Per-request customer spending cap, at final customer prices. Greater than $0 and at most $10." }, "dailyLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional daily customer spend limit at final customer prices, reset at 00:00 UTC. Null or blank means unlimited; 0 blocks new paid spend. Active reservations count against the allowance." }, "totalLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional lifetime customer spend limit at final customer prices. Null or blank means unlimited; 0 blocks new paid spend. Actual charges persist across limit edits and analytics expiry." }, "reuseExisting": { "type": "boolean", "default": false, "description": "Reuse a valid browser-linked key rather than issuing another. Used automatically by the playground." } } } } } }, "responses": { "201": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/mcp/install-key": { "post": { "x-browser-only": true, "summary": "Generate an account-linked MCP setup key when copying client configuration", "description": "Website Copy setup/Copy agent instructions only. Requires same-origin browser context; Bearer authentication is rejected. A signed-in session creates a key in its Default project; an anonymous visitor gets a browser-linked key and Secure HttpOnly cookie. Anonymous keys and usage attach on login/account creation in the same browser before expiry, 30 days from the first key. New keys have search/balance scopes and $1 per-request, $5 daily and $20 total limits. The page keeps the returned secret only in memory and may supply reuseKey on later copies. Ownership and revocation are rechecked against the current browser; valid reuse preserves project, scopes and limits. No recoverable key is stored server-side. Responses are private/no-store; anonymous issuance limits apply.", "operationId": "mcpInstallKey", "security": [ { "SessionAuth": [] }, { "VisitorAuth": [] }, {} ], "parameters": [ { "in": "header", "name": "Origin", "required": true, "schema": { "type": "string", "const": "https://openserp.io" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "additionalProperties": false, "properties": { "reuseKey": { "type": "string", "writeOnly": true, "pattern": "^osk?_[A-Za-z0-9_-]{20,197}$", "description": "Previously generated secret held in page memory; never place in a URL." } } }, "example": {} } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "201": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "429": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/projects": { "get": { "summary": "List owned projects and key counts", "operationId": "projects", "security": [ { "SessionAuth": [] } ], "parameters": [], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } }, "post": { "summary": "Create a named project", "operationId": "createProject", "security": [ { "SessionAuth": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 80 } } } } } }, "responses": { "201": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/projects/{id}": { "patch": { "summary": "Rename a project", "operationId": "renameProject", "security": [ { "SessionAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 80 } } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/keys": { "get": { "summary": "List key limits, actual daily/lifetime spend and reservations without secret values", "operationId": "keys", "security": [ { "SessionAuth": [] } ], "parameters": [ { "in": "query", "name": "projectId", "schema": { "type": "string" } }, { "in": "query", "name": "cursor", "schema": { "type": "string" }, "description": "nextCursor from the previous page; 100 keys per page." } ], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } }, "post": { "summary": "Create a project key with per-request, daily and lifetime spend limits; secret shown once", "operationId": "createKey", "security": [ { "SessionAuth": [] } ], "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 80 }, "projectId": { "type": "string", "description": "Project owned by the signed-in account; defaults to the Default project on creation and cannot be changed on an existing key." }, "scopes": { "type": "array", "minItems": 1, "items": { "type": "string", "enum": [ "search", "balance" ] } }, "maxCostUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "exclusiveMinimum": 0, "maximum": 10 } ], "default": "1", "description": "Per-request customer spending cap, at final customer prices. Greater than $0 and at most $10." }, "dailyLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional daily customer spend limit at final customer prices, reset at 00:00 UTC. Null or blank means unlimited; 0 blocks new paid spend. Active reservations count against the allowance." }, "totalLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional lifetime customer spend limit at final customer prices. Null or blank means unlimited; 0 blocks new paid spend. Actual charges persist across limit edits and analytics expiry." } } } } } }, "responses": { "201": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/keys/{id}": { "patch": { "summary": "Update key name, permissions and per-request, daily or lifetime spend limits", "operationId": "updateKey", "security": [ { "SessionAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 80 }, "projectId": { "type": "string", "description": "Project owned by the signed-in account; defaults to the Default project on creation and cannot be changed on an existing key." }, "scopes": { "type": "array", "minItems": 1, "items": { "type": "string", "enum": [ "search", "balance" ] } }, "maxCostUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "exclusiveMinimum": 0, "maximum": 10 } ], "default": "1", "description": "Per-request customer spending cap, at final customer prices. Greater than $0 and at most $10." }, "dailyLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional daily customer spend limit at final customer prices, reset at 00:00 UTC. Null or blank means unlimited; 0 blocks new paid spend. Active reservations count against the allowance." }, "totalLimitUsd": { "oneOf": [ { "type": "string" }, { "type": "number", "minimum": 0 }, { "type": "null" } ], "default": null, "description": "Optional lifetime customer spend limit at final customer prices. Null or blank means unlimited; 0 blocks new paid spend. Actual charges persist across limit edits and analytics expiry." } } } } } }, "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } }, "delete": { "summary": "Revoke a key while retaining its usage history", "operationId": "revokeKey", "security": [ { "SessionAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/account/usage": { "get": { "summary": "Compare searches and actual charges across keys; includes revoked-key history", "operationId": "keyUsage", "security": [ { "SessionAuth": [] } ], "parameters": [ { "in": "query", "name": "days", "schema": { "type": "integer", "enum": [ 1, 7, 30 ], "default": 7 } }, { "in": "query", "name": "projectId", "schema": { "type": "string" } }, { "in": "query", "name": "keyId", "schema": { "type": "string" } } ], "responses": { "200": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "404": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "409": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/account/exports/payments.csv": { "get": { "summary": "Export complete payment history, status, credit reversals and net credited amounts as CSV", "description": "Exports the authenticated account only. Requires a browser session or API key with balance permission. All history by default; from/to are inclusive UTC calendar dates. Responses stream CSV without queuing a job.", "operationId": "exportPaymentHistory", "security": [ { "SessionAuth": [] }, { "BearerAuth": [] } ], "parameters": [ { "in": "query", "name": "from", "schema": { "type": "string", "format": "date" }, "description": "First UTC date, inclusive. Omit for all history." }, { "in": "query", "name": "to", "schema": { "type": "string", "format": "date" }, "description": "Last UTC date, inclusive. Defaults to today; future dates are rejected." } ], "responses": { "200": { "description": "Private CSV download", "headers": { "Content-Disposition": { "schema": { "type": "string" }, "description": "attachment with a generated CSV filename" } }, "content": { "text/csv": { "schema": { "type": "string" } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } }, "/api/account/exports/daily-spend.csv": { "get": { "summary": "Export daily UTC wallet spend across all projects and keys, including zero-spend dates, as CSV", "description": "Exports the authenticated account only. Requires a browser session or API key with balance permission. All history by default; from/to are inclusive UTC calendar dates. Responses stream CSV without queuing a job.", "operationId": "exportDailySpendHistory", "security": [ { "SessionAuth": [] }, { "BearerAuth": [] } ], "parameters": [ { "in": "query", "name": "from", "schema": { "type": "string", "format": "date" }, "description": "First UTC date, inclusive. Omit for all history." }, { "in": "query", "name": "to", "schema": { "type": "string", "format": "date" }, "description": "Last UTC date, inclusive. Defaults to today; future dates are rejected." } ], "responses": { "200": { "description": "Private CSV download", "headers": { "Content-Disposition": { "schema": { "type": "string" }, "description": "attachment with a generated CSV filename" } }, "content": { "text/csv": { "schema": { "type": "string" } } } }, "400": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "401": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } }, "403": { "description": "JSON response", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true } } } } } } } } } ``` ## MCP tool schemas Source: https://openserp.io/mcp-tools.json ```json { "tools": [ { "name": "search", "description": "Defaults to Firehose Lite, results only, with shared cache enabled and a 24-hour maximum age. Set an endpoint or firehoseTier to override; request pageMarkdown true explicitly for paid full-page content. Search live web results with an API key (including a free anonymous key generated at https://openserp.io/keys) or account OAuth. Anonymous keys and usage attach on login in the original browser. Automatic engine selection (auto.search) uses only Google, Bing and Yahoo. Free results never include full-page content or page Markdown, even from shared cache. Free accounts may choose any engine, including Firehose Lite with provider auto and automatic routing; fast/cheap preferences are ignored. Shared cached results have unlimited age; cache misses run a live search within the free allowance. firehose.search returns combined ranked results and Markdown within a deadline. Paid requests may spend up to maxCostUsd. maxResults is an upstream request target; every valid unique received result is returned, including extras. Country and language names/codes are normalized; advanced fields route only to compatible sources. Firehose accepts firehoseTier lite (lower search cost) or advanced (broader coverage at higher search cost). Free and paid users can select either; free requests reuse unlimited-age shared cache first, then search live on a miss without page Markdown.", "inputSchema": { "type": "object", "properties": { "pageMarkdown": { "default": false, "description": "Defaults to false: return search results and snippets without page fetching. For Firehose, true adds paid full-page Markdown, cost and response time. Use search_markdown for full-page content on other engines.", "type": "boolean" }, "firehoseTier": { "default": "lite", "description": "Firehose coverage tier. Omitted means lite, the lower search-cost combination. default is a backward-compatible alias for lite. Advanced adds broader coverage at higher search cost. Results use query relevance, weighted source priority and agreement. Lite is available to free and paid users; Advanced requires paid access, including cached results. Free Lite requests reuse shared cache first and search live on a miss, without page Markdown. Applies only to firehose.search.", "type": "string", "enum": [ "lite", "default", "advanced" ] }, "endpoint": { "default": "firehose.search", "description": "Defaults to firehose.search: Firehose Lite combined search. Choose another endpoint to select an engine. auto.search selects Google, Bing or Yahoo. Free accounts may choose engines or Firehose Lite with automatic routing. Firehose Advanced requires paid access, including cached results.", "type": "string", "maxLength": 80 }, "engine": { "type": "string", "maxLength": 40 }, "query": { "description": "Search text, at most 2,000 characters after normalization (24,000 encoded input characters). Whitespace, control characters, percent/HTML encoding and typographic quotes are normalized. File-type aliases use each engine’s syntax; quoted operators remain literal. Firehose routes operators only to compatible sources. DeepSeek limits the final query to 128 Unicode characters.", "type": "string", "maxLength": 24000 }, "q": { "type": "string", "maxLength": 24000 }, "provider": { "default": "auto", "description": "Provider or offering selection requires a funded account. With allowFallback true this is a preference; set false to pin one route. Free searches require auto.", "type": "string", "maxLength": 100 }, "strategy": { "default": "cheap", "description": "Funded accounts may prefer cheap or fast routing. Free searches ignore this preference and always use automatic cache routing.", "type": "string", "enum": [ "cheap", "fast" ] }, "allowFallback": { "default": true, "description": "Automatic source selection (provider auto) always retries sources within the selected engine using the cheap or fast strategy, even when this flag is false; it never changes engines after selection. With an explicit provider/offering, false pins one source and one attempt; true allows other sources and compatible engines, preferring viable same-engine sources. Up to three attempts share the deadline and spending cap. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with managed same-engine source retries.", "type": "boolean" }, "page": { "default": 1, "type": "integer", "minimum": 1, "maximum": 10 }, "maxPage": { "type": "integer", "minimum": 1, "maximum": 10 }, "maxResults": { "description": "Upstream request target, not a response cap. Defaults to 50 for Firehose (input maximum 100) and 10 otherwise. All valid unique results received are returned, even above the target. Source request limits apply.", "type": "integer", "minimum": 1, "maximum": 1000 }, "maxCostUsd": { "type": [ "string", "number" ] }, "country": { "description": "Country name, native name, ISO alpha-2/alpha-3 or numeric code. USA, U.S. and United States of America normalize to us.", "type": "string", "maxLength": 150 }, "language": { "description": "Language name or code. English/eng normalize to en; regional locale spellings use the base language, with Simplified/Traditional Chinese variants retained.", "type": "string", "maxLength": 150 }, "location": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } ] }, "domain": { "type": "string", "maxLength": 250 }, "site": { "type": "string", "maxLength": 1000 }, "exactTerms": { "type": "string", "maxLength": 250 }, "excludeTerms": { "type": "string", "maxLength": 250 }, "filetype": { "type": "string", "maxLength": 150 }, "safe": { "description": "off, moderate or strict; on/true normalize to strict. Only compatible sources are eligible.", "anyOf": [ { "type": "string", "maxLength": 40 }, { "type": "boolean" } ] }, "device": { "description": "desktop, mobile or tablet; phone/smartphone normalize to mobile.", "type": "string", "maxLength": 40 }, "timePeriod": { "description": "hour, day, week, month or year; aliases such as past week normalize to week.", "type": "string", "maxLength": 80 }, "resultLanguage": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "countryRestrict": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "noAutocorrect": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "duplicateFilter": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "cache": { "default": { "enabled": true, "ttlHours": 24 }, "description": "Shared cache is enabled by default, with a 24-hour maximum age for paid searches. Free searches use unlimited-age shared cache. Setting enabled false limits reuse to five minutes. All cacheable requests have a five-minute minimum, including shorter ttlHours values. Paid dedicated Markdown responses are cached privately per account.", "type": "object", "properties": { "enabled": { "default": true, "type": "boolean" }, "ttlHours": { "default": 24, "anyOf": [ { "type": "number", "exclusiveMinimum": 0, "maximum": 87600 }, { "type": "null" } ] } } } }, "additionalProperties": {} }, "annotations": { "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } }, { "name": "quote", "description": "Defaults to Firehose Lite with results only and shared cache enabled (24 hours). Compare inclusive prices, trailing-hour median/p90 search latency and source timeouts without a paid search. Page Markdown fetching is excluded.", "inputSchema": { "type": "object", "properties": { "pageMarkdown": { "default": false, "description": "Defaults to false: return search results and snippets without page fetching. For Firehose, true adds paid full-page Markdown, cost and response time. Use search_markdown for full-page content on other engines.", "type": "boolean" }, "firehoseTier": { "default": "lite", "description": "Firehose coverage tier. Omitted means lite, the lower search-cost combination. default is a backward-compatible alias for lite. Advanced adds broader coverage at higher search cost. Results use query relevance, weighted source priority and agreement. Lite is available to free and paid users; Advanced requires paid access, including cached results. Free Lite requests reuse shared cache first and search live on a miss, without page Markdown. Applies only to firehose.search.", "type": "string", "enum": [ "lite", "default", "advanced" ] }, "endpoint": { "default": "firehose.search", "description": "Defaults to firehose.search: Firehose Lite combined search. Choose another endpoint to select an engine. auto.search selects Google, Bing or Yahoo. Free accounts may choose engines or Firehose Lite with automatic routing. Firehose Advanced requires paid access, including cached results.", "type": "string", "maxLength": 80 }, "engine": { "type": "string", "maxLength": 40 }, "query": { "description": "Search text, at most 2,000 characters after normalization (24,000 encoded input characters). Whitespace, control characters, percent/HTML encoding and typographic quotes are normalized. File-type aliases use each engine’s syntax; quoted operators remain literal. Firehose routes operators only to compatible sources. DeepSeek limits the final query to 128 Unicode characters.", "type": "string", "maxLength": 24000 }, "q": { "type": "string", "maxLength": 24000 }, "provider": { "default": "auto", "description": "Provider or offering selection requires a funded account. With allowFallback true this is a preference; set false to pin one route. Free searches require auto.", "type": "string", "maxLength": 100 }, "strategy": { "default": "cheap", "description": "Funded accounts may prefer cheap or fast routing. Free searches ignore this preference and always use automatic cache routing.", "type": "string", "enum": [ "cheap", "fast" ] }, "allowFallback": { "default": true, "description": "Automatic source selection (provider auto) always retries sources within the selected engine using the cheap or fast strategy, even when this flag is false; it never changes engines after selection. With an explicit provider/offering, false pins one source and one attempt; true allows other sources and compatible engines, preferring viable same-engine sources. Up to three attempts share the deadline and spending cap. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with managed same-engine source retries.", "type": "boolean" }, "page": { "default": 1, "type": "integer", "minimum": 1, "maximum": 10 }, "maxPage": { "type": "integer", "minimum": 1, "maximum": 10 }, "maxResults": { "description": "Upstream request target, not a response cap. Defaults to 50 for Firehose (input maximum 100) and 10 otherwise. All valid unique results received are returned, even above the target. Source request limits apply.", "type": "integer", "minimum": 1, "maximum": 1000 }, "maxCostUsd": { "type": [ "string", "number" ] }, "country": { "description": "Country name, native name, ISO alpha-2/alpha-3 or numeric code. USA, U.S. and United States of America normalize to us.", "type": "string", "maxLength": 150 }, "language": { "description": "Language name or code. English/eng normalize to en; regional locale spellings use the base language, with Simplified/Traditional Chinese variants retained.", "type": "string", "maxLength": 150 }, "location": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } ] }, "domain": { "type": "string", "maxLength": 250 }, "site": { "type": "string", "maxLength": 1000 }, "exactTerms": { "type": "string", "maxLength": 250 }, "excludeTerms": { "type": "string", "maxLength": 250 }, "filetype": { "type": "string", "maxLength": 150 }, "safe": { "description": "off, moderate or strict; on/true normalize to strict. Only compatible sources are eligible.", "anyOf": [ { "type": "string", "maxLength": 40 }, { "type": "boolean" } ] }, "device": { "description": "desktop, mobile or tablet; phone/smartphone normalize to mobile.", "type": "string", "maxLength": 40 }, "timePeriod": { "description": "hour, day, week, month or year; aliases such as past week normalize to week.", "type": "string", "maxLength": 80 }, "resultLanguage": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "countryRestrict": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "noAutocorrect": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "duplicateFilter": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "cache": { "default": { "enabled": true, "ttlHours": 24 }, "description": "Shared cache is enabled by default, with a 24-hour maximum age for paid searches. Free searches use unlimited-age shared cache. Setting enabled false limits reuse to five minutes. All cacheable requests have a five-minute minimum, including shorter ttlHours values. Paid dedicated Markdown responses are cached privately per account.", "type": "object", "properties": { "enabled": { "default": true, "type": "boolean" }, "ttlHours": { "default": 24, "anyOf": [ { "type": "number", "exclusiveMinimum": 0, "maximum": 87600 }, { "type": "null" } ] } } } }, "additionalProperties": {} }, "annotations": { "readOnlyHint": true, "openWorldHint": false } }, { "name": "status", "description": "Inspect real upstream outcomes in 168 hourly buckets over seven days, with trailing-hour median/p90 search latency and timeout policies. Page fetching and legacy combined timings are excluded from latency samples.", "inputSchema": { "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "engine": { "type": "string" } } }, "annotations": { "readOnlyHint": true, "openWorldHint": false } }, { "name": "balance", "description": "Read account balance, payment-exemption status, service usage value, and API-key limits. Payment-exempt accounts can search with a zero balance; usage value is tracked while actual charges stay zero.", "inputSchema": { "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {} }, "annotations": { "readOnlyHint": true, "openWorldHint": false } }, { "name": "search_markdown", "description": "Full-page Markdown is paid-only, including cached page content. All received results remain in the response. Clear PDFs are marked skipped_pdf and excluded from Markdown fetching and page-fetch charges; retrieve eligible unique URLs within the deadline and spending cap. Requires a funded account and search permission. Default 45 seconds and $1 total cap. Partial results identify unavailable, budget-limited or size-limited content.", "inputSchema": { "type": "object", "properties": { "firehoseTier": { "default": "lite", "description": "Firehose coverage tier. Omitted means lite, the lower search-cost combination. default is a backward-compatible alias for lite. Advanced adds broader coverage at higher search cost. Results use query relevance, weighted source priority and agreement. Lite is available to free and paid users; Advanced requires paid access, including cached results. Free Lite requests reuse shared cache first and search live on a miss, without page Markdown. Applies only to firehose.search.", "type": "string", "enum": [ "lite", "default", "advanced" ] }, "endpoint": { "default": "firehose.search", "description": "Defaults to firehose.search: Firehose Lite combined search. Choose another endpoint to select an engine. auto.search selects Google, Bing or Yahoo. Free accounts may choose engines or Firehose Lite with automatic routing. Firehose Advanced requires paid access, including cached results.", "type": "string", "maxLength": 80 }, "engine": { "type": "string", "maxLength": 40 }, "query": { "description": "Search text, at most 2,000 characters after normalization (24,000 encoded input characters). Whitespace, control characters, percent/HTML encoding and typographic quotes are normalized. File-type aliases use each engine’s syntax; quoted operators remain literal. Firehose routes operators only to compatible sources. DeepSeek limits the final query to 128 Unicode characters.", "type": "string", "maxLength": 24000 }, "q": { "type": "string", "maxLength": 24000 }, "provider": { "default": "auto", "description": "Provider or offering selection requires a funded account. With allowFallback true this is a preference; set false to pin one route. Free searches require auto.", "type": "string", "maxLength": 100 }, "strategy": { "default": "cheap", "description": "Funded accounts may prefer cheap or fast routing. Free searches ignore this preference and always use automatic cache routing.", "type": "string", "enum": [ "cheap", "fast" ] }, "allowFallback": { "default": true, "description": "Automatic source selection (provider auto) always retries sources within the selected engine using the cheap or fast strategy, even when this flag is false; it never changes engines after selection. With an explicit provider/offering, false pins one source and one attempt; true allows other sources and compatible engines, preferring viable same-engine sources. Up to three attempts share the deadline and spending cap. Sources with at least ten trailing-hour samples below 90% success remain deprioritized. Compatible web alternatives are Google, Bing and Yahoo; image fallback stays on image engines. Firehose always retries sources within each component engine. Free searches use shared cache first and live search on a miss with managed same-engine source retries.", "type": "boolean" }, "page": { "default": 1, "type": "integer", "minimum": 1, "maximum": 10 }, "maxPage": { "type": "integer", "minimum": 1, "maximum": 10 }, "maxResults": { "description": "Upstream request target, not a response cap. Defaults to 50 for Firehose (input maximum 100) and 10 otherwise. All valid unique results received are returned, even above the target. Source request limits apply.", "type": "integer", "minimum": 1, "maximum": 1000 }, "maxCostUsd": { "type": [ "string", "number" ] }, "country": { "description": "Country name, native name, ISO alpha-2/alpha-3 or numeric code. USA, U.S. and United States of America normalize to us.", "type": "string", "maxLength": 150 }, "language": { "description": "Language name or code. English/eng normalize to en; regional locale spellings use the base language, with Simplified/Traditional Chinese variants retained.", "type": "string", "maxLength": 150 }, "location": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} } ] }, "domain": { "type": "string", "maxLength": 250 }, "site": { "type": "string", "maxLength": 1000 }, "exactTerms": { "type": "string", "maxLength": 250 }, "excludeTerms": { "type": "string", "maxLength": 250 }, "filetype": { "type": "string", "maxLength": 150 }, "safe": { "description": "off, moderate or strict; on/true normalize to strict. Only compatible sources are eligible.", "anyOf": [ { "type": "string", "maxLength": 40 }, { "type": "boolean" } ] }, "device": { "description": "desktop, mobile or tablet; phone/smartphone normalize to mobile.", "type": "string", "maxLength": 40 }, "timePeriod": { "description": "hour, day, week, month or year; aliases such as past week normalize to week.", "type": "string", "maxLength": 80 }, "resultLanguage": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "countryRestrict": { "anyOf": [ { "type": "string", "maxLength": 250 }, { "maxItems": 10, "type": "array", "items": { "type": "string", "maxLength": 150 } } ] }, "noAutocorrect": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "duplicateFilter": { "anyOf": [ { "type": "boolean" }, { "type": "string", "maxLength": 20 }, { "type": "integer", "minimum": 0, "maximum": 1 } ] }, "cache": { "default": { "enabled": true, "ttlHours": 24 }, "description": "Shared cache is enabled by default, with a 24-hour maximum age for paid searches. Free searches use unlimited-age shared cache. Setting enabled false limits reuse to five minutes. All cacheable requests have a five-minute minimum, including shorter ttlHours values. Paid dedicated Markdown responses are cached privately per account.", "type": "object", "properties": { "enabled": { "default": true, "type": "boolean" }, "ttlHours": { "default": 24, "anyOf": [ { "type": "number", "exclusiveMinimum": 0, "maximum": 87600 }, { "type": "null" } ] } } }, "scraper": { "default": "auto", "type": "string", "enum": [ "auto", "scrapingdog", "scrapingbee" ] }, "timeoutMs": { "default": 45000, "type": "integer", "minimum": 5000, "maximum": 60000 } }, "additionalProperties": {} }, "annotations": { "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } } ] } ```