> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl-claude-eager-dijkstra-u6tgua.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Elixir Agent Quickstart

> Canonical Firecrawl Elixir quickstart for external agents using search, scrape, and interact.

# Firecrawl Elixir Agent Quickstart

Canonical Firecrawl Elixir quickstart for external agents. Generated from SDK source (`firecrawl` hex package v1.9.1) and the v2 OpenAPI spec. The Elixir SDK is auto-generated from the OpenAPI spec.

## Install

Add to `mix.exs`:

```elixir theme={null}
{:firecrawl, "~> 1.9"}
```

## Authenticate

```elixir theme={null}
# config/runtime.exs or config.exs
config :firecrawl, api_key: System.get_env("FIRECRAWL_API_KEY")

# or pass api_key per call
{:ok, res} = Firecrawl.search_and_scrape(
  [query: "site:docs.firecrawl.dev webhook retries"],
  api_key: "fc-your-api-key"
)
```

There is no client struct or process. The SDK is a single flat module (`Firecrawl`) with module-level functions. Auth is configured globally via application config or per-call via opts. All functions also accept `:base_url` in opts to override the default API URL.

The API key may be omitted for keyless free-tier access (rate-limited per IP) on scrape, search, and interact.

## When To Use What

* `search`: use when you start with a query and need discovery.
* `scrape`: use when you already have a URL and want page content.
* `interact`: use when the page needs clicks, forms, or post-scrape browser actions.

## Search

### Why use it

Discover relevant pages from a query, then pick URLs to scrape or interact with. Constrain results to a site with `site:`.

### Preferred SDK method

`Firecrawl.search_and_scrape(params \\ [], opts \\ [])`

### Example

```elixir theme={null}
{:ok, res} = Firecrawl.search_and_scrape(
  query: "site:docs.firecrawl.dev webhook retries",
  limit: 5,
  scrape_options: [
    formats: ["markdown"],
    only_main_content: true
  ]
)
```

### Parameters

Parameters are passed as a keyword list. Snake\_case keys are auto-converted to camelCase for the API.

* `query` — string (required). The search query.

* `sources` — list. Sources to search. Default: `["web"]`. Values: `:web`, `:news`, `:images`, or `%{type: "web"}` maps.

* `categories` — list. Category filter. Values: `:github`, `:research`, `:pdf`, or typed maps.

* `include_domains` — list of strings. Restrict results to these domains.

* `exclude_domains` — list of strings. Exclude results from these domains.

* `limit` — integer. Maximum results to return.

* `tbs` — string. Time-based filter (e.g. `"qdr:d"`, `"qdr:w"`).

* `location` — string. Geographic location for localized results.

* `country` — string. ISO 3166-1 alpha-2 code for geo-targeting (e.g. `"US"`).

* `ignore_invalid_urls` — boolean. Drop URLs that cannot be scraped.

* `highlights` — boolean. Generate query-relevant highlights. Default: true.

* `timeout` — integer. Request timeout in milliseconds.

* `enterprise` — list of strings. Enterprise options: `["zdr"]` for zero data retention, `["anon"]` for anonymized.

* `scrape_options` — keyword list. Options for scraping each search result (same fields as scrape).

## Scrape

### Why use it

Get structured content from a URL in one or more formats.

### Preferred SDK method

`Firecrawl.scrape_and_extract_from_url(params \\ [], opts \\ [])`

### Example

```elixir theme={null}
{:ok, res} = Firecrawl.scrape_and_extract_from_url(
  url: "https://example.com/pricing",
  formats: [
    "markdown",
    "links",
    %{type: "json", prompt: "Extract plan names and prices."}
  ],
  only_main_content: true
)
```

### Parameters

* `url` — string (required). The URL to scrape.

* `formats` — list of format strings or format maps. Output formats.
  * String formats: `"markdown"`, `"html"`, `"rawHtml"`, `"links"`, `"images"`, `"screenshot"`, `"summary"`, `"changeTracking"`, `"json"`, `"branding"`, `"audio"`, `"video"`
  * Map formats: `%{type: "json", prompt: "..."}`, `%{type: "screenshot", fullPage: true}`, `%{type: "changeTracking", modes: ["git-diff"]}`

* `headers` — map. Custom HTTP headers.

* `include_tags` — list of strings. Only include content from these HTML tags.

* `exclude_tags` — list of strings. Exclude content from these HTML tags.

* `only_main_content` — boolean. Strip nav, footer, and other boilerplate.

* `timeout` — integer. Timeout in milliseconds. Default: 60000, min: 1000, max: 300000.

* `wait_for` — integer. Wait for page to render (milliseconds).

* `mobile` — boolean. Emulate mobile viewport.

* `parsers` — list. Values: `"pdf"` or `%{type: "pdf", mode: "auto", maxPages: 5}`.

* `actions` — list of action maps. Pre-scrape browser actions.
  * `%{type: "click", selector: "#btn"}`
  * `%{type: "wait", milliseconds: 1000}` or `%{type: "wait", selector: "#el"}`
  * `%{type: "write", text: "hello"}`
  * `%{type: "press", key: "Enter"}`
  * `%{type: "scroll", direction: "down"}`
  * `%{type: "scrape"}`
  * `%{type: "executeJavascript", script: "..."}`

* `location` — keyword list with `country:` and `languages:`. Geo or language-aware scraping.

* `skip_tls_verification` — boolean. Skip TLS verification.

* `remove_base64_images` — boolean. Drop base64 images from markdown.

* `block_ads` — boolean. Block ads and cookie popups.

* `proxy` — atom. Values: `:basic`, `:enhanced`, `:auto`. Enhanced costs up to 5 credits.

* `max_age` — integer. Use cached result if younger than this (milliseconds).

* `min_age` — integer. Cache-only mode; minimum cache age.

* `store_in_cache` — boolean. Store result in Firecrawl cache.

* `lockdown` — boolean. Serve from cache only.

* `redact_pii` — boolean. Redact PII from content.

* `profile` — keyword list with `name:` and optional `save_changes:`. Persistent browser profile.

* `zero_data_retention` — boolean. Enable zero data retention.

## Interact

### Why use it

Run code in the browser session tied to a scrape job. The Elixir SDK exposes code-based interactions only (no `prompt` parameter).

### Preferred SDK method

`Firecrawl.interact_with_scrape_browser_session(job_id, params \\ [], opts \\ [])`

### Example

```elixir theme={null}
{:ok, scrape_res} = Firecrawl.scrape_and_extract_from_url(
  url: "https://example.com",
  formats: ["markdown"]
)

job_id = scrape_res.body["data"]["metadata"]["scrapeId"]

{:ok, res} = Firecrawl.interact_with_scrape_browser_session(
  job_id,
  code: "console.log(await page.title());",
  language: :node,
  timeout: 60
)
```

Stop the session when done:

```elixir theme={null}
{:ok, _} = Firecrawl.stop_interactive_scrape_browser_session(job_id)
```

### Parameters

* `job_id` — string (required, first positional argument). Scrape job ID.

* `code` — string (required). Code to execute in the browser session.

* `language` — atom. Runtime for code execution. Values: `:python`, `:node`, `:bash`.

* `timeout` — integer. Execution timeout in seconds.

* `origin` — string. Optional origin label for telemetry.

## Notes

* The Elixir SDK is auto-generated from the OpenAPI spec via `mix run generate.exs`. Function names match the OpenAPI operation names.
* Each function has a bang (`!`) variant that raises on error instead of returning `{:error, _}`.
* All parameters use snake\_case keyword lists. They are auto-converted to camelCase maps for the JSON API body.
* Atom values (except `true`, `false`, `nil`) are auto-converted to strings before sending.
* NimbleOptions validates all parameters at the SDK level before the HTTP call.
* There is no client struct or GenServer — the SDK constructs a fresh `Req` client per call.
* No deprecated aliases exist; function names are generated directly from the spec.

## Source Of Truth

* `firecrawl/apps/elixir-sdk/mix.exs`
* `firecrawl/apps/elixir-sdk/lib/firecrawl.ex`
* `firecrawl-docs/api-reference/v2-openapi.json`
