Search.
One endpoint for all thirteen engines. Authenticated, metered, normalized.
POST https://metasearch.sh/api/v1/search
Authorization: Bearer ms_live_…
Content-Type: application/jsonAuthentication is a bearer API key minted in the dashboard. A missing or invalid key returns 401 invalid_api_key.
Request body
| field | type | description |
|---|---|---|
| query | string, required | What to search for. For extract, scrape, and similar modes, pass a full http(s) URL instead of a query. |
| mode | string, optional | One of the 13 modes below. Defaults to general. |
| provider | string, optional | Force a specific engine, e.g. "exa". Omit to let the router choose. |
| count | integer, optional | Desired number of results. Providers may cap it. |
Modes
| mode | what it does |
|---|---|
| general | broad web search |
| news | recent coverage, news indexes |
| academic | papers and scholarly sources |
| people | find people and profiles |
| deep | multi-step deep research with sources |
| extract | clean text from a URL (query is the URL) |
| similar | pages similar to a URL (query is the URL) |
| scrape | raw page fetch, headless or stealth (query is the URL) |
| scholar | Google Scholar results |
| patents | patent search |
| images | image search |
| places | local places and maps |
| social | X/Twitter and social content |
Which engines serve which mode is on Providers & modes.
Provider selection
If you pass provider, it is validated strictly: the name must exist (400 unknown_provider, response lists valid_providers), the provider must support the requested mode (400 provider_mode_mismatch, response lists its supported_modes), and it must be configured on the server (503 provider_not_available).
If you omit provider, the router dispatches to the first configured engine in the mode's priority list — the same fallback-chain ordering search-cli uses. If no configured provider supports the mode, you get 503 no_provider_for_mode.
Your balance is checked before dispatch: at $0.00 or below, the call is refused with 402 insufficient_credits and nothing is sent upstream.
Response
| field | description |
|---|---|
| request_id | UUID for this call. Also stamped on your usage ledger, and included in error responses for failed upstream calls. |
| provider | The engine that actually served the request. |
| mode | The mode that was executed. |
| results[] | Normalized items: title, url, snippet, plus an optional extra object with provider-specific fields (published date, author, image URL, …). |
| billing.charged_usd | What this call cost you, in USD. |
| billing.balance_usd | Your remaining credit after the charge. |
Limits & failures
Requests run for at most 90 seconds — enough for deep-research modes, but plan client timeouts accordingly. If the upstream engine fails, you get 502 provider_error with the request_id and the upstream message; unexpected server faults return 500 internal_error. Failed calls are recorded but never billed.