> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.auxiliar.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.auxiliar.ai/_mcp/server.

# Serper

Proxies [Serper](https://serper.dev). One Serper key spans many Google SERP verticals, each its own endpoint, plus a webpage scraper. The gateway exposes them all under `/serper`, injecting the secret `X-API-KEY` header.

```
GET|POST /serper                 → https://google.serper.dev/search   (alias)
GET|POST /serper/<endpoint>       → https://google.serper.dev/<endpoint>
GET|POST /serper/webpage          → https://scrape.serper.dev/
```

Bare `/serper` is kept as an alias for `/serper/search` — Serper's original single-endpoint contract — so existing clients keep working.

## Endpoints

The gateway accepts exactly this whitelist; any other subpath returns the gateway's `404` without reaching Serper.

| Endpoint                                                                                                                    | Upstream                               |
| --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| `search`, `images`, `videos`, `places`, `maps`, `reviews`, `news`, `shopping`, `lens`, `scholar`, `patents`, `autocomplete` | `https://google.serper.dev/<endpoint>` |
| `webpage`                                                                                                                   | `https://scrape.serper.dev/`           |

Serper's `/account` endpoint (remaining credit balance) is **deliberately not proxied** — it's account-wide billing metadata, not a search interface, and per-client tokens have no business reading the shared balance.

## Request forms

Serper accepts two request forms, and both are forwarded:

* **`POST` with a JSON body** — the form Serper's docs lead with. A JSON **array** body (batched search) is forwarded like any other body.
* **`GET` with controls in the query string** — passed through byte-for-byte.

A client-supplied `apiKey` query param is dropped and a client `X-API-KEY` header is overwritten, so the injected key is the only credential Serper sees. The `Authorization` header (your gateway token) is stripped before forwarding.

## Examples

```bash
curl -X POST "$GATEWAY/serper" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"q": "apple inc", "gl": "us", "hl": "en"}'
```

```bash
curl -X POST "$GATEWAY/serper/news" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"q": "cloudflare workers"}'
```

```bash
curl "$GATEWAY/serper/search?q=apple+inc&gl=us" \
  -H "Authorization: Bearer $TOKEN"
```

```bash
curl -X POST "$GATEWAY/serper/webpage" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
```

```bash
curl -X POST "$GATEWAY/serper/search" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '[{"q": "apple inc"}, {"q": "google llc"}]'
```

The response is Serper's JSON, returned unchanged. For request and response fields, follow [Serper's documentation](https://serper.dev) — the gateway does not alter them.