Quickstart.
Key to first results in five steps. No SDK required — it is one HTTPS endpoint.
01Sign in
Go to metasearch.sh/login and enter your email. You get a magic link — no password to invent or forget.
02Mint a key
In the dashboard, create an API key. It starts with ms_live_ and is shown once — copy it into your environment, not your codebase.
$ export METASEARCH_API_KEY="ms_live_…"Using search-cli? Skip the copy-paste: search login opens the browser, you approve, and the key is stored for you.
03Top up credits
Add credits from the dashboard (Stripe checkout, fixed USD amounts). Credits are prepaid dollars. No subscription, and they do not expire. Each call deducts its exact metered price.
04Make your first request
$ curl https://metasearch.sh/api/v1/search \ -H "Authorization: Bearer $METASEARCH_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "solid-state batteries", "mode": "news", "count": 5}'
{
"request_id": "d80da58d-2b59-4be1-9c3e-…",
"provider": "parallel",
"mode": "news",
"results": [
{
"title": "Solid-state batteries clear a manufacturing hurdle",
"url": "https://…",
"snippet": "…",
"published": "2026-07-01"
}
],
"billing": {
"charged_usd": 0.0075,
"balance_usd": 4.9925
}
}Every successful response carries billing.charged_usd (what this call cost you) and billing.balance_usd (what remains). Failed calls return an error and charge nothing.
05Check status before you route
Providers go down. The status page probes every engine with a real billed request every 30 minutes, and GET /api/v1/providers returns the same health data as JSON — availability, per-call price, and last check per provider. If you pin a provider in your requests, consult it first; if you omit it, the router only considers configured engines anyway.
From code
import os, requests
r = requests.post(
"https://metasearch.sh/api/v1/search",
headers={"Authorization": f"Bearer {os.environ['METASEARCH_API_KEY']}"},
json={"query": "solid-state batteries", "mode": "news", "count": 5},
timeout=90,
)
r.raise_for_status()
data = r.json()
print(data["provider"], data["billing"]["charged_usd"])
for hit in data["results"]:
print(hit["title"], hit["url"])const res = await fetch("https://metasearch.sh/api/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.METASEARCH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "solid-state batteries", mode: "news", count: 5 }),
});
if (!res.ok) throw new Error(`search failed: ${res.status}`);
const data = await res.json();
console.log(data.provider, data.billing.charged_usd);