Run your first OpenSERP Cloud request in a few minutes. Pick the JavaScript SDK, the Python SDK, or call the HTTP API directly with curl or fetch — all four use the same endpoints.
1. Create an API key
Open API keys, create a key, and copy the secret. It looks like:
osk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
You only see the full secret once. Store it in an environment variable or a secrets manager and never commit it.
Want to see results without writing code first? The Search Playground lets you pick an engine, run a query, inspect the response, and copy a working
curl.
2. Make a request
Pick whichever runs in the codebase you are building.
JavaScript / TypeScript
npm install @openserp/sdk
import { OpenSERP } from "@openserp/sdk";
const client = new OpenSERP({ apiKey: process.env.OPENSERP_KEY });
const response = await client.search({
engine: "google",
text: "openserp",
limit: 5,
region: "US",
});
for (const result of response.results) {
console.log(result.rank, result.title, result.url);
}
console.log("credits remaining:", client.lastResponse?.credits?.remaining);
Works in Node 18+, Bun, Deno, Cloudflare Workers, Vercel Edge, and any runtime with global fetch.
Python
pip install openserp
import os
from openserp import OpenSERP
client = OpenSERP(api_key=os.environ["OPENSERP_KEY"])
response = client.search(engine="google", text="openserp", limit=5, region="US")
for result in response.results:
print(result.rank, result.title, result.url)
print("credits remaining:", client.last_response.credits.remaining)
curl
curl "https://api.openserp.org/v1/google/search?text=openserp&limit=5®ion=US" \
-H "Authorization: Bearer $OPENSERP_KEY"
JavaScript fetch
const url = new URL("https://api.openserp.org/v1/google/search");
url.search = new URLSearchParams({
text: "openserp",
limit: "5",
region: "US",
}).toString();
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OPENSERP_KEY}` },
});
if (!res.ok) {
throw new Error(`OpenSERP ${res.status}: ${await res.text()}`);
}
const data = await res.json();
console.log(data.results);
Running the open-source server locally? Use the same SDK code with
baseUrl: "http://localhost:7000"and no API key.
3. Try multi-engine search
When one engine isn’t enough, query several at once. There’s a single endpoint with three behaviors — pick the one that matches your cost/coverage trade-off:
| Method | What it does | Billing |
|---|---|---|
megaSearch |
Queries every engine in parallel, merges and deduplicates into one list | 1 credit per engine |
fastSearch |
Tries engines one at a time (healthiest first), returns the first success | 1 credit |
anySearch |
Like fastSearch, but tries engines in the order you list them |
1 credit |
Use megaSearch for the broadest coverage in a single call:
const response = await client.megaSearch({
text: "openserp api",
engines: ["google", "bing", "duckduckgo"],
limit: 20,
});
console.log(response.results.length, "merged results");
console.log("credits used:", client.lastResponse?.credits?.used);
When you want one successful response and predictable 1-credit billing instead, use fastSearch (low-latency engine first) or anySearch (your preferred order):
const response = await client.fastSearch({
text: "openserp api",
engines: ["google", "bing", "duckduckgo"],
limit: 10,
});
console.log("served by:", client.lastResponse?.engineUsed);
console.log(response.results);
The raw HTTP equivalent:
curl "https://api.openserp.org/v1/mega/search?text=openserp+api&mode=fast&engines=google,bing,duckduckgo&limit=10" \
-H "Authorization: Bearer $OPENSERP_KEY"
4. Read the response
Every search returns the same envelope:
{
"query": { "text": "openserp", "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": "OpenSERP - open-source SERP API",
"url": "https://openserp.org/",
"display_url": "openserp.org",
"snippet": "OpenSERP is an API and CLI for search engine results.",
"domain": "openserp.org",
"position": { "absolute": 1 },
"engine": "google"
}
]
}
Any/Fast responses also include meta.engine_used, meta.engines_tried, and the X-Engine-Used header so you know which engine served the request.
5. Track credits
Every billable response includes three headers:
| Header | Meaning |
|---|---|
X-Credits-Used |
Credits charged for this request |
X-Credits-Remaining |
Account balance after this request |
X-Engine-Used |
Engine used by Any/Fast routing |
In the JavaScript SDK, read them from client.lastResponse:
console.log(client.lastResponse?.credits?.used);
console.log(client.lastResponse?.credits?.remaining);
console.log(client.lastResponse?.engineUsed);
console.log(client.lastResponse?.requestId);
Always include requestId in error reports — it lets support trace the exact call.
Next steps
- Endpoints reference — every endpoint and parameter, with SDK and HTTP examples.
- Authentication — key storage and rotation.
- Errors & rate limits — retry behavior and failure handling.