Appearance
Rust SDK
Updated Feb 2026A community-maintained Rust SDK for Firecrawl. Supports the v1 API with async methods powered by Tokio. Provides scraping, crawling, mapping, and JSON extraction capabilities.
| Crate | firecrawl |
| Version | ^1.0 |
| API Versions | v1 |
| Maintained by | Community |
| Source | github.com/mendableai/firecrawl |
Community SDK
This SDK is community-maintained and only supports the v1 API. For v2 features like search, batch scrape, extract, agent, and browser sessions, use the Python SDK or Node.js SDK.
Installation
Add the following to your Cargo.toml:
toml
[dependencies]
firecrawl = "^1.0"
tokio = { version = "^1", features = ["full"] }
serde_json = "1"Initialization
Create a FirecrawlApp instance with your API key:
rust
use firecrawl::FirecrawlApp;
#[tokio::main]
async fn main() {
let app = FirecrawlApp::new("fc-YOUR-API-KEY")
.expect("Failed to initialize FirecrawlApp");
}Methods
scrape_url()
Scrapes a single URL and returns a Document object. See Scrape feature docs for general parameter details.
Signature:
rust
async fn scrape_url(
&self,
url: &str,
options: Option<ScrapeOptions>
) -> Result<Document, FirecrawlError>ScrapeOptions fields:
| Field | Type | Description |
|---|---|---|
formats | Vec<ScrapeFormats> | Output formats: Markdown, HTML, Json |
json_options | Option<ExtractOptions> | JSON extraction schema and prompt |
Basic example:
rust
use firecrawl::{FirecrawlApp, ScrapeOptions, ScrapeFormats};
#[tokio::main]
async fn main() {
let app = FirecrawlApp::new("fc-YOUR-API-KEY").unwrap();
let options = ScrapeOptions {
formats: vec![ScrapeFormats::Markdown, ScrapeFormats::HTML],
..Default::default()
};
let result = app.scrape_url("https://firecrawl.dev", Some(options))
.await
.unwrap();
println!("{}", result.markdown.unwrap_or_default());
}With JSON extraction:
rust
use firecrawl::{FirecrawlApp, ScrapeOptions, ScrapeFormats, ExtractOptions};
use serde_json::json;
#[tokio::main]
async fn main() {
let app = FirecrawlApp::new("fc-YOUR-API-KEY").unwrap();
let options = ScrapeOptions {
formats: vec![ScrapeFormats::Json],
json_options: Some(ExtractOptions {
schema: Some(json!({
"type": "object",
"properties": {
"title": { "type": "string" },
"description": { "type": "string" },
"features": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["title", "description"]
})),
prompt: Some("Extract the page title, description, and key features".to_string()),
..Default::default()
}),
..Default::default()
};
let result = app.scrape_url("https://firecrawl.dev", Some(options))
.await
.unwrap();
if let Some(extracted) = result.extract {
println!("Extracted: {}", extracted);
}
}crawl_url()
Crawls a website synchronously, waiting for the job to complete before returning. See Crawl feature docs for general parameter details.
Signature:
rust
async fn crawl_url(
&self,
url: &str,
options: Option<CrawlOptions>
) -> Result<CrawlResult, FirecrawlError>CrawlOptions fields:
| Field | Type | Description |
|---|---|---|
scrape_options | Option<CrawlScrapeOptions> | Scrape settings for each page |
limit | Option<u32> | Maximum pages to crawl |
Example:
rust
use firecrawl::{FirecrawlApp, CrawlOptions, CrawlScrapeOptions, CrawlScrapeFormats};
#[tokio::main]
async fn main() {
let app = FirecrawlApp::new("fc-YOUR-API-KEY").unwrap();
let options = CrawlOptions {
scrape_options: Some(CrawlScrapeOptions {
formats: Some(vec![CrawlScrapeFormats::Markdown]),
..Default::default()
}),
limit: Some(100),
..Default::default()
};
let result = app.crawl_url("https://docs.firecrawl.dev", Some(options))
.await
.unwrap();
println!("Credits used: {}", result.credits_used);
for doc in &result.data {
println!("Page: {}", doc.markdown.as_deref().unwrap_or("N/A"));
}
}crawl_url_async()
Initiates a non-blocking crawl that returns immediately with a job ID.
Signature:
rust
async fn crawl_url_async(
&self,
url: &str,
options: Option<CrawlOptions>
) -> Result<CrawlAsyncResponse, FirecrawlError>Example:
rust
let response = app.crawl_url_async("https://docs.firecrawl.dev", Some(options))
.await
.unwrap();
println!("Crawl ID: {}", response.id);check_crawl_status()
Checks the status of an asynchronous crawl job.
Signature:
rust
async fn check_crawl_status(
&self,
crawl_id: &str
) -> Result<CrawlStatus, FirecrawlError>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
crawl_id | &str | Yes | Job ID from crawl_url_async() |
Example:
rust
use firecrawl::CrawlStatusTypes;
let status = app.check_crawl_status(&response.id)
.await
.unwrap();
if status.status == CrawlStatusTypes::Completed {
println!("Crawl complete!");
for doc in &status.data {
println!("{}", doc.markdown.as_deref().unwrap_or("N/A"));
}
} else {
println!("Status: {:?}", status.status);
}Polling loop:
rust
use tokio::time::{sleep, Duration};
loop {
let status = app.check_crawl_status(&response.id).await.unwrap();
match status.status {
CrawlStatusTypes::Completed => {
println!("Done! {} pages crawled", status.data.len());
break;
}
CrawlStatusTypes::Failed => {
eprintln!("Crawl failed");
break;
}
_ => {
println!("Still crawling...");
sleep(Duration::from_secs(5)).await;
}
}
}map_url()
Discovers all URLs on a website without scraping their content. See Map feature docs for general parameter details.
Signature:
rust
async fn map_url(
&self,
url: &str,
options: Option<MapOptions>
) -> Result<Vec<String>, FirecrawlError>Example:
rust
let urls = app.map_url("https://firecrawl.dev", None)
.await
.unwrap();
for url in &urls {
println!("{}", url);
}
println!("Total URLs found: {}", urls.len());Complete Example
A full working example demonstrating scrape, crawl, status check, and map:
rust
use firecrawl::{
FirecrawlApp, ScrapeOptions, ScrapeFormats,
CrawlOptions, CrawlScrapeOptions, CrawlScrapeFormats,
CrawlStatusTypes,
};
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let app = FirecrawlApp::new("fc-YOUR-API-KEY")?;
// 1. Scrape a single page
let scrape_opts = ScrapeOptions {
formats: vec![ScrapeFormats::Markdown],
..Default::default()
};
let doc = app.scrape_url("https://firecrawl.dev", Some(scrape_opts)).await?;
println!("Scraped: {} chars", doc.markdown.as_ref().map_or(0, |m| m.len()));
// 2. Start an async crawl
let crawl_opts = CrawlOptions {
limit: Some(10),
scrape_options: Some(CrawlScrapeOptions {
formats: Some(vec![CrawlScrapeFormats::Markdown]),
..Default::default()
}),
..Default::default()
};
let crawl = app.crawl_url_async("https://docs.firecrawl.dev", Some(crawl_opts)).await?;
println!("Crawl started: {}", crawl.id);
// 3. Poll for completion
loop {
let status = app.check_crawl_status(&crawl.id).await?;
match status.status {
CrawlStatusTypes::Completed => {
println!("Crawl done: {} pages", status.data.len());
break;
}
_ => {
println!("Crawling...");
sleep(Duration::from_secs(5)).await;
}
}
}
// 4. Map site URLs
let urls = app.map_url("https://firecrawl.dev", None).await?;
println!("Mapped {} URLs", urls.len());
Ok(())
}Error Handling
The SDK uses a FirecrawlError enum that implements the standard Error, Debug, and Display traits:
rust
match app.scrape_url("https://example.com", None).await {
Ok(doc) => println!("Success: {}", doc.markdown.unwrap_or_default()),
Err(e) => eprintln!("Firecrawl error: {}", e),
}Common error scenarios:
| Scenario | Cause |
|---|---|
| Invalid API key | Key is missing, expired, or malformed |
| Rate limit exceeded | Too many requests in a short period |
| URL not reachable | Target URL is down or blocked |
| Network error | Connection timeout or DNS failure |
Important Notes
- All methods are async and require the Tokio runtime (
#[tokio::main]). - Completed crawl results are auto-deleted after 24 hours. Download results promptly.
- v2 API features (sitemap-only crawling, search, batch scrape, extract, agent, browser sessions) are not available in this SDK. For v2 sitemap-only crawling, you can call the REST endpoint directly using
reqwest.
Limitations
Since this is a community SDK targeting v1, the following v2 features are not available:
- Search
- Batch scrape
- Extract
- Agent
- Browser sessions
- WebSocket watcher
- Auto-pagination
For these features, use the Python SDK, Node.js SDK, or CLI.
Related Pages
- SDKs Overview -- Compare all available SDKs
- Python SDK -- Full-featured Python SDK
- Node.js SDK -- Full-featured Node.js SDK
- Go SDK -- Community Go SDK (also v1)
- Scrape -- Single-page extraction details
- Crawl -- Multi-page crawling details
- Map -- URL discovery details