diff --git a/agent-quickstart/elixir.mdx b/agent-quickstart/elixir.mdx new file mode 100644 index 000000000..86c5266eb --- /dev/null +++ b/agent-quickstart/elixir.mdx @@ -0,0 +1,234 @@ +--- +title: "Elixir Agent Quickstart" +description: "Canonical Firecrawl Elixir quickstart for external agents using search, scrape, and interact." +--- + +# Firecrawl Elixir Agent Quickstart + +This file is the canonical quickstart for external agents integrating Firecrawl with Elixir. Generated from SDK source (`firecrawl` hex package v1.9) and the Firecrawl OpenAPI spec. + +The Elixir SDK is auto-generated from the Firecrawl OpenAPI spec. Function names match OpenAPI operation IDs. + +## Install + +Add to your `mix.exs`: + +```elixir +defp deps do + [ + {:firecrawl, "~> 1.4"} + ] +end +``` + +## Authenticate + +Configure the API key globally in your application config: + +```elixir +# config/config.exs +config :firecrawl, api_key: "fc-YOUR_API_KEY" +``` + +Or pass it per-call: + +```elixir +Firecrawl.scrape_and_extract_from_url([url: "https://example.com"], api_key: "fc-YOUR_API_KEY") +``` + +Additional per-call options: + +| Option | Type | Default | Description | +|---|---|---|---| +| `api_key` | `string` | Application config | Override API key for this request. | +| `base_url` | `string` | `"https://api.firecrawl.dev/v2"` | Override base URL (self-hosted). | + +A nil API key is allowed — scrape, search, and interact fall back to a keyless free tier (rate-limited per IP). + +## When To Use What + +- **`search_and_scrape`**: Start with a query, discover relevant pages. Returns search results with optional scraping of each result. +- **`scrape_and_extract_from_url`**: Start with a URL, get page content in markdown, HTML, or other formats. +- **`interact_with_scrape_browser_session`**: Execute code in a browser session from a prior scrape. Use for post-scrape browser automation. + +## Search + +### Why use it + +Use `search_and_scrape` when you have a query and want to discover relevant web pages. Optionally scrape each result to get full page content. + +### Preferred SDK function + +``` +Firecrawl.search_and_scrape(params, opts) +``` + +Bang variant: `Firecrawl.search_and_scrape!(params, opts)` raises on error. + +### Example + +```elixir +{:ok, response} = Firecrawl.search_and_scrape( + query: "firecrawl web scraping API", + limit: 5, + scrape_options: [formats: ["markdown"]] +) + +for item <- response.body["data"]["web"] || [] do + IO.puts("#{item["url"]} #{String.slice(item["markdown"] || "", 0..200)}") +end +``` + +### Parameters + +Parameters are passed as a keyword list. Validated at call time via NimbleOptions. + +| Parameter | Type | Description | +|---|---|---| +| `query` | `string` | Search query (required). | +| `limit` | `integer` | Max results. | +| `sources` | `list(any)` | Sources to search. | +| `categories` | `list(any)` | Category filters. | +| `include_domains` | `list(string)` | Restrict results to these domains. | +| `exclude_domains` | `list(string)` | Exclude results from these domains. | +| `tbs` | `string` | Time-based search filter (e.g. `"qdr:d"`). | +| `location` | `string` | Location string for geo-targeted search. | +| `country` | `string` | Country code (ISO). | +| `timeout` | `integer` | Timeout in ms. | +| `highlights` | `boolean` | Generate query-relevant highlights. Server default: `true`. | +| `ignore_invalid_urls` | `boolean` | Skip invalid URLs. | +| `enterprise` | `list(string)` | Enterprise options: `["zdr"]` or `["anon"]`. | +| `scrape_options` | `keyword` | Options for scraping each result page (same params as scrape). | + +**Return type:** `{:ok, %Req.Response{}}` or `{:error, exception}`. The response body is a decoded JSON map. + +## Scrape + +### Why use it + +Use `scrape_and_extract_from_url` when you already have a URL and want page content as markdown, HTML, screenshots, structured JSON, or other formats. + +### Preferred SDK function + +``` +Firecrawl.scrape_and_extract_from_url(params, opts) +``` + +Bang variant: `Firecrawl.scrape_and_extract_from_url!(params, opts)` raises on error. + +### Example + +```elixir +{:ok, response} = Firecrawl.scrape_and_extract_from_url( + url: "https://example.com", + formats: ["markdown", "links"], + only_main_content: true +) + +data = response.body["data"] +IO.puts(data["markdown"]) +IO.puts(data["metadata"]["title"]) +``` + +### Parameters + +Parameters are passed as a keyword list. + +| Parameter | Type | Description | +|---|---|---| +| `url` | `string` | URL to scrape (required). | +| `formats` | `list(any)` | Output formats: `"markdown"`, `"html"`, `"rawHtml"`, `"links"`, `"images"`, `"screenshot"`, `"json"`, `"changeTracking"`, `"branding"`, `"product"`, `"menu"`, `"audio"`, `"video"`, etc. | +| `headers` | `any` | Custom HTTP headers. | +| `include_tags` | `list(string)` | HTML tags to include. | +| `exclude_tags` | `list(string)` | HTML tags to exclude. | +| `only_main_content` | `boolean` | Only return main content. Server default: `true`. | +| `timeout` | `integer` | Timeout in ms. Server default: `60000`. | +| `wait_for` | `integer` | Wait time in ms before scraping. | +| `mobile` | `boolean` | Emulate mobile device. | +| `parsers` | `list(any)` | Parser configuration. | +| `actions` | `list(any)` | Browser actions before scraping. Each is a keyword list or map with `type` key. | +| `location` | `keyword` | Geolocation: `[country: "US", languages: ["en"]]`. | +| `skip_tls_verification` | `boolean` | Skip TLS cert verification. | +| `remove_base64_images` | `boolean` | Remove base64 images. | +| `block_ads` | `boolean` | Block ads. Server default: `true`. | +| `proxy` | `:basic \| :enhanced \| :auto` | Proxy mode. | +| `max_age` | `integer` | Use cached result if younger than this (ms). | +| `store_in_cache` | `boolean` | Cache the result. | +| `lockdown` | `boolean` | Serve from cache only. | +| `redact_pii` | `boolean` | Redact PII from output. | +| `profile` | `keyword` | Persistent browser profile. | +| `audit_metadata` | `keyword` | User attribution: `[username: "user"]`. | +| `zero_data_retention` | `boolean` | Enable zero data retention. | + +**Return type:** `{:ok, %Req.Response{}}`. The response body `data` field is a map with `"markdown"`, `"html"`, `"metadata"`, `"links"`, etc. + +## Interact + +### Why use it + +Use `interact_with_scrape_browser_session` to execute code in the browser session from a prior scrape. The scrape must have returned a job ID. Use it for post-scrape automation. + +### Preferred SDK function + +``` +Firecrawl.interact_with_scrape_browser_session(job_id, params, opts) +``` + +Bang variant: `Firecrawl.interact_with_scrape_browser_session!(job_id, params, opts)` raises on error. + +### Example + +```elixir +# First scrape to get a job_id +{:ok, scrape_response} = Firecrawl.scrape_and_extract_from_url( + url: "https://example.com", + formats: ["markdown"] +) +job_id = scrape_response.body["data"]["metadata"]["jobId"] + +# Interact with the browser session +{:ok, result} = Firecrawl.interact_with_scrape_browser_session(job_id, + code: "document.title", + language: :node +) + +IO.puts(result.body["stdout"]) +IO.puts(result.body["result"]) +``` + +### Parameters + +The first argument is `job_id` (string). Remaining parameters are passed as a keyword list. + +| Parameter | Type | Description | +|---|---|---| +| `job_id` | `string` | Scrape job ID (required, first positional argument). | +| `code` | `string` | Code to execute (required). | +| `language` | `:python \| :node \| :bash` | Language for code execution. Default: `"node"` (server-side). | +| `timeout` | `integer` | Execution timeout in seconds. Server default: `30`. | + +**Return type:** `{:ok, %Req.Response{}}`. Body contains `"success"`, `"stdout"`, `"result"`, `"stderr"`, `"exitCode"`, `"killed"`, `"error"`. + +### Stop a session + +```elixir +Firecrawl.stop_interactive_scrape_browser_session(job_id) +``` + +## Notes + +- **Auto-generated from OpenAPI**: Function names match OpenAPI operation IDs and are verbose (e.g. `scrape_and_extract_from_url` instead of `scrape`). +- **snake_case in, camelCase out**: Pass snake_case keywords (e.g. `only_main_content: true`). They are automatically converted to camelCase JSON keys. +- **NimbleOptions validation**: Parameters are validated at call time. Passing an unrecognized key or wrong type returns `{:error, %NimbleOptions.ValidationError{}}` immediately. +- **Bang variants**: Every function `foo/n` has a `foo!/n` that raises `Firecrawl.Error` instead of returning `{:error, _}`. +- **No client struct**: Unlike other SDKs, there is no connection object to create upfront. A fresh `Req` client is built per call. +- **Response bodies are raw JSON maps**: No typed response structs — access data via map keys like `response.body["data"]["markdown"]`. +- **No deprecated aliases**: The generated client has one function per operation. +- **Keyless free tier**: Works without an API key (rate-limited per IP). +- **Batch scraping**: `Firecrawl.scrape_and_extract_from_urls/2` is available for batch operations. + +## Source Of Truth + +- `/firecrawl/apps/elixir-sdk/lib/firecrawl.ex` +- `/firecrawl/apps/elixir-sdk/mix.exs` +- `/firecrawl-docs/api-reference/v2-openapi.json` diff --git a/agent-quickstart/java.mdx b/agent-quickstart/java.mdx new file mode 100644 index 000000000..e3f46bfe9 --- /dev/null +++ b/agent-quickstart/java.mdx @@ -0,0 +1,271 @@ +--- +title: "Java Agent Quickstart" +description: "Canonical Firecrawl Java quickstart for external agents using search, scrape, and interact." +--- + +# Firecrawl Java Agent Quickstart + +This file is the canonical quickstart for external agents integrating Firecrawl with Java. Generated from SDK source (`firecrawl-java` v1.12) and the Firecrawl OpenAPI spec. + +## Install + +**Maven:** + +```xml + + com.firecrawl + firecrawl-java + 1.12.1 + +``` + +**Gradle (Kotlin DSL):** + +```kotlin +implementation("com.firecrawl:firecrawl-java:1.12.1") +``` + +Requires Java 11+. + +## Authenticate + +```java +import com.firecrawl.client.FirecrawlClient; + +// Builder pattern (preferred) +FirecrawlClient client = FirecrawlClient.builder() + .apiKey("fc-YOUR_API_KEY") + .build(); + +// From environment (FIRECRAWL_API_KEY env var or firecrawl.apiKey system property) +FirecrawlClient client = FirecrawlClient.fromEnv(); +``` + +Builder options: + +| Option | Type | Default | Description | +|---|---|---|---| +| `apiKey` | `String` | `FIRECRAWL_API_KEY` env var or `firecrawl.apiKey` system property | API key. Null allowed for keyless free tier. | +| `apiUrl` | `String` | `"https://api.firecrawl.dev"` | API base URL. Also reads `FIRECRAWL_API_URL` env var. | +| `timeoutMs` | `long` | `300000` | Per-request timeout in ms. | +| `maxRetries` | `int` | `3` | Max retries for failed requests. | +| `backoffFactor` | `double` | `0.5` | Exponential backoff factor. | +| `asyncExecutor` | `Executor` | `ForkJoinPool.commonPool()` | Executor for async methods. | +| `httpClient` | `OkHttpClient` | auto-created | Custom OkHttp client (overrides `timeoutMs`). | + +## When To Use What + +- **`search`**: Start with a query, discover relevant pages. Returns search results with optional scraping of each result. +- **`scrape`**: Start with a URL, get page content in markdown, HTML, or other formats. +- **`interact`**: Execute code in a browser session from a prior scrape. Use for post-scrape browser automation. + +## Search + +### Why use it + +Use `search` when you have a query and want to discover relevant web pages. Optionally scrape each result to get full page content. + +### Preferred SDK method + +``` +client.search(query) +client.search(query, options) +``` + +### Example + +```java +import com.firecrawl.models.SearchOptions; +import com.firecrawl.models.ScrapeOptions; +import com.firecrawl.models.SearchData; + +SearchData results = client.search("firecrawl web scraping API", + SearchOptions.builder() + .limit(5) + .scrapeOptions(ScrapeOptions.builder() + .formats(List.of("markdown")) + .build()) + .build()); + +for (Map item : results.getWeb()) { + System.out.println(item.get("url") + " " + item.get("markdown")); +} +``` + +### Parameters + +All fields on `SearchOptions` are nullable and omitted from the request when null. + +| Parameter | Type | Description | +|---|---|---| +| `query` | `String` | Search query (required, first argument). | +| `sources` | `List` | Sources: strings like `"web"`, `"news"`, `"images"`, or `{type: "web"}` maps. | +| `categories` | `List` | Category filters: `"github"`, `"research"`, `"pdf"`. | +| `includeDomains` | `List` | Restrict results to these domains. | +| `excludeDomains` | `List` | Exclude results from these domains. | +| `limit` | `Integer` | Max results. | +| `tbs` | `String` | Time-based filter (e.g. `"qdr:d"` for past day). | +| `location` | `String` | Location string for geo-targeted search. | +| `ignoreInvalidURLs` | `Boolean` | Skip invalid URLs. | +| `timeout` | `Integer` | Timeout in ms. | +| `highlights` | `Boolean` | Generate query-relevant highlights. Server default: `true`. | +| `scrapeOptions` | `ScrapeOptions` | Options for scraping each result page. | +| `integration` | `String` | Integration identifier. | + +**Return type:** `SearchData` with `getWeb()`, `getNews()`, `getImages()` returning `List>`. + +### Async variant + +```java +CompletableFuture future = client.searchAsync("query", options); +``` + +## Scrape + +### Why use it + +Use `scrape` when you already have a URL and want page content as markdown, HTML, screenshots, structured JSON, or other formats. + +### Preferred SDK method + +``` +client.scrape(url) +client.scrape(url, options) +``` + +### Example + +```java +import com.firecrawl.models.ScrapeOptions; +import com.firecrawl.models.Document; + +Document doc = client.scrape("https://example.com", + ScrapeOptions.builder() + .formats(List.of("markdown", "links")) + .onlyMainContent(true) + .build()); + +System.out.println(doc.getMarkdown()); +System.out.println(doc.getMetadata().get("title")); +``` + +### Parameters + +All fields on `ScrapeOptions` are nullable and omitted when null. + +| Parameter | Type | Description | +|---|---|---| +| `url` | `String` | URL to scrape (required, first argument). | +| `formats` | `List` | Output formats. Strings: `"markdown"`, `"html"`, `"rawHtml"`, `"links"`, `"images"`, `"screenshot"`, `"summary"`, `"json"`, `"audio"`, `"video"`, `"product"`, `"menu"`. Also accepts format config objects (`JsonFormat`, `QuestionFormat`, `HighlightsFormat`). | +| `headers` | `Map` | Custom HTTP headers. | +| `includeTags` | `List` | HTML tags to include. | +| `excludeTags` | `List` | HTML tags to exclude. | +| `onlyMainContent` | `Boolean` | Only return main content. Server default: `true`. | +| `timeout` | `Integer` | Timeout in ms. Server default: `60000`. | +| `waitFor` | `Integer` | Wait time in ms before scraping. Server default: `0`. | +| `mobile` | `Boolean` | Emulate mobile device. | +| `parsers` | `List` | Parser configuration (e.g. PDF handling). | +| `actions` | `List>` | Browser actions before scraping. | +| `location` | `LocationConfig` | Geolocation: `LocationConfig.builder().country("US").languages(List.of("en")).build()`. | +| `skipTlsVerification` | `Boolean` | Skip TLS cert verification. | +| `removeBase64Images` | `Boolean` | Remove base64 images. | +| `blockAds` | `Boolean` | Block ads. Server default: `true`. | +| `proxy` | `String` | Proxy mode: `"basic"`, `"stealth"`, `"enhanced"`, `"auto"`. | +| `maxAge` | `Long` | Use cached result if younger than this (ms). | +| `storeInCache` | `Boolean` | Cache the result. | +| `lockdown` | `Boolean` | Serve from cache only. | +| `redactPII` | `Boolean` | Redact PII from output. | +| `auditMetadata` | `AuditMetadata` | User attribution for SIEM logging. | +| `integration` | `String` | Integration identifier. | + +**Return type:** `Document` with getters: `getMarkdown()`, `getHtml()`, `getRawHtml()`, `getJson()`, `getSummary()`, `getMetadata()`, `getLinks()`, `getImages()`, `getScreenshot()`, `getAudio()`, `getVideo()`, `getActions()`, `getAnswer()`, `getHighlights()`, `getWarning()`, `getChangeTracking()`, `getBranding()`, `getProduct()`, `getMenu()`. + +### Async variant + +```java +CompletableFuture future = client.scrapeAsync("https://example.com", options); +``` + +## Interact + +### Why use it + +Use `interact` to execute code in the browser session from a prior scrape. The scrape must have returned a job ID (in the response metadata). Use it for post-scrape automation. + +### Preferred SDK method + +``` +client.interact(jobId, code) +client.interact(jobId, code, language, timeout) +``` + +### Example + +```java +import com.firecrawl.models.BrowserExecuteResponse; + +// First scrape to get a jobId +Document doc = client.scrape("https://example.com", + ScrapeOptions.builder().formats(List.of("markdown")).build()); +String jobId = (String) doc.getMetadata().get("scrapeId"); + +// Interact with the browser session +BrowserExecuteResponse result = client.interact(jobId, "document.title"); + +System.out.println(result.getStdout()); +System.out.println(result.getResult()); +``` + +### Parameters + +| Parameter | Type | Description | +|---|---|---| +| `jobId` | `String` | Scrape job ID (required). | +| `code` | `String` | Code to execute (required). | +| `language` | `String` | Language: `"python"`, `"node"`, `"bash"`. Default: `"node"`. | +| `timeout` | `Integer` | Execution timeout in seconds. Server default: `30`. | +| `origin` | `String` | Origin tag. Auto-set to `"java-sdk@1.12.1"`. | + +**Return type:** `BrowserExecuteResponse` with fields: `success`, `stdout`, `result`, `stderr`, `exitCode`, `killed`, `error`. + +### Overloads + +```java +// Minimal +client.interact(jobId, code); + +// With language and timeout +client.interact(jobId, code, "node", 60); + +// Full +client.interact(jobId, code, "node", 60, "my-origin"); +``` + +### Stop a session + +```java +client.stopInteractiveBrowser(jobId); +``` + +### Async variants + +```java +CompletableFuture future = client.interactAsync(jobId, code); +``` + +## Notes + +- **camelCase** parameter names throughout (e.g. `onlyMainContent`, `includeTags`, `waitFor`). +- **Builder pattern** on all option classes: `ScrapeOptions.builder()...build()`, `SearchOptions.builder()...build()`. +- **Method overloads**: Most methods have a minimal version (just required args) and a full version (with options). +- **Checked exceptions**: All sync methods throw `FirecrawlException`. Subclasses: `AuthenticationException` (401), `RateLimitException` (429), `JobTimeoutException`. +- **Deprecated aliases**: `scrapeExecute` → `interact`, `deleteScrapeBrowser` → `stopInteractiveBrowser`. +- **Weakly typed search results**: `SearchData` returns `List>`, not typed model classes. +- **Keyless free tier**: Scrape, search, and interact work without an API key (rate-limited per IP). +- **The `jobId` for interact** is obtained from `doc.getMetadata().get("scrapeId")` after a scrape. + +## Source Of Truth + +- `/firecrawl/apps/java-sdk/src/main/java/com/firecrawl/client/FirecrawlClient.java` +- `/firecrawl/apps/java-sdk/src/main/java/com/firecrawl/models/` (ScrapeOptions, SearchOptions, Document, etc.) +- `/firecrawl-docs/api-reference/v2-openapi.json` diff --git a/agent-quickstart/node.mdx b/agent-quickstart/node.mdx new file mode 100644 index 000000000..30f5b1b82 --- /dev/null +++ b/agent-quickstart/node.mdx @@ -0,0 +1,213 @@ +--- +title: "Node.js Agent Quickstart" +description: "Canonical Firecrawl Node.js quickstart for external agents using search, scrape, and interact." +--- + +# Firecrawl Node.js Agent Quickstart + +This file is the canonical quickstart for external agents integrating Firecrawl with Node.js/TypeScript. Generated from SDK source (`@mendable/firecrawl-js` v4) and the Firecrawl OpenAPI spec. + +## Install + +```bash +npm install @mendable/firecrawl-js +``` + +Requires Node >= 22. + +## Authenticate + +```javascript +import Firecrawl from "@mendable/firecrawl-js"; + +const client = new Firecrawl("fc-YOUR_API_KEY"); +// or use FIRECRAWL_API_KEY env var: +const client = new Firecrawl(); +``` + +Constructor options: + +| Option | Type | Default | Description | +|---|---|---|---| +| `apiKey` | `string \| null` | `process.env.FIRECRAWL_API_KEY` | API key. Omit for keyless free tier. | +| `apiUrl` | `string \| null` | `"https://api.firecrawl.dev"` | API base URL. | +| `timeoutMs` | `number` | `300000` | Per-request timeout in ms. | +| `maxRetries` | `number` | `3` | Max retries on 502 errors. | +| `backoffFactor` | `number` | `0.5` | Exponential backoff factor in seconds. | + +## When To Use What + +- **`search`**: Start with a query, discover relevant pages. Returns search results with optional scraping of each result. +- **`scrape`**: Start with a URL, get page content in markdown, HTML, or other formats. +- **`interact`**: Execute code or send a prompt in a browser session from a prior scrape. Use for post-scrape browser automation. + +## Search + +### Why use it + +Use `search` when you have a query and want to discover relevant web pages. Optionally scrape each result to get full page content. + +### Preferred SDK method + +``` +client.search(query, options?) +``` + +### Example + +```javascript +const results = await client.search("firecrawl web scraping API", { + limit: 5, + scrapeOptions: { formats: ["markdown"] }, +}); + +for (const item of results.web ?? []) { + console.log(item.url, item.markdown?.slice(0, 200)); +} +``` + +### Parameters + +| Parameter | Type | Description | +|---|---|---| +| `query` | `string` | Search query (required, first argument). | +| `sources` | `Array<"web" \| "news" \| "images" \| { type: string }>` | Result sources to include. Determines which arrays appear in the response. | +| `categories` | `Array<"github" \| "research" \| "pdf" \| "developer">` | Category filters for results. | +| `includeDomains` | `string[]` | Restrict results to these domains. Cannot combine with `excludeDomains`. | +| `excludeDomains` | `string[]` | Exclude results from these domains. Cannot combine with `includeDomains`. | +| `limit` | `number` | Max results. Must be positive. | +| `tbs` | `string` | Time-based search filter (e.g. `"qdr:d"` for past day, `"qdr:w"` for past week). | +| `location` | `string` | Location string for geo-targeted search. | +| `ignoreInvalidURLs` | `boolean` | Skip invalid URLs instead of erroring. | +| `timeout` | `number` | Timeout in ms. Must be positive. | +| `highlights` | `boolean` | Generate query-relevant highlights. Server default: `true`. | +| `scrapeOptions` | `ScrapeOptions` | Options for scraping each result page. Same options as `scrape`. | +| `enterprise` | `Array<"default" \| "anon" \| "zdr">` | Enterprise search modes. Must be enabled for your team. | +| `threatProtection` | `object` | Per-request threat protection overrides (enterprise). | +| `integration` | `string` | Integration identifier. | + +**Return type:** `SearchData` with properties `web`, `news`, `images`, `developer` (arrays, depending on `sources`). Do **not** access `.data` — it throws an error. + +## Scrape + +### Why use it + +Use `scrape` when you already have a URL and want page content as markdown, HTML, screenshots, structured JSON, or other formats. + +### Preferred SDK method + +``` +client.scrape(url, options?) +``` + +### Example + +```javascript +const doc = await client.scrape("https://example.com", { + formats: ["markdown", "links"], + onlyMainContent: true, +}); + +console.log(doc.markdown); +console.log(doc.metadata?.title); +``` + +### Parameters + +| Parameter | Type | Description | +|---|---|---| +| `url` | `string` | URL to scrape (required, first argument). | +| `formats` | `FormatOption[]` | Output formats. Strings: `"markdown"`, `"html"`, `"rawHtml"`, `"links"`, `"images"`, `"screenshot"`, `"summary"`, `"changeTracking"`, `"attributes"`, `"branding"`, `"product"`, `"menu"`, `"audio"`, `"video"`. Objects: `{ type: "json", prompt?, schema? }`, `{ type: "screenshot", fullPage?, quality?, viewport? }`, `{ type: "question", question }`, `{ type: "highlights", query }`, `{ type: "changeTracking", modes, schema?, prompt?, tag? }`, `{ type: "attributes", selectors }`. Note: `"json"` as a bare string throws — use the object form. | +| `headers` | `Record` | Custom HTTP headers. | +| `includeTags` | `string[]` | HTML tags to include. | +| `excludeTags` | `string[]` | HTML tags to exclude. | +| `onlyMainContent` | `boolean` | Only return main content, excluding headers/navs/footers. Server default: `true`. | +| `timeout` | `number` | Timeout in ms. Range: 1000–300000. Server default: `60000`. | +| `waitFor` | `number` | Wait time in ms before scraping. Server default: `0`. | +| `mobile` | `boolean` | Emulate mobile device. Server default: `false`. | +| `parsers` | `Array` | Parser configuration (e.g. PDF handling). | +| `actions` | `ActionOption[]` | Browser actions before scraping: `wait`, `click`, `write`, `press`, `scroll`, `screenshot`, `scrape`, `executeJavascript`, `pdf`. | +| `location` | `{ country?: string, languages?: string[] }` | Geolocation settings. | +| `skipTlsVerification` | `boolean` | Skip TLS cert verification. Server default: `true`. | +| `removeBase64Images` | `boolean` | Remove base64 images. Server default: `true`. | +| `fastMode` | `boolean` | Enable fast mode. | +| `blockAds` | `boolean` | Block ads. Server default: `true`. | +| `proxy` | `"basic" \| "stealth" \| "enhanced" \| "auto"` | Proxy mode. Server default: `"auto"`. | +| `maxAge` | `number` | Use cached result if younger than this (ms). Server default: `172800000` (2 days). | +| `storeInCache` | `boolean` | Cache the result. Server default: `true`. | +| `lockdown` | `boolean` | Serve from cache only; never make outbound requests. | +| `redactPII` | `boolean \| RedactPIIOptions` | Redact PII from output. | +| `profile` | `{ name: string, saveChanges?: boolean }` | Persistent browser profile. | +| `threatProtection` | `object` | Per-request threat protection overrides (enterprise). | +| `auditMetadata` | `{ username: string }` | User attribution for SIEM logging. | +| `integration` | `string` | Integration identifier. | + +**Return type:** `Document` with optional fields: `markdown`, `html`, `rawHtml`, `json`, `summary`, `metadata`, `links`, `images`, `screenshot`, `audio`, `video`, `actions`, `answer`, `highlights`, `warning`, `changeTracking`, `branding`, `product`, `menu`. + +## Interact + +### Why use it + +Use `interact` to execute code or send a natural-language prompt in the browser session from a prior scrape. The scrape must have returned a `jobId` (available in the response metadata). Use it for post-scrape browser automation — clicking, filling forms, navigating, or running arbitrary JavaScript. + +### Preferred SDK method + +``` +client.interact(jobId, args) +``` + +### Example + +```javascript +// First scrape to get a jobId +const doc = await client.scrape("https://example.com", { + formats: ["markdown"], +}); +const jobId = doc.metadata?.jobId; + +// Then interact with the browser session +const result = await client.interact(jobId, { + code: "document.title", + language: "node", +}); + +console.log(result.stdout); +console.log(result.result); +``` + +### Parameters + +The second argument is a `ScrapeExecuteRequest` object: + +| Parameter | Type | Description | +|---|---|---| +| `jobId` | `string` | Scrape job ID (required, first argument). | +| `code` | `string` | Code to execute. At least one of `code` or `prompt` is required. | +| `prompt` | `string` | Natural-language instruction for the browser agent. At least one of `code` or `prompt` is required. | +| `language` | `"python" \| "node" \| "bash"` | Language for code execution. Default: `"node"`. | +| `timeout` | `number` | Execution timeout in seconds. Range: 1–300. Server default: `30`. | + +**Return type:** `ScrapeExecuteResponse` with fields: `success`, `stdout`, `result`, `stderr`, `exitCode`, `killed`, `error`, `cdpUrl`, `liveViewUrl`, `interactiveLiveViewUrl`, `output`. + +### Stop a session + +```javascript +await client.stopInteraction(jobId); +``` + +## Notes + +- **camelCase** parameter names throughout (e.g. `onlyMainContent`, `includeTags`, `waitFor`). +- **Deprecated aliases**: `scrapeUrl` → `scrape`, `scrapeExecute` → `interact`, `stopInteractiveBrowser` / `deleteScrapeBrowser` → `stopInteraction`. Use the preferred names. +- **`"json"` format caveat**: Passing `"json"` as a bare string in `formats` throws an error. Use `{ type: "json", prompt: "...", schema: ... }` with at least one of `prompt` or `schema`. Zod schemas are auto-converted to JSON Schema. +- **`SearchData.data` trap**: Accessing `.data` on search results throws an error. Use `.web`, `.news`, `.images`, or `.developer` instead. +- **Keyless free tier**: Scrape, search, and interact work without an API key (rate-limited per IP). + +## Source Of Truth + +- `/firecrawl/apps/js-sdk/firecrawl/src/index.ts` +- `/firecrawl/apps/js-sdk/firecrawl/src/v2/client.ts` +- `/firecrawl/apps/js-sdk/firecrawl/src/v2/types.ts` +- `/firecrawl/apps/js-sdk/firecrawl/src/v2/methods/scrape.ts` +- `/firecrawl/apps/js-sdk/firecrawl/src/v2/methods/search.ts` +- `/firecrawl-docs/api-reference/v2-openapi.json` diff --git a/agent-quickstart/python.mdx b/agent-quickstart/python.mdx new file mode 100644 index 000000000..07e9ed434 --- /dev/null +++ b/agent-quickstart/python.mdx @@ -0,0 +1,214 @@ +--- +title: "Python Agent Quickstart" +description: "Canonical Firecrawl Python quickstart for external agents using search, scrape, and interact." +--- + +# Firecrawl Python Agent Quickstart + +This file is the canonical quickstart for external agents integrating Firecrawl with Python. Generated from SDK source (`firecrawl-py` v4) and the Firecrawl OpenAPI spec. + +## Install + +```bash +pip install firecrawl-py +``` + +## Authenticate + +```python +from firecrawl import Firecrawl + +client = Firecrawl(api_key="fc-YOUR_API_KEY") +# or use FIRECRAWL_API_KEY env var: +client = Firecrawl() +``` + +Constructor parameters: + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `api_key` | `str` | `FIRECRAWL_API_KEY` env var | API key. Omit for keyless free tier. | +| `api_url` | `str` | `"https://api.firecrawl.dev"` | API base URL. | +| `timeout` | `float` | `None` | Default request timeout in seconds. | +| `max_retries` | `int` | `3` | Max retries for failed requests. | +| `backoff_factor` | `float` | `0.5` | Exponential backoff factor. | + +An async variant is also available: `from firecrawl import AsyncFirecrawl`. + +## When To Use What + +- **`search`**: Start with a query, discover relevant pages. Returns search results with optional scraping of each result. +- **`scrape`**: Start with a URL, get page content in markdown, HTML, or other formats. +- **`interact`**: Execute code or send a prompt in a browser session from a prior scrape. Use for post-scrape browser automation. + +## Search + +### Why use it + +Use `search` when you have a query and want to discover relevant web pages. Optionally scrape each result to get full page content. + +### Preferred SDK method + +``` +client.search(query, **kwargs) +``` + +### Example + +```python +results = client.search( + "firecrawl web scraping API", + limit=5, + scrape_options={"formats": ["markdown"]}, +) + +for item in results.web or []: + print(item.url, item.markdown[:200] if item.markdown else "") +``` + +### Parameters + +All parameters except `query` are keyword-only. + +| Parameter | Type | Description | +|---|---|---| +| `query` | `str` | Search query (required, positional). | +| `sources` | `list[SourceOption]` | Search sources (e.g. `"web"`, `"news"`, `"images"`). | +| `categories` | `list[CategoryOption]` | Category filters: `"github"`, `"research"`, `"pdf"`, `"developer"`. | +| `include_domains` | `list[str]` | Restrict results to these domains. Cannot combine with `exclude_domains`. | +| `exclude_domains` | `list[str]` | Exclude results from these domains. Cannot combine with `include_domains`. | +| `limit` | `int` | Max results. Default applied during serialization: `5`. | +| `tbs` | `str` | Time-based search filter (e.g. `"qdr:d"` for past day). | +| `location` | `str` | Location string for geo-targeted search. Note: this is a plain string, unlike `scrape`'s `Location` object. | +| `ignore_invalid_urls` | `bool` | Skip invalid URLs instead of failing. | +| `timeout` | `int` | Timeout in ms. Default applied during serialization: `300000`. | +| `highlights` | `bool` | Generate query-relevant highlights. Server default: `True`. | +| `scrape_options` | `ScrapeOptions \| dict` | Options for scraping each result page. | +| `enterprise` | `list[str]` | Enterprise options: `["zdr"]` or `["anon"]`. Must be enabled for your team. | +| `threat_protection` | `ThreatProtectionOptions` | Per-request threat protection overrides (enterprise). | +| `integration` | `str` | Integration identifier. | + +**Return type:** `SearchData` with attributes `web`, `news`, `images`, `developer` (lists). Do **not** access `.data` — it raises `AttributeError` with a helpful message. + +## Scrape + +### Why use it + +Use `scrape` when you already have a URL and want page content as markdown, HTML, screenshots, structured JSON, or other formats. + +### Preferred SDK method + +``` +client.scrape(url, **kwargs) +``` + +### Example + +```python +doc = client.scrape( + "https://example.com", + formats=["markdown", "links"], + only_main_content=True, +) + +print(doc.markdown) +print(doc.metadata.title if doc.metadata else "") +``` + +### Parameters + +All parameters except `url` are keyword-only. + +| Parameter | Type | Description | +|---|---|---| +| `url` | `str` | URL to scrape (required, positional). | +| `formats` | `list[FormatOption]` | Output formats: `"markdown"`, `"html"`, `"rawHtml"`, `"links"`, `"images"`, `"screenshot"`, `"summary"`, `"json"`, `"changeTracking"`, `"attributes"`, `"branding"`, `"product"`, `"menu"`, `"audio"`, `"video"`. Also accepts format config dicts for `json`, `screenshot`, `question`, `highlights`, `changeTracking`, `attributes`. | +| `headers` | `dict[str, str]` | Custom HTTP headers. | +| `include_tags` | `list[str]` | HTML tags to include. | +| `exclude_tags` | `list[str]` | HTML tags to exclude. | +| `only_main_content` | `bool` | Only return main content. Server default: `True`. | +| `timeout` | `int` | Timeout in ms. Server default: `60000`. | +| `wait_for` | `int` | Wait time in ms before scraping. Server default: `0`. | +| `mobile` | `bool` | Emulate mobile device. Server default: `False`. | +| `parsers` | `list` | Parser configuration (e.g. `["pdf"]` or `[PDFParser(mode="ocr")]`). | +| `actions` | `list[Action]` | Browser actions before scraping: `WaitAction`, `ClickAction`, `WriteAction`, `PressAction`, `ScrollAction`, `ScreenshotAction`, `ScrapeAction`, `ExecuteJavascriptAction`, `PDFAction`. | +| `location` | `Location` | Geolocation settings. `Location(country="US", languages=["en"])`. | +| `skip_tls_verification` | `bool` | Skip TLS cert verification. Server default: `True`. | +| `remove_base64_images` | `bool` | Remove base64 images. Server default: `True`. | +| `fast_mode` | `bool` | Enable fast mode. | +| `block_ads` | `bool` | Block ads. Server default: `True`. | +| `proxy` | `str` | Proxy mode: `"basic"`, `"stealth"`, `"enhanced"`, `"auto"`. Server default: `"auto"`. | +| `max_age` | `int` | Use cached result if younger than this (ms). Server default: `172800000`. | +| `store_in_cache` | `bool` | Cache the result. Server default: `True`. | +| `lockdown` | `bool` | Serve from cache only; never make outbound requests. | +| `profile` | `dict` | Persistent browser profile: `{"name": "my-profile", "saveChanges": True}`. | +| `audit_metadata` | `AuditMetadata` | User attribution for SIEM logging. | +| `threat_protection` | `ThreatProtectionOptions` | Per-request threat protection overrides (enterprise). | +| `integration` | `str` | Integration identifier. | + +**Return type:** `Document` (Pydantic model) with fields: `markdown`, `html`, `raw_html`, `json`, `summary`, `metadata`, `links`, `images`, `screenshot`, `audio`, `video`, `actions`, `answer`, `highlights`, `warning`, `change_tracking`, `branding`, `product`, `menu`. + +## Interact + +### Why use it + +Use `interact` to execute code or send a natural-language prompt in the browser session from a prior scrape. The scrape must have returned a `jobId` (in `metadata`). Use it for post-scrape automation — clicking, filling forms, navigating, or running arbitrary code. + +### Preferred SDK method + +``` +client.interact(job_id, code=None, *, prompt=None, language="node", timeout=None) +``` + +### Example + +```python +# First scrape to get a job_id +doc = client.scrape("https://example.com", formats=["markdown"]) +job_id = doc.metadata.scrape_id if doc.metadata else None + +# Then interact with the browser session +result = client.interact( + job_id, + code="document.title", + language="node", +) + +print(result.stdout) +print(result.result) +``` + +### Parameters + +| Parameter | Type | Description | +|---|---|---| +| `job_id` | `str` | Scrape job ID (required, positional). | +| `code` | `str \| None` | Code to execute (positional). At least one of `code` or `prompt` required. | +| `prompt` | `str \| None` | Natural-language instruction for the browser agent. At least one of `code` or `prompt` required. | +| `language` | `"python" \| "node" \| "bash"` | Language for code execution. Default: `"node"`. | +| `timeout` | `int \| None` | Execution timeout in seconds. Range: 1–300. Server default: `30`. | + +**Return type:** `BrowserExecuteResponse` with fields: `success`, `stdout`, `result`, `stderr`, `exit_code`, `killed`, `error`, `output`, `cdp_url`, `live_view_url`, `interactive_live_view_url`. + +### Stop a session + +```python +client.stop_interaction(job_id) +``` + +## Notes + +- **snake_case** parameter names throughout (e.g. `only_main_content`, `include_tags`, `wait_for`, `skip_tls_verification`). +- **Deprecated aliases**: `scrape_url` → `scrape`, `scrape_execute` → `interact`, `stop_interactive_browser` / `delete_scrape_browser` → `stop_interaction`. Use the preferred names. +- **`code` is positional** in `interact()`: you can call `client.interact(job_id, "some_code")` without naming the parameter. +- **`SearchData.data` trap**: Accessing `.data` on search results raises `AttributeError`. Use `.web`, `.news`, `.images`, or `.developer` instead. +- **`location` differs by endpoint**: In `scrape()`, `location` is a `Location` object (with `country` and `languages`). In `search()`, it is a plain `str`. +- **Keyless free tier**: Scrape, search, and interact work without an API key (rate-limited per IP). +- Legacy alias `FirecrawlApp` is available but `Firecrawl` is preferred. + +## Source Of Truth + +- `/firecrawl/apps/python-sdk/firecrawl/client.py` +- `/firecrawl/apps/python-sdk/firecrawl/v2/client.py` +- `/firecrawl/apps/python-sdk/firecrawl/v2/types.py` +- `/firecrawl-docs/api-reference/v2-openapi.json` diff --git a/agent-quickstart/rust.mdx b/agent-quickstart/rust.mdx new file mode 100644 index 000000000..62b930721 --- /dev/null +++ b/agent-quickstart/rust.mdx @@ -0,0 +1,253 @@ +--- +title: "Rust Agent Quickstart" +description: "Canonical Firecrawl Rust quickstart for external agents using search, scrape, and interact." +--- + +# Firecrawl Rust Agent Quickstart + +This file is the canonical quickstart for external agents integrating Firecrawl with Rust. Generated from SDK source (`firecrawl` crate v2) and the Firecrawl OpenAPI spec. + +## Install + +Add to your `Cargo.toml`: + +```toml +[dependencies] +firecrawl = "2" +tokio = { version = "1", features = ["full"] } +``` + +## Authenticate + +```rust +use firecrawl::Client; + +// With API key +let client = Client::new("fc-YOUR_API_KEY")?; + +// With custom API URL (self-hosted) +let client = Client::new_selfhosted( + "https://your-firecrawl.example.com", + Some("fc-YOUR_API_KEY"), +)?; + +// Keyless free tier (rate-limited per IP) +let client = Client::new_selfhosted("https://api.firecrawl.dev", None::<&str>)?; +``` + +## When To Use What + +- **`search`**: Start with a query, discover relevant pages. Returns search results with optional scraping of each result. +- **`scrape`**: Start with a URL, get page content in markdown, HTML, or other formats. +- **`interact`**: Execute code or send a prompt in a browser session from a prior scrape. Use for post-scrape browser automation. + +## Search + +### Why use it + +Use `search` when you have a query and want to discover relevant web pages. Optionally scrape each result to get full page content. + +### Preferred SDK method + +``` +client.search(query, options).await +``` + +### Example + +```rust +use firecrawl::{Client, SearchOptions, ScrapeOptions, Format}; + +let client = Client::new("fc-YOUR_API_KEY")?; + +let response = client.search("firecrawl web scraping API", SearchOptions { + limit: Some(5), + scrape_options: Some(ScrapeOptions { + formats: Some(vec![Format::Markdown]), + ..Default::default() + }), + ..Default::default() +}).await?; + +if let Some(web) = &response.data.web { + for item in web { + println!("{:?}", item); + } +} +``` + +### Parameters + +All fields on `SearchOptions` are `Option` and default to `None` (omitted from request). + +| Parameter | Type | Description | +|---|---|---| +| `query` | `&str` | Search query (required, first argument). | +| `limit` | `Option` | Max results. Server default: `10`. | +| `sources` | `Option>` | Sources: `SearchSource::Web`, `News`, `Images`. | +| `categories` | `Option>` | Categories: `SearchCategory::Github`, `Research`, `Pdf`. | +| `include_domains` | `Option>` | Restrict results to these domains. | +| `exclude_domains` | `Option>` | Exclude results from these domains. | +| `tbs` | `Option` | Time-based filter (e.g. `"qdr:d"`). | +| `location` | `Option` | Location string for geo-targeted search. | +| `ignore_invalid_urls` | `Option` | Skip invalid URLs. | +| `timeout` | `Option` | Timeout in ms. | +| `highlights` | `Option` | Generate query-relevant highlights. Server default: `true`. | +| `scrape_options` | `Option` | Options for scraping each result page. | +| `integration` | `Option` | Integration identifier. | + +**Return type:** `SearchResponse` with `success: bool`, `data: SearchData`, `warning: Option`. `SearchData` has `web: Option>`, `news`, `images`. + +### Convenience method + +```rust +let docs = client.search_and_scrape("query", 5).await?; +``` + +Calls `search` with default `ScrapeOptions` and returns only `Document` results. + +## Scrape + +### Why use it + +Use `scrape` when you already have a URL and want page content as markdown, HTML, screenshots, structured JSON, or other formats. + +### Preferred SDK method + +``` +client.scrape(url, options).await +``` + +### Example + +```rust +use firecrawl::{Client, ScrapeOptions, Format}; + +let client = Client::new("fc-YOUR_API_KEY")?; + +let doc = client.scrape("https://example.com", ScrapeOptions { + formats: Some(vec![Format::Markdown, Format::Links]), + only_main_content: Some(true), + ..Default::default() +}).await?; + +println!("{}", doc.markdown.unwrap_or_default()); +``` + +### Parameters + +All fields on `ScrapeOptions` are `Option` and default to `None`. + +| Parameter | Type | Description | +|---|---|---| +| `url` | `&str` | URL to scrape (required, first argument). | +| `formats` | `Option>` | Output formats. Enum variants: `Markdown`, `Html`, `RawHtml`, `Links`, `Images`, `Screenshot`, `Summary`, `ChangeTracking`, `Json`, `Attributes`, `Branding`, `Product`, `Menu`, `Audio`, `Video`. Also: `Question(QuestionFormat)`, `Highlights(HighlightsFormat)`. | +| `headers` | `Option>` | Custom HTTP headers. | +| `include_tags` | `Option>` | HTML tags to include. | +| `exclude_tags` | `Option>` | HTML tags to exclude. | +| `only_main_content` | `Option` | Only return main content. Server default: `true`. | +| `timeout` | `Option` | Timeout in ms. Server default: `60000`. | +| `wait_for` | `Option` | Wait time in ms before scraping. Server default: `0`. | +| `mobile` | `Option` | Emulate mobile device. Server default: `false`. | +| `parsers` | `Option>` | Parser configuration (e.g. PDF handling). | +| `actions` | `Option>` | Browser actions before scraping. Enum variants: `Wait`, `Click`, `Write`, `Press`, `Scroll`, `Screenshot`, `Scrape`, `ExecuteJavascript`. | +| `location` | `Option` | Geolocation: `{ country, languages }`. | +| `skip_tls_verification` | `Option` | Skip TLS cert verification. | +| `remove_base64_images` | `Option` | Remove base64 images. | +| `fast_mode` | `Option` | Enable fast mode. | +| `block_ads` | `Option` | Block ads. Server default: `true`. | +| `proxy` | `Option` | Proxy mode: `Basic`, `Stealth`, `Enhanced`, `Auto`. Server default: `Auto`. | +| `max_age` | `Option` | Use cached result if younger than this (ms). | +| `store_in_cache` | `Option` | Cache the result. | +| `lockdown` | `Option` | Serve from cache only. | +| `redact_pii` | `Option` | Redact PII from output. | +| `profile` | `Option` | Persistent browser profile: `{ name, save_changes }`. | +| `audit_metadata` | `Option` | User attribution for SIEM logging. | +| `json_options` | `Option` | JSON extraction: `{ schema, system_prompt, prompt }`. | +| `screenshot_options` | `Option` | Screenshot config: `{ full_page, quality, viewport }`. | +| `change_tracking_options` | `Option` | Change tracking config. | +| `attribute_selectors` | `Option>` | Attribute selectors: `{ selector, attribute }`. | +| `integration` | `Option` | Integration identifier. | + +**Return type:** `Document` with optional fields: `markdown`, `html`, `raw_html`, `json`, `summary`, `metadata`, `links`, `images`, `screenshot`, `audio`, `video`, `actions`, `answer`, `highlights`, `warning`, `change_tracking`, `branding`, `product`, `menu`. + +### Convenience method + +```rust +let json_value = client.scrape_with_schema("https://example.com", schema, Some("Extract product info")).await?; +``` + +## Interact + +### Why use it + +Use `interact` to execute code or send a natural-language prompt in the browser session from a prior scrape. The scrape must have returned a job ID. Use it for post-scrape automation. + +### Preferred SDK method + +``` +client.interact(job_id, options).await +``` + +### Example + +```rust +use firecrawl::{Client, ScrapeOptions, ScrapeExecuteOptions, Format}; + +let client = Client::new("fc-YOUR_API_KEY")?; + +// First scrape to get a job_id +let doc = client.scrape("https://example.com", ScrapeOptions { + formats: Some(vec![Format::Markdown]), + ..Default::default() +}).await?; + +let job_id = doc.metadata + .as_ref() + .and_then(|m| m.get("jobId")) + .and_then(|v| v.as_str()) + .expect("no jobId"); + +// Interact with the browser session +let result = client.interact(job_id, ScrapeExecuteOptions { + code: Some("document.title".to_string()), + ..Default::default() +}).await?; + +println!("{:?}", result.stdout); +``` + +### Parameters + +| Parameter | Type | Description | +|---|---|---| +| `job_id` | `&str` | Scrape job ID (required, first argument). | +| `code` | `Option` | Code to execute. At least one of `code` or `prompt` required (client-side validation). | +| `prompt` | `Option` | Natural-language instruction for the browser agent. | +| `language` | `Option` | Language: `Python`, `Node`, `Bash`. Default: `Node`. | +| `timeout` | `Option` | Execution timeout in seconds. Range: 1–300. Server default: `30`. | + +**Return type:** `ScrapeExecuteResponse` with fields: `success`, `stdout`, `result`, `stderr`, `exit_code`, `killed`, `error`, `live_view_url`, `interactive_live_view_url`, `output`. + +### Stop a session + +```rust +client.stop_interaction(job_id).await?; +``` + +## Notes + +- **snake_case** field names throughout, serialized to camelCase via `#[serde(rename_all = "camelCase")]`. +- **No builder pattern**: Use struct-update syntax `..Default::default()` to fill optional fields. +- **`impl Into>`**: Both `scrape` and `search` accept `None`, `Some(opts)`, or `opts` directly for the options argument. +- **All methods are `async`** and return `Result`. +- **Deprecated aliases**: `scrape_execute` → `interact`, `stop_interactive_browser` / `delete_scrape_browser` → `stop_interaction`. +- **Client-side validation**: `interact` returns `FirecrawlError::Misuse` if neither `code` nor `prompt` is provided. +- **Keyless free tier**: Works without an API key (rate-limited per IP). + +## Source Of Truth + +- `/firecrawl/apps/rust-sdk/src/client.rs` +- `/firecrawl/apps/rust-sdk/src/scrape.rs` +- `/firecrawl/apps/rust-sdk/src/search.rs` +- `/firecrawl-docs/api-reference/v2-openapi.json`