Skip to content

LLM Extract (JSON Mode)

Updated Feb 2026

Extract structured data from any web page using AI-powered JSON extraction. Define a schema or provide a prompt, and Firecrawl returns clean, typed data. This is the JSON format option on the scrape endpoint.

Extract API vs LLM Extract

This page covers JSON mode on /v2/scrape -- extracting structured data from a single URL during scraping. For the dedicated Extract API (/v1/extract) which handles multi-URL extraction and supports the FIRE-1 agent, see Extract API.

Overview

LLM Extract works by converting the page to markdown, then passing it through an LLM with your schema or prompt to produce structured JSON output.

Cost: +4 credits per page (on top of the base 1 credit scrape).

Schema-Based Extraction

With Pydantic (Python)

python
from firecrawl import Firecrawl
from pydantic import BaseModel, Field
from typing import List, Optional

firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

class CompanyInfo(BaseModel):
    company_mission: str = Field(description="The company's mission statement")
    supports_sso: bool = Field(description="Whether the company offers SSO")
    is_open_source: bool = Field(description="Whether the product is open source")
    pricing_tiers: List[str] = Field(description="Names of pricing tiers")

result = firecrawl.scrape(
    "https://firecrawl.dev",
    formats=[{
        "type": "json",
        "schema": CompanyInfo.model_json_schema()
    }],
    only_main_content=False,
    timeout=120000
)

print(result['json'])
# {"company_mission": "...", "supports_sso": true, "is_open_source": true, "pricing_tiers": ["Free", "Starter", "Growth"]}

With Zod (Node.js)

javascript
import Firecrawl from '@mendable/firecrawl-js';
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';

const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

const CompanyInfo = z.object({
  company_mission: z.string().describe("The company's mission statement"),
  supports_sso: z.boolean().describe("Whether the company offers SSO"),
  is_open_source: z.boolean().describe("Whether the product is open source"),
  pricing_tiers: z.array(z.string()).describe("Names of pricing tiers"),
});

const result = await firecrawl.scrape("https://firecrawl.dev", {
  formats: [{
    type: "json",
    schema: zodToJsonSchema(CompanyInfo)
  }],
  onlyMainContent: false,
  timeout: 120000
});

console.log(result.json);

With Raw JSON Schema (cURL)

bash
curl -X POST https://api.firecrawl.dev/v2/scrape \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer fc-YOUR-API-KEY' \
  -d '{
    "url": "https://firecrawl.dev",
    "formats": [{
      "type": "json",
      "schema": {
        "type": "object",
        "properties": {
          "company_mission": {"type": "string"},
          "supports_sso": {"type": "boolean"},
          "is_open_source": {"type": "boolean"},
          "pricing_tiers": {
            "type": "array",
            "items": {"type": "string"}
          }
        },
        "required": ["company_mission", "supports_sso", "is_open_source"]
      }
    }],
    "onlyMainContent": false,
    "timeout": 120000
  }'

Prompt-Based Extraction (No Schema)

When you do not need a rigid structure, use a prompt to guide the LLM:

python
result = firecrawl.scrape(
    "https://firecrawl.dev",
    formats=[{
        "type": "json",
        "prompt": "Extract the company mission, key features, and pricing information from this page."
    }],
    only_main_content=False
)

print(result['json'])
# LLM determines the output structure based on your prompt
javascript
const result = await firecrawl.scrape("https://firecrawl.dev", {
  formats: [{
    type: "json",
    prompt: "Extract the company mission, key features, and pricing information from this page."
  }],
  onlyMainContent: false
});
bash
curl -X POST https://api.firecrawl.dev/v2/scrape \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer fc-YOUR-API-KEY' \
  -d '{
    "url": "https://firecrawl.dev",
    "formats": [{"type": "json", "prompt": "Extract the company mission, key features, and pricing information."}],
    "onlyMainContent": false
  }'

Schema + Prompt Combined

Use both for maximum control -- the schema defines the structure, and the prompt guides the extraction:

python
result = firecrawl.scrape(
    "https://firecrawl.dev",
    formats=[{
        "type": "json",
        "schema": CompanyInfo.model_json_schema(),
        "prompt": "Focus on the main product page content. Ignore blog posts and documentation links."
    }],
    only_main_content=False
)

Parameters

ParameterTypeRequiredDescription
typestringYesMust be "json"
schemaobjectNo*JSON Schema defining output structure
promptstringNo*Natural language extraction guidance
only_main_contentbooleanNoFilter to main content area (default: true)
timeoutnumberNoRequest timeout in milliseconds

*At least one of schema or prompt is required.

Response Format

json
{
  "success": true,
  "data": {
    "json": {
      "company_mission": "Make the web accessible to AI",
      "supports_sso": true,
      "is_open_source": true,
      "pricing_tiers": ["Free", "Starter", "Growth", "Enterprise"]
    },
    "metadata": {
      "title": "Firecrawl - Turn websites into LLM-ready data",
      "description": "...",
      "ogTitle": "...",
      "sourceURL": "https://firecrawl.dev",
      "statusCode": 200
    }
  }
}

Important Limitations

HTML Attributes Are Stripped

JSON extraction works on the markdown conversion of the page, which only preserves visible text content. HTML attributes like data-id, class, href, and custom attributes are stripped during conversion and are not accessible to the LLM.

Workarounds:

  1. Use rawHtml format -- request both json and rawHtml, then parse attributes client-side
  2. Use executeJavascript action -- inject attribute values into visible text before extraction
python
# Workaround: Inject data attributes into visible text
result = firecrawl.scrape(
    "https://example.com/products",
    formats=[{
        "type": "json",
        "schema": {...}
    }],
    actions=[{
        "type": "executeJavascript",
        "code": """
            document.querySelectorAll('[data-product-id]').forEach(el => {
                el.textContent += ` [ID: ${el.dataset.productId}]`;
            });
        """
    }]
)

Token Limits

Very long pages may exceed the LLM's context window. Strategies:

  • Set only_main_content: true to reduce content
  • Use specific, focused schemas instead of extracting everything
  • Consider Extract API for multi-page extraction tasks

Common Patterns

E-Commerce Product Data

python
class Product(BaseModel):
    name: str
    price: str
    description: str
    rating: Optional[float]
    reviews_count: Optional[int]
    in_stock: bool
    categories: List[str]

result = firecrawl.scrape(
    "https://store.example.com/product/widget-pro",
    formats=[{"type": "json", "schema": Product.model_json_schema()}]
)

Contact Information

python
class ContactInfo(BaseModel):
    company_name: str
    email: Optional[str]
    phone: Optional[str]
    address: Optional[str]
    social_links: List[str]

result = firecrawl.scrape(
    "https://example.com/contact",
    formats=[{"type": "json", "schema": ContactInfo.model_json_schema()}],
    only_main_content=False  # Contact info often in footer
)

Job Listings

python
class JobListing(BaseModel):
    title: str
    department: str
    location: str
    type: str  # full-time, part-time, contract
    description: str

class JobListings(BaseModel):
    jobs: List[JobListing]

result = firecrawl.scrape(
    "https://example.com/careers",
    formats=[{"type": "json", "schema": JobListings.model_json_schema()}]
)

Cost

OperationCredits
Base scrape1
JSON extraction add-on+4
Total per page5

JSON extraction in batch scrape applies the +4 cost per URL.

  • Scrape -- All scrape formats including JSON mode
  • Extract API -- Multi-URL extraction with FIRE-1 agent support
  • FIRE-1 -- AI agent for complex browser-based extraction
  • Batch Scrape -- Bulk extraction with schemas
  • AI Models -- Model selection for extraction tasks

Next: AI Models -->