# Perplexed v0.2.0 - API Reference

## Modules

- [Perplexed](Perplexed.md): A small web search, scrape and research toolkit, in the spirit of Firecrawl
or Exa.

- Search
  - [Perplexed.Search](Perplexed.Search.md): Swappable web search: every provider takes a query and returns normalized
`Perplexed.Search.Hit`s, so callers change engines by changing one option.
Built-in providers, by name, with list price per successful request (USD,
as of 2026-11-10) used for per-run cost accounting
  - [Perplexed.Search.Cloudflare](Perplexed.Search.Cloudflare.md): Cloudflare Web Search API (through AI Gateway) as a `Perplexed.Search` provider.
  - [Perplexed.Search.DeepSeek](Perplexed.Search.DeepSeek.md): DeepSeek Search API (`POST /v1/tools/search`) as a `Perplexed.Search` provider.
  - [Perplexed.Search.Fallback](Perplexed.Search.Fallback.md): Opt-in provider fallback: a list of provider specs, tried in order until
one answers, such as free first and paid last
  - [Perplexed.Search.Firecrawl](Perplexed.Search.Firecrawl.md): Firecrawl v2 search as a `Perplexed.Search` provider.
  - [Perplexed.Search.Fusion](Perplexed.Search.Fusion.md): Merges ranked hit lists from several sources (SearXNG instances, search
engines) into one list: de-duplicates by normalized URL, scores by
reciprocal rank, boosts hits several engines agree on, and demotes hits
that share no terms with the query.
  - [Perplexed.Search.Hit](Perplexed.Search.Hit.md): One search result, normalized across providers.
  - [Perplexed.Search.Result](Perplexed.Search.Result.md): One search call: the hits, the provider that answered, and what it cost.
  - [Perplexed.Search.SearXNG](Perplexed.Search.SearXNG.md): Keyless web search through SearXNG metasearch instances, as a
`Perplexed.Search` provider (`:searxng`). Free: price 0.
  - [Perplexed.Search.SearXNG.Directory](Perplexed.Search.SearXNG.Directory.md): Picks public SearXNG instances from searx.space's daily health check
(`https://searx.space/data/instances.json`).
  - [Perplexed.Search.SearXNG.Instances](Perplexed.Search.SearXNG.Instances.md): The live set of public SearXNG instances, discovered instead of
hard-coded. Set `searxng_instances: :auto` and `Perplexed.Search.SearXNG`
asks this store for its instances.
  - [Perplexed.Search.SearXNG.Pool](Perplexed.Search.SearXNG.Pool.md): Health, speed and rate-limit state for SearXNG instances, learned from the
searches this node makes. One pool runs under the `:perplexed` application;
tests and hosts can start more with `:name`.

- Scrape
  - [Perplexed.Document](Perplexed.Document.md): One scraped page as Markdown, with how it was obtained.
  - [Perplexed.PdfConverter](Perplexed.PdfConverter.md): The behaviour that turns PDF bytes into Markdown for a scrape.
  - [Perplexed.Scrape](Perplexed.Scrape.md): Scrapes a URL to Markdown by climbing a ladder of `Perplexed.Scraper`s,
cheapest first.
  - [Perplexed.Scraper](Perplexed.Scraper.md): The behaviour of one scrape tier, and the registry of built-in tiers.
  - [Perplexed.Scraper.BrowserRun](Perplexed.Scraper.BrowserRun.md): Cloudflare Browser Run `/markdown` quick action as a `Perplexed.Scraper`:
loads the URL in headless Chrome, runs its JavaScript, and returns the
rendered page as Markdown.
  - [Perplexed.Scraper.DeepSeek](Perplexed.Scraper.DeepSeek.md): DeepSeek Fetch API (`POST /v1/tools/fetch`) as a `Perplexed.Scraper`:
DeepSeek fetches the URL and returns the page as Markdown.
  - [Perplexed.Scraper.Direct](Perplexed.Scraper.Direct.md): Plain HTTP as a `Perplexed.Scraper`, sending browser-like request headers.
Free and fast; the first tier of the default ladder.

  - [Perplexed.Scraper.Firecrawl](Perplexed.Scraper.Firecrawl.md): Firecrawl v2 scrape as a `Perplexed.Scraper`.
  - [Perplexed.Scraper.Impersonated](Perplexed.Scraper.Impersonated.md): HTTP through `CloakedReq` (Rust wreq) as a `Perplexed.Scraper`: the
request carries a real browser's TLS and HTTP/2 fingerprint and headers,
which gets past sites that refuse plain clients on that signal alone.
  - [Perplexed.Verdict](Perplexed.Verdict.md): Judges whether fetched page text is worth handing to a model.

- Answer
  - [Perplexed.Answer](Perplexed.Answer.md): The result of `Perplexed.answer/2`.
  - [Perplexed.Answer.Candidate](Perplexed.Answer.Candidate.md): One unique search hit an answer considered.
  - [Perplexed.Answer.Source](Perplexed.Answer.Source.md): One page an answer was written from. `number` is its citation number;
`tier` is the scraper that read it and `cost` what reading it cost.

  - [Perplexed.Passages](Perplexed.Passages.md): Chooses which parts of a long page a model gets to read.
  - [Perplexed.Pipeline](Perplexed.Pipeline.md): One-shot web answering, in fixed steps

- Infrastructure
  - [Perplexed.Config](Perplexed.Config.md): Perplexed's settings.
  - [Perplexed.Telemetry](Perplexed.Telemetry.md): `:telemetry` events Perplexed emits. Attach handlers to track spend or to
be told when a provider needs attention.
  - [Perplexed.UrlGuard](Perplexed.UrlGuard.md): Refuses URLs that would point a scrape at a private network.

## Mix Tasks

- [mix perplexed.searxng.instances](Mix.Tasks.Perplexed.Searxng.Instances.md): Fetches today's public SearXNG instances from searx.space, probes each
start page from this machine, and prints which are up, fastest first.
- [mix tidewave](Mix.Tasks.Tidewave.md): Starts the app and serves Tidewave's MCP at
`http://localhost:<port>/tidewave/mcp` so a coding agent can evaluate code
inside the running project. Tidewave ships only as a Phoenix plug, so this
runs that plug under Bandit for a library with no endpoint.

