```yaml
product: AlterLab
title: /v1/search to /v1/serp
category: migrations
comparison_context: "AlterLab is an alternative to Firecrawl, ScrapingBee, and Bright Data."
source_url: https://alterlab.io/docs/migrations/search-to-serp
```

# /v1/search to /v1/serp

`/v1/serp` is the single search endpoint. `/v1/search` and `/v1/search/batch` keep working as deprecated aliases with identical billing.

## Deprecation Timeline

- **Now:** the alias endpoints respond normally and add a `Deprecation: true` header plus `Link` headers pointing to `/api/v1/serp` (`rel="successor-version"`) and to this guide (`rel="deprecation"`).
- **Removal:** no removal date has been set, so responses carry no `Sunset` header yet. Existing integrations keep working until one is published.

## Parameter Mapping

| /v1/search | /v1/serp | Notes |
|---|---|---|
| `POST /api/v1/search` | `POST /api/v1/serp` | Single query |
| `POST /api/v1/search/batch` | `POST /api/v1/serp/batch` | Up to 50 queries; optional `webhook_url` |
| `engine` | `search_engine` (alias: `engine`) | Default differs, see below |
| `num_results`, `page` | `num_results` (alias: `num`), `start` or `page` | Window |
| `country`, `language`, `safe_search` | `country`, `language`, `safe_search` | Same |
| `results[]` | `organic_results[]` | Response field name |

> **Default engine:** `/v1/search` defaults to `duckduckgo` ($0.001/query); `/v1/serp` defaults to `google` ($0.004/query). Send `search_engine` explicitly to keep your current engine.

## Billing

Billing is identical on both surfaces: $0.001 per DuckDuckGo query and $0.004 per Google or Bing query, charged at the requested engine. Switching endpoints changes no price.

## Code Migration

```python
import requests

resp = requests.post(
    "https://api.alterlab.io/api/v1/serp",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"query": "headless browsers", "search_engine": "duckduckgo", "num_results": 10},
)
for result in resp.json()["organic_results"]:
    print(result["position"], result["title"], result["url"])
```

The Python and Node SDKs already send eligible requests to `/v1/serp`; `client.search()` keeps its `duckduckgo` default.

## Not Yet on /v1/serp

`scrape_results`, `domain` and `time_range` are currently served only by the `/v1/search` alias. Keep using the alias for those requests.
