Appearance
Extract API
Updated Feb 2026The Extract API (/v1/extract) gathers structured data from one or more URLs using LLM-powered extraction. It handles crawling, parsing, and collating datasets -- distinct from the JSON mode on scrape which operates on a single page.
Extract vs Scrape + JSON Mode
- Scrape + JSON Mode (
/v2/scrape): Extract structured data from one URL during a scrape. See LLM Extract. - Extract API (
/v1/extract): Extract structured data across multiple URLs, supports async operations, wildcards, web search enrichment, and the FIRE-1 agent for complex interactions.
Overview
Rate Limit: 10 requests per minute
Extraction Modes
| Mode | Description | When to Use |
|---|---|---|
| Schema-based | Provide a JSON Schema for rigid, typed output | You know the exact structure you need |
| Prompt-only | Let the LLM determine output structure | Exploratory extraction, flexible needs |
| Schema + Prompt | Schema for structure, prompt for guidance | Maximum control over extraction |
| No URLs (Alpha) | Extract using only a prompt, no URLs | Let the system find relevant data |
| FIRE-1 Agent | Browser automation for complex pages | Paginated data, dynamic elements, forms |
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
urls | string[] | No* | Target URLs; supports wildcards (e.g., https://example.com/*) |
prompt | string | Yes | Natural language description of the data to extract |
schema | object | No | JSON Schema defining the output structure |
enableWebSearch | boolean | No | Follow external links for enriched results |
agent | object | No | Agent configuration (e.g., {"model": "FIRE-1"}) |
*URLs are optional in Alpha mode (prompt-only extraction).
URL Patterns
python
# Single URL
urls = ["https://example.com/pricing"]
# Multiple specific URLs
urls = [
"https://example.com/pricing",
"https://example.com/features",
"https://example.com/about"
]
# Wildcard (experimental) — matches all pages on the domain
urls = ["https://example.com/*"]Wildcard Support
Wildcard URL patterns (/*) are experimental. Coverage of large sites may be incomplete, and results can vary on dynamic sites.
Basic Usage
Schema-Based Extraction
Python
python
from firecrawl import FirecrawlApp
app = FirecrawlApp(api_key="fc-YOUR-API-KEY")
result = app.extract(
urls=["https://firecrawl.dev/pricing"],
prompt="Extract all pricing plans with their names, prices, and included features",
schema={
"type": "object",
"properties": {
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"monthly_price": {"type": "string"},
"annual_price": {"type": "string"},
"features": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["name", "monthly_price"]
}
}
},
"required": ["plans"]
}
)
for plan in result['data']['plans']:
print(f"{plan['name']}: {plan['monthly_price']}/mo")Node.js
javascript
import FirecrawlApp from '@mendable/firecrawl-js';
const app = new FirecrawlApp({ apiKey: "fc-YOUR-API-KEY" });
const result = await app.extract({
urls: ["https://firecrawl.dev/pricing"],
prompt: "Extract all pricing plans with their names, prices, and included features",
schema: {
type: "object",
properties: {
plans: {
type: "array",
items: {
type: "object",
properties: {
name: { type: "string" },
monthly_price: { type: "string" },
annual_price: { type: "string" },
features: { type: "array", items: { type: "string" } }
},
required: ["name", "monthly_price"]
}
}
},
required: ["plans"]
}
});
console.log(result.data);cURL
bash
curl -X POST https://api.firecrawl.dev/v1/extract \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-YOUR-API-KEY' \
-d '{
"urls": ["https://firecrawl.dev/pricing"],
"prompt": "Extract all pricing plans with their names, prices, and included features",
"schema": {
"type": "object",
"properties": {
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"monthly_price": {"type": "string"},
"features": {"type": "array", "items": {"type": "string"}}
},
"required": ["name", "monthly_price"]
}
}
},
"required": ["plans"]
}
}'Prompt-Only Extraction
Let the LLM decide the output structure:
python
result = app.extract(
urls=["https://firecrawl.dev"],
prompt="Extract all information about the company's products, pricing, and team"
)
print(result['data'])
# Structure determined by the LLM based on page contentjavascript
const result = await app.extract({
urls: ["https://firecrawl.dev"],
prompt: "Extract all information about the company's products, pricing, and team"
});With Web Search Enrichment
Follow external links to gather additional context:
python
result = app.extract(
urls=["https://example.com/company"],
prompt="Extract company information and recent funding details",
schema={
"type": "object",
"properties": {
"name": {"type": "string"},
"founded": {"type": "string"},
"funding": {"type": "string"},
"investors": {"type": "array", "items": {"type": "string"}}
}
},
enableWebSearch=True # Follow links for enrichment
)With FIRE-1 Agent
For pages requiring browser interaction:
python
result = app.extract(
urls=["https://example.com/products"],
prompt="Navigate through all pagination pages and extract every product name, price, and rating",
schema={
"type": "object",
"properties": {
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"price": {"type": "string"},
"rating": {"type": "number"}
}
}
}
}
},
agent={"model": "FIRE-1"}
)See FIRE-1 Agent Model for full documentation.
Async Operations
For long-running extractions, use the start/poll pattern:
Python
python
# Start the extraction job (returns immediately)
job = app.start_extract(
urls=["https://example.com/*"],
prompt="Extract all product information from the site",
schema={...}
)
print(f"Job ID: {job['id']}")
# Poll for status
import time
while True:
status = app.get_extract_status(job['id'])
print(f"Status: {status['status']}")
if status['status'] == 'completed':
print(status['data'])
break
elif status['status'] == 'failed':
print(f"Error: {status.get('error')}")
break
time.sleep(5)Node.js
javascript
// Start the extraction job
const job = await app.startExtract({
urls: ["https://example.com/*"],
prompt: "Extract all product information from the site",
schema: {...}
});
console.log(`Job ID: ${job.id}`);
// Poll for status
let status;
do {
await new Promise(resolve => setTimeout(resolve, 5000));
status = await app.getExtractStatus(job.id);
console.log(`Status: ${status.status}`);
} while (status.status === 'processing');
if (status.status === 'completed') {
console.log(status.data);
}cURL
bash
# Start extraction
curl -X POST https://api.firecrawl.dev/v1/extract \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer fc-YOUR-API-KEY' \
-d '{
"urls": ["https://example.com/*"],
"prompt": "Extract all product information",
"schema": {...}
}'
# Response: {"success": true, "id": "extract-abc123"}
# Check status
curl -X GET https://api.firecrawl.dev/v1/extract/extract-abc123 \
-H 'Authorization: Bearer fc-YOUR-API-KEY'Job Status Values
| Status | Description |
|---|---|
processing | Job is running |
completed | Results are ready |
failed | Job encountered an error |
cancelled | Job was cancelled |
Results are accessible for 24 hours after completion.
Response Format
json
{
"success": true,
"data": {
"plans": [
{
"name": "Free",
"monthly_price": "$0",
"features": ["500 credits", "5 agent runs/day"]
},
{
"name": "Starter",
"monthly_price": "$19",
"features": ["3,000 credits", "Batch scrape", "Priority support"]
}
]
}
}Extract vs Agent API
| Feature | Extract (/v1/extract) | Agent (/v2/agent) |
|---|---|---|
| Purpose | Structured extraction from known URLs | Autonomous research |
| URLs | Required (or wildcard) | Optional |
| Web Search | Optional (enableWebSearch) | Built-in |
| Browser Agent | FIRE-1 (optional) | Spark-1 Mini/Pro |
| Output | Schema-defined JSON | Schema or unstructured |
| Best For | Targeted data collection | Open-ended research |
When to Use Which
- Known URLs, need structured data --> Extract API
- Don't know where the data is --> Agent API
- Single page, simple extraction --> Scrape + JSON mode
- Complex page interactions needed --> Extract API + FIRE-1
Pricing
Extract API uses a unified credit system where each credit equals approximately 15 tokens. Costs vary based on:
- Number of URLs processed
- Prompt complexity
- Schema size
- Data volume in responses
- FIRE-1 agent usage (if enabled)
See Pricing for full details.
Limitations (Beta)
The Extract API is in beta. Current limitations:
- Large sites: Full coverage of massive sites with wildcards may be incomplete
- Complex queries: Highly complex logical queries may produce inconsistent results
- Dynamic sites: Results may vary on frequently updated or JavaScript-heavy sites
- Rate limit: 10 requests per minute
Related Pages
- LLM Extract (JSON Mode) -- Single-page extraction on scrape
- FIRE-1 Agent Model -- Browser automation agent
- Agent API -- Autonomous research with Spark-1
- AI Models -- Model comparison and selection
- Batch Scrape -- Bulk URL scraping
Next: Features Overview -->