# serpcheap
[](https://hex.pm/packages/serpcheap)
Elixir client for the [serp.cheap](https://serp.cheap) **Google Search API** — real-time Google SERP data (organic results, ads, knowledge graph, page scraping, rank tracking). Phoenix-friendly: configure it via application env and call it from your contexts.
The **cheapest Google Search API** we know of: $0.0003 per cached search, $0.0006 fresh, no monthly minimum (~10× cheaper than SerpApi). Dependency-light — built on Erlang's `:httpc` + `Jason`.
## Install
```elixir
# mix.exs
def deps do
[{:serpcheap, "~> 0.1"}]
end
```
Configure your API key (get one at [app.serp.cheap](https://app.serp.cheap)):
```elixir
# config/runtime.exs
config :serpcheap, api_key: System.get_env("SERPCHEAP_API_KEY")
```
## Usage
```elixir
{:ok, results} = SerpCheap.search("best running shoes", gl: "us")
{:ok, page} = SerpCheap.scrape("https://example.com")
{:ok, rank} = SerpCheap.rank("example.com", "best running shoes")
```
Every function returns `{:ok, map}` or `{:error, %SerpCheap.Error{}}`. The `!` variants (`search!/2`, `scrape!/2`, `rank!/3`) return the map or raise.
In a Phoenix app, call it straight from a context:
```elixir
defmodule MyApp.Search do
def run(query), do: SerpCheap.search(query, gl: "us")
end
```
## Options
Options can be set globally in config or overridden per call:
| Option | Default | Description |
| --- | --- | --- |
| `:api_key` | `config :serpcheap` | API key (required) |
| `:base_url` | `https://api.serp.cheap` | API base URL |
| `:timeout_ms` | `15000` | Per-request timeout |
| `:max_retries` | `2` | Retries on transient errors (429/503/timeout) |
Search/rank also take `:gl`, `:hl`, `:tbs`, `:page`/`:pages`, `:match_type`; scrape takes `:render_js`, `:screenshot`, `:wait_for`, `:wait_ms`.
```elixir
SerpCheap.search("shoes", gl: "br", hl: "pt", page: 2, api_key: "override")
```
## License
MIT