> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firecrawl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust Source of Truth

> Canonical Firecrawl Rust source of truth for agents using key endpoints like search, scrape, and interact.

Canonical Firecrawl Rust source of truth for agents. Generated from SDK source and the v2 OpenAPI spec.

## Install

```bash theme={null}
cargo add firecrawl
```

Crate: **`firecrawl`** on crates.io. The current SDK version is **2.0.0** (verify the latest release on crates.io before pinning).

## Authenticate

```rust theme={null}
use firecrawl::Client;

let client = Client::new("fc-your-api-key")?;
// Self-hosted example:
// let client = Client::new_selfhosted("http://localhost:3002", Some("fc-your-api-key"))?;
```

## 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.
* `support/ask`: use when a Firecrawl API call fails or returns unexpected results and you need a diagnosis.
* `support/docs-search`: use when you need to look up Firecrawl documentation.

## Search

### Why use it

Use search to discover relevant pages from a query, then pick URLs to scrape or interact with. You can constrain results to a site with `site:`, for example `site:docs.firecrawl.dev crawl webhooks`.

### Preferred SDK method

`client.search(query, options)` → `Result<SearchResponse, FirecrawlError>`

### Simple Example

```rust theme={null}
use firecrawl::Client;

let results = client
    .search("site:docs.firecrawl.dev webhook retries", None)
    .await?;
```

### Complex Example

```rust theme={null}
use firecrawl::{
    Client, SearchOptions, SearchSource, SearchCategory, ScrapeOptions, Format, JsonOptions,
};

let options = SearchOptions {
    sources: Some(vec![SearchSource::Web, SearchSource::News]),
    categories: Some(vec![SearchCategory::Research]),
    limit: Some(10),
    tbs: Some("qdr:m".to_string()),
    location: Some("San Francisco,California,United States".to_string()),
    ignore_invalid_urls: Some(true),
    timeout: Some(60000),
    scrape_options: Some(ScrapeOptions {
        formats: Some(vec![Format::Markdown, Format::Links, Format::Json]),
        json_options: Some(JsonOptions {
            prompt: Some("Extract title and key endpoints.".to_string()),
            ..Default::default()
        }),
        only_main_content: Some(true),
        ..Default::default()
    }),
    ..Default::default()
};

let results = client
    .search("site:docs.firecrawl.dev crawl webhooks", options)
    .await?;
```

### Return type

`client.search(...)` returns `Result<SearchResponse, FirecrawlError>`.

* `SearchResponse`
  * `success: bool`
  * `data: SearchData`
  * `warning: Option<String>`
* `SearchData`
  * `web: Option<Vec<SearchResultOrDocument>>` — each item is either `SearchResultOrDocument::WebResult(SearchResultWeb)` (url, title, description, …) or `SearchResultOrDocument::Document(Document)` when the API returned scraped content for that row (detected when markdown, html, rawHtml, or metadata is present).
  * `news: Option<Vec<SearchResultNews>>`
  * `images: Option<Vec<SearchResultImage>>`

### Parameters

* `query`
  * Type: `impl AsRef<str>`
  * Use when: you need a search query.
  * Notes: use `site:example.com` to limit results to a domain.

* `options.sources`
  * Type: `Vec<SearchSource>`
  * Use when: you want to control which sources are searched.
  * Confirmed values: `Web`, `News`, `Images`

* `options.categories`
  * Type: `Vec<SearchCategory>`
  * Use when: you want to filter results by category.
  * Confirmed values: `Github`, `Research`, `Pdf`

* `options.limit`
  * Type: u32
  * Use when: you want to cap results.

* `options.tbs`
  * Type: String
  * Use when: you need a time-based filter (for example `qdr:d`, `qdr:w`, `sbd:1,qdr:m`).

* `options.location`
  * Type: String
  * Use when: you want localized results.

* `options.ignore_invalid_urls`
  * Type: bool
  * Use when: you want to drop URLs that cannot be scraped by other endpoints.

* `options.timeout`
  * Type: u32
  * Use when: you need a request timeout in milliseconds.

* `options.scrape_options`
  * Type: `ScrapeOptions`
  * Use when: you want to scrape each search result (see Scrape parameters for fields).

* `options.integration`
  * Type: `Option<String>`
  * Use when: you need an integration identifier for server-side tracking.
  * Notes: omit in agent-oriented examples unless your product intentionally sets it.

## Scrape

### Why use it

Use scrape when you already have a URL and want structured content in one or more formats.

### Preferred SDK method

`client.scrape(url, options)` → `Result<Document, FirecrawlError>` (the HTTP response `data` field is unwrapped in the SDK).

### Simple Example

```rust theme={null}
use firecrawl::{Client, ScrapeOptions, Format};

let doc = client
    .scrape("https://docs.firecrawl.dev", ScrapeOptions {
        formats: Some(vec![Format::Markdown]),
        ..Default::default()
    })
    .await?;
```

### Complex Example

```rust theme={null}
use firecrawl::{
    Client, ScrapeOptions, Format, JsonOptions, ScreenshotOptions, ChangeTrackingOptions,
    ChangeTrackingMode, AttributeSelector, Action, ParserConfig, ProxyType,
};

let doc = client
    .scrape("https://example.com/pricing", ScrapeOptions {
        formats: Some(vec![
            Format::Markdown,
            Format::Links,
            Format::Json,
            Format::Screenshot,
            Format::ChangeTracking,
            Format::Attributes,
        ]),
        json_options: Some(JsonOptions {
            prompt: Some("Extract plan names and prices.".to_string()),
            ..Default::default()
        }),
        screenshot_options: Some(ScreenshotOptions {
            full_page: Some(true),
            quality: Some(80),
            ..Default::default()
        }),
        change_tracking_options: Some(ChangeTrackingOptions {
            modes: Some(vec![ChangeTrackingMode::GitDiff]),
            tag: Some("pricing".to_string()),
            ..Default::default()
        }),
        attribute_selectors: Some(vec![AttributeSelector {
            selector: "a".to_string(),
            attribute: "href".to_string(),
        }]),
        parsers: Some(vec![ParserConfig::Pdf {
            parser_type: "pdf".to_string(),
            max_pages: Some(5),
        }]),
        actions: Some(vec![
            Action::Click { selector: "#accept".to_string() },
            Action::Wait { milliseconds: Some(750), selector: None },
            Action::Scrape,
        ]),
        proxy: Some(ProxyType::Auto),
        ..Default::default()
    })
    .await?;
```

### Parameters

* `url`
  * Type: `impl AsRef<str>`
  * Use when: you want to scrape a specific page.

* `options.formats`
  * Type: `Vec<Format>`
  * Use when: you want multiple output formats.
  * Confirmed values: `Markdown`, `Html`, `RawHtml`, `Links`, `Images`, `Screenshot`, `Summary`, `ChangeTracking`, `Json`, `Attributes`, `Branding`, `Audio`, `Video`

* `options.headers`
  * Type: `HashMap<String, String>`
  * Use when: you need custom request headers.

* `options.include_tags`
  * Type: `Vec<String>`
  * Use when: you want to include only specific HTML tags.

* `options.exclude_tags`
  * Type: `Vec<String>`
  * Use when: you want to exclude specific HTML tags.

* `options.only_main_content`
  * Type: bool
  * Use when: you want to strip nav, footer, and other boilerplate.

* `options.timeout`
  * Type: u32
  * Use when: you need a timeout in milliseconds.

* `options.wait_for`
  * Type: u32
  * Use when: you need to wait for the page to render (milliseconds).

* `options.mobile`
  * Type: bool
  * Use when: you want a mobile viewport.

* `options.parsers`
  * Type: `Vec<ParserConfig>`
  * Use when: you need file parsing controls.
  * Confirmed values:
    * `ParserConfig::Simple("pdf".to_string())`
    * `ParserConfig::Pdf { parser_type: "pdf", max_pages: Some(n) }`

* `options.actions`
  * Type: `Vec<Action>`
  * Use when: you need lightweight pre-scrape actions.
  * Confirmed action types:
    * `Wait`: `milliseconds` or `selector` required
    * `Screenshot`: `full_page`, `quality`, `viewport` optional
    * `Click`: `selector` required
    * `Write`: `text` required (click to focus the input first)
    * `Press`: `key` required
    * `Scroll`: `direction` (`Up` or `Down`) required, `selector` optional
    * `Scrape`: no additional fields
    * `ExecuteJavascript`: `script` required
    * `Pdf`: `format` (A0, A1, A2, A3, A4, A5, A6, Letter, Legal, Tabloid, Ledger), `landscape`, `scale` optional

* `options.location`
  * Type: `LocationConfig`
  * Use when: you need geo or language-aware scraping.
  * Confirmed fields: `country`, `languages`

* `options.skip_tls_verification`
  * Type: bool
  * Use when: you need to skip TLS verification.

* `options.remove_base64_images`
  * Type: bool
  * Use when: you want to drop base64 images from markdown output.

* `options.fast_mode`
  * Type: bool
  * Use when: you want faster scrapes with reduced fidelity.

* `options.block_ads`
  * Type: bool
  * Use when: you want ad and cookie popup blocking.

* `options.proxy`
  * Type: `ProxyType`
  * Use when: you need proxy control.
  * Confirmed values: `Basic`, `Stealth`, `Enhanced`, `Auto`

* `options.max_age`
  * Type: u32
  * Use when: you want cached data up to a maximum age (milliseconds).

* `options.min_age`
  * Type: u32
  * Use when: you want cached data only if it is at least this old (milliseconds).

* `options.store_in_cache`
  * Type: bool
  * Use when: you want Firecrawl to cache the result.

* `options.profile`
  * Type: `ProfileConfig`
  * Use when: you want a persistent browser profile shared across scrapes and interactions.
  * Confirmed fields: `name`, `save_changes`

* `options.integration`
  * Type: `Option<String>`
  * Use when: you need an integration identifier for server-side tracking.
  * Notes: omit in agent-oriented examples unless your product intentionally sets it.

* `options.json_options`
  * Type: `JsonOptions`
  * Use when: you want to configure JSON extraction.
  * Confirmed fields: `schema`, `system_prompt`, `prompt`

* `options.screenshot_options`
  * Type: `ScreenshotOptions`
  * Use when: you want to configure screenshot output.
  * Confirmed fields: `full_page`, `quality`, `viewport`

* `options.change_tracking_options`
  * Type: `ChangeTrackingOptions`
  * Use when: you want to configure change tracking output.
  * Confirmed fields: `modes` (`GitDiff` or `Json`), `schema`, `prompt`, `tag`

* `options.attribute_selectors`
  * Type: `Vec<AttributeSelector>`
  * Use when: you want attribute extraction output.
  * Confirmed fields: `selector`, `attribute`

## Interact

### Why use it

Use interact when a page requires browser actions or code execution after a scrape starts.

### Preferred SDK method

`client.interact(job_id, options)`

To end the browser session, use `client.stop_interaction(job_id)` (HTTP `DELETE` on `/v2/scrape/{jobId}/interact`).

### Simple Example

```rust theme={null}
use firecrawl::{Client, ScrapeExecuteOptions};

let result = client
    .interact(
        "<scrapeJobId>",
        ScrapeExecuteOptions {
            prompt: Some("Click the pricing tab and summarize the plans.".to_string()),
            ..Default::default()
        },
    )
    .await?;
```

### Complex Example

```rust theme={null}
use firecrawl::{Client, ScrapeExecuteOptions, ScrapeExecuteLanguage};

let result = client
    .interact(
        "<scrapeJobId>",
        ScrapeExecuteOptions {
            code: Some("console.log(await page.title());".to_string()),
            language: Some(ScrapeExecuteLanguage::Node),
            timeout: Some(60),
            ..Default::default()
        },
    )
    .await?;
```

### Stop session

```rust theme={null}
let stopped = client.stop_interaction("<scrapeJobId>").await?;
// stopped: ScrapeBrowserDeleteResponse { success, session_duration_ms, credits_billed, error, ... }
```

### Parameters

* `job_id`
  * Type: `impl AsRef<str>`
  * Use when: you have a scrape job ID.

* `options.code`
  * Type: `Option<String>`
  * Use when: you want to run code in the browser session.

* `options.prompt`
  * Type: `Option<String>`
  * Use when: you want the browser agent to follow a natural-language instruction.

* `options.language`
  * Type: `ScrapeExecuteLanguage`
  * Use when: you need a specific runtime.
  * Confirmed values: `Python`, `Node`, `Bash`
  * Notes: defaults to `Node` in the SDK if omitted.

* `options.timeout`
  * Type: u32
  * Use when: you need an execution timeout in seconds.

* `options.origin`
  * Type: `Option<String>`
  * Use when: you need an optional origin label for execution telemetry.
  * Notes: omit in agent-oriented examples unless your product intentionally sets it.

At least one of `options.code` or `options.prompt` must be non-empty; otherwise the SDK returns `FirecrawlError::Misuse` before calling the API.

### Response types

* `interact` → `Result<ScrapeExecuteResponse, FirecrawlError>`
  * `success: bool` is always present; `live_view_url`, `interactive_live_view_url`, `output`, `stdout`, `result`, `stderr`, `exit_code`, `killed`, and `error` are `Option` fields on the struct.
* `stop_interaction` → `Result<ScrapeBrowserDeleteResponse, FirecrawlError>`
  * `success: bool` is always present; `session_duration_ms`, `credits_billed`, and `error` are optional.

The v2 OpenAPI spec currently models the interact request body with `code` as required; the Rust SDK matches server behavior by accepting **either** `code` **or** `prompt` (see `ScrapeExecuteOptions` in `scrape.rs`).

## Notes

* Deprecated aliases: `scrape_execute`, `stop_interactive_browser`, and `delete_scrape_browser` map to `interact` and `stop_interaction`.
* `ScrapeOptions` includes dedicated `json_options`, `screenshot_options`, and `change_tracking_options` for advanced formats.
* `search_and_scrape(query, limit)` is a convenience helper: it calls `search` with default `ScrapeOptions` and returns `Vec<Document>` built from `SearchResultOrDocument::Document` entries in `data.web` (see `search.rs`).
* v2 SDK exports all types at the crate root: `use firecrawl::Client` (not `use firecrawl::v2::Client`).
* Error types simplified in v2: `CrawlJobFailed(String, CrawlStatus)` → `JobFailed(String)`, `Missuse` → `Misuse`.

## Source Of Truth

* `firecrawl/apps/rust-sdk/Cargo.toml`
* `firecrawl/apps/rust-sdk/src/lib.rs`
* `firecrawl/apps/rust-sdk/src/client.rs`
* `firecrawl/apps/rust-sdk/src/scrape.rs`
* `firecrawl/apps/rust-sdk/src/search.rs`
* `firecrawl/apps/rust-sdk/src/crawl.rs`
* `firecrawl/apps/rust-sdk/src/map.rs`
* `firecrawl/apps/rust-sdk/src/batch_scrape.rs`
* `firecrawl/apps/rust-sdk/src/agent.rs`
* `firecrawl/apps/rust-sdk/src/types.rs`
* `firecrawl-docs/api-reference/v2-openapi.json`
