OpenSERP Cloud Updated Quickstart →

Endpoints Reference

Every Cloud endpoint is a JSON API under: Search endpoints are GET requests and require the bearer auth from Authentication. The official SDKs call these sam...

Every Cloud endpoint is a JSON API under:

https://api.openserp.org

Search endpoints are GET requests and require the bearer auth from Authentication. The official SDKs call these same endpoints for you — when an example is shown for both, pick whichever fits your codebase.

Endpoint map

Endpoint Use when
GET /v1/{engine}/search You want web results from one engine.
GET /v1/{engine}/image You want image results from one engine.
GET /v1/mega/search?mode=balanced You want merged, deduplicated web results from multiple engines.
GET /v1/mega/image?mode=balanced You want merged image results from multiple engines.
GET /v1/mega/search?mode=any You want one good web response, engines tried in your order.
GET /v1/mega/search?mode=fast You want a low-latency web response from a healthy engine.
GET /v1/mega/image?mode=any | ?mode=fast First-successful or low-latency image routing.
GET /v1/extract You want clean, LLM-ready content from one URL.
POST /v1/extract/batch You want clean content from up to 20 URLs in one request.
GET /v1/me Validate a key or read the account balance.
GET /v1/engines/status User-facing engine health and latency.
GET /v1/engines/capabilities Supported web/image capability matrix.

Supported engines: google, bing, yandex, baidu, duckduckgo (alias duck), ecosia.

Use this when you know which engine you want.

JavaScript SDK

const response = await client.search({
  engine: "google",
  text: "golang",
  limit: 10,
  region: "US",
  lang: "EN",
});

for (const r of response.results) {
  console.log(r.rank, r.title, r.url);
}

Python SDK

response = client.search(engine="google", text="golang", limit=10, region="US", lang="EN")

for r in response.results:
    print(r.rank, r.title, r.url)

HTTP

curl "https://api.openserp.org/v1/google/search?text=golang&limit=10&region=US&lang=EN" -H "Authorization: Bearer $OPENSERP_API_KEY"

Common search parameters

Parameter Type Default Description
text string required Search query.
limit integer 10 Maximum results, 1 to 100. A limit over 10 can return multiple SERP pages where available; single-engine web search bills ceil(returned web results / 10), not query count.
start integer 0 Nonnegative result offset. Support and step size depend on the engine. See Pagination.
lang string optional Language code such as EN, DE, RU, ES, FR, ZH.
region string US Country/region code such as US, GB, DE, RU.
date string optional Date range YYYYMMDD..YYYYMMDD, e.g. 20250101..20251231. Google and Ecosia only.
site string optional Restrict to a domain, e.g. github.com.
file string optional Restrict to a file type, e.g. pdf.
features boolean true Return serp_features (AI Overview, answer boxes, people also ask, related searches) when the page has them. false returns an empty array. Same flag and default as OpenSERP OSS.

Not every engine supports every filter — treat lang, site, and file as best-effort outside Google. start and date are strict: if the engine can’t serve them, the request fails with 400 invalid_request (for example “date is not supported for this engine.”) and isn’t charged.

Engine start date
Google Yes, multiples of 10 Yes
Bing Yes, multiples of 10 No
Yandex Yes, multiples of 10 No
Baidu First few pages No
Ecosia Yes Yes
DuckDuckGo No No

Response envelope

Search responses always use the same query, meta, results, pagination shape:

{
  "query": { "text": "golang", "engines_requested": ["google"] },
  "meta": {
    "request_id": "019dc6c1-da45-706e-a57c-d671fa2862ee",
    "requested_at": "2026-05-12T18:30:00Z",
    "took_ms": 642
  },
  "results": [
    {
      "id": "google-1",
      "rank": 1,
      "type": "organic",
      "title": "The Go Programming Language",
      "url": "https://go.dev/",
      "display_url": "go.dev",
      "snippet": "Go is an open source programming language.",
      "domain": "go.dev",
      "position": { "absolute": 1 },
      "engine": "google"
    }
  ],
  "pagination": { "page": 1, "has_more": true, "next_start": 10 }
}

Web result fields include title, url, snippet, domain, type, position, and engine. Image results use the same envelope and add image-specific fields described below.

Use mode=balanced for broader coverage with one deduplicated list.

JavaScript SDK

const response = await client.megaSearch({
  text: "openserp api",
  engines: ["google", "bing", "duckduckgo"],
  limit: 20,
  region: "US",
});

console.log(response.results.length, "merged results");
console.log("credits used:", client.lastResponse?.credits?.used);

HTTP

curl "https://api.openserp.org/v1/mega/search?text=openserp+api&mode=balanced&engines=google,bing,duckduckgo&limit=20&region=US" -H "Authorization: Bearer $OPENSERP_API_KEY"

Mega parameters

Parameter Type Description
engines comma-separated list Engines to query, e.g. google,bing,yandex. Omit to use the default engine set.
mode enum balanced, any, or fast. Defaults to balanced.
features boolean Return merged serp_features. Defaults to true; false returns an empty array, as in OpenSERP OSS.

Mega endpoints are billed dynamically from the engines that successfully return data. Image endpoints are billed by returned image volume. Use X-Credits-Used (or client.lastResponse?.credits?.used) as the source of truth.

Any and Fast routing

These modes return one successful response and bill a predictable 1 credit. Use them when you want resilience without merged coverage.

Mode Behavior
any Tries engines in your order. If one is slow, the next starts a few seconds later, and the first good result wins.
fast Same race, with engines ordered by recent health and latency.

Both answer within about 15 seconds. start is passed through on any and fast; balanced mega rejects start above 0 with 400.

JavaScript SDK

const fast = await client.fastSearch({
  text: "golang",
  engines: ["google", "bing", "duckduckgo"],
  limit: 10,
});
console.log("served by:", client.lastResponse?.engineUsed);

const any = await client.anySearch({
  text: "golang",
  engines: ["google", "bing", "duckduckgo"],
  limit: 10,
});
console.log("served by:", client.lastResponse?.engineUsed);

HTTP

curl "https://api.openserp.org/v1/mega/search?text=golang&mode=fast&engines=google,bing,duckduckgo&limit=10" -H "Authorization: Bearer $OPENSERP_API_KEY"

Any/Fast success responses include meta.engine_used and the X-Engine-Used header. engines_tried and engines_skipped may be absent. If every requested engine fails, the response is 502 and isn’t charged. If every engine rejects the requested paging or date filter, the response is 400 invalid_request without charge. See Errors & rate limits.

Image endpoints take text, limit, and region (plus engines and mode on mega).

Single-engine

const images = await client.image({
  engine: "bing",
  text: "golang logo",
  limit: 10,
});

for (const img of images.results) {
  console.log(img.title, img.image_url, `${img.width}x${img.height}`);
}
curl "https://api.openserp.org/v1/bing/image?text=golang+logo&limit=10" -H "Authorization: Bearer $OPENSERP_API_KEY"

Multi-engine

const merged = await client.megaImage({
  text: "golang logo",
  engines: ["bing", "google"],
  limit: 20,
});

const fastImg = await client.fastImage({
  text: "golang logo",
  engines: ["bing", "google"],
  limit: 10,
});

const anyImg = await client.anyImage({
  text: "golang logo",
  engines: ["bing", "google"],
  limit: 10,
});

Image result fields

Image results extend the standard envelope with:

Field Description
image_url Direct URL to the full-size image.
thumbnail_url URL for a smaller preview.
source_url Page where the image is hosted.
width, height Image dimensions in pixels (when known).
title, snippet Caption and surrounding context.

URL extraction

GET /v1/extract fetches one URL and returns clean, LLM-ready markdown, text, and page metadata.

JavaScript SDK

const page = await client.extract({
  url: "https://openserp.org/docs",
  mode: "auto",
});

console.log(page.markdown);

cURL

curl -H "Authorization: Bearer $OPENSERP_API_KEY" "https://api.openserp.org/v1/extract?url=https://openserp.org/docs&mode=auto"

Many URLs at once

POST /v1/extract/batch extracts up to 20 URLs concurrently and returns one item per URL. A URL that fails becomes an item with an error rather than failing the request, so one dead link never costs you the other results:

curl -X POST -H "Authorization: Bearer $OPENSERP_API_KEY" -H "Content-Type: application/json" -d '{"urls":["https://openserp.org/docs","https://openserp.org/blog"],"mode":"auto"}' "https://api.openserp.org/v1/extract/batch"
const batch = await client.batchExtract({
  urls: ["https://openserp.org/docs", "https://openserp.org/blog"],
  mode: "auto",
});

for (const item of batch.results ?? []) {
  if (item.error) console.warn(item.url, "failed:", item.error);
  else console.log(item.url, item.page_content?.slice(0, 120));
}

Billing is per URL and matches calling /v1/extract that many times: successful extractions bill their mode, while failed and empty ones are free. A batch reserves its worst case up front and returns the unused remainder when it finishes, so a large batch can be refused for insufficient credits even when the real charge would be smaller.

Extracting from a specific region

Pass region (a two-letter country code) to extract as a visitor from that country - useful for geo-fenced or localized pages. It applies to every URL in a batch and adds 1 credit per successfully extracted URL:

curl -H "Authorization: Bearer $OPENSERP_API_KEY" "https://api.openserp.org/v1/extract?url=https://example.com/pricing&region=DE"

Omit region to extract at the base rate. Unlike search, extraction accepts country codes only - not city names or numeric region IDs.

Pagination

Use start to request later result pages. For Google, Bing, and Yandex, keep limit at 10 (or a multiple of 10) and pass the previous response’s pagination.next_start:

async function paginate(text: string, pages = 3) {
  const all = [];
  let start = 0;
  for (let i = 0; i < pages; i += 1) {
    const page = await client.search({ engine: "google", text, limit: 10, start });
    all.push(...page.results);
    if (!page.pagination?.has_more || page.results.length === 0) break;
    start = page.pagination.next_start;
  }
  return all;
}

const results = await paginate("openserp");
console.log(results.length);

pagination is computed from your request: page is floor(start / limit) + 1, has_more is true while a page returns results (unless the engine reports the last page), and next_start is start + limit when has_more is true, otherwise 0. has_more is a continuation hint; it does not guarantee a nonempty next page. An offset the engine can’t serve (see the table under Common search parameters) returns 400 invalid_request and isn’t charged.

Each page is a separate billable request, and a later page costs the same as the first. Watch X-Credits-Used and X-Credits-Remaining on long pagination jobs.

Account and capability endpoints

These endpoints are free to call.

GET /v1/me

The account associated with the API key and the current credit balance.

const account = await client.me();
console.log(account.email, account.credits_remaining);
{ "email": "[email protected]", "credits_remaining": 4250 }

GET /v1/pricing

Live credit pricing. Fetch it from your own app when you want to display expected cost without hardcoding values.

const pricing = await client.pricing();
console.log(pricing.credit_price_usd, pricing.search.credits);

Use GET /v1/pricing as the source of truth for current per-call credit costs — values may change while pricing is being finalized.

GET /v1/engines/status

User-facing operational status and recent latency signals.

const status = await client.enginesStatus();
console.log(status);
{
  "engines": {
    "google": { "status": "operational", "latency_ms": 420 },
    "yandex": { "status": "loaded", "latency_ms": 710 }
  }
}

Status values:

  • operational - engine is delivering results.
  • loaded - engine is delivering results under load.
  • down - currently unavailable.

Idle engines retain their last known status across restarts.

Without an API key, the response contains only { "overall": "operational" }, with overall one of operational, degraded, or down. Per-engine details require Authorization: Bearer authentication.

GET /v1/engines/capabilities

Currently supported web and image capabilities.

const caps = await client.enginesCapabilities();
console.log(caps.engines?.google);
{
  "engines": {
    "google": { "web": true, "image": true }
  },
  "modes": {
    "any": { "web": true, "image": true },
    "fast": { "web": true, "image": true },
    "mega": { "web": true, "image": true }
  }
}

Response telemetry

Every billable response includes:

Header SDK accessor Meaning
X-Request-Id client.lastResponse?.requestId Unique request ID — quote in support tickets.
X-Credits-Used client.lastResponse?.credits?.used Credits charged for this request.
X-Credits-Remaining client.lastResponse?.credits?.remaining Account balance after the request.
X-Engine-Used client.lastResponse?.engineUsed Engine used by Any/Fast routing.

Next