| title | SmartCrawler |
|---|---|
| description | AI-powered website crawling and multi-page extraction |
| icon | spider |
SmartCrawler is our advanced web crawling service that offers two modes:
- AI-Powered Extraction: LLM-powered web crawling with intelligent data extraction (10 credits per page)
- Markdown Conversion: Cost-effective HTML to markdown conversion without AI/LLM processing (2 credits per page - 80% savings!)
Unlike SmartScraper, which extracts data from a single page, SmartCrawler can traverse multiple pages, follow links, and either extract structured data or convert content to clean markdown from entire websites or sections.
Try SmartCrawler instantly in our [interactive playground](https://dashboard.scrapegraphai.com/)from scrapegraph_py import Client
client = Client(api_key="your-api-key")
response = client.crawl(
url="https://scrapegraphai.com/",
prompt="Extract info about the company",
depth=2,
breadth=None,
max_pages=10,
rules={
"include_paths": ["/about", "/services/*"],
"exclude_paths": ["/admin/*", "/api/**"],
"same_domain": True
}
)import { smartCrawler } from 'scrapegraph-js';
const apiKey = 'your-api-key';
const url = 'https://scrapegraphai.com';
const prompt = 'Extract info about the company';
const depth = 2;
const breadth = null;
const maxPages = 10;
const rules = {
include_paths: ['/about', '/services/*'],
exclude_paths: ['/admin/*', '/api/**'],
same_domain: true
};
try {
const response = await smartCrawler(apiKey, url, prompt, depth, breadth, maxPages, null, rules);
console.log(response);
} catch (error) {
console.error(error);
}curl -X 'POST' \
'https://api.scrapegraphai.com/v1/crawl' \
-H 'accept: application/json' \
-H 'SGAI-APIKEY: your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://scrapegraphai.com/",
"prompt": "Extract info about the company",
"depth": 2,
"breadth": null,
"max_pages": 10,
"rules": {
"include_paths": ["/about", "/services/*"],
"exclude_paths": ["/admin/*", "/api/**"],
"same_domain": true
}
}'| Header | Description |
|---|---|
| SGAI-APIKEY | Your API authentication key |
| Content-Type | application/json |
| Parameter | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | The starting URL for the crawl. |
| prompt | string | No* | Instructions for what to extract (*required when extraction_mode=true). |
| extraction_mode | bool | No | When false, enables markdown conversion mode (default: true). |
| depth | int | No | How many link levels to follow (default: 1). |
| breadth | int | No | Maximum number of links to crawl per depth level. If null/undefined, unlimited (default). Controls the 'width' of exploration at each depth. Useful for limiting crawl scope on large sites. Note: max_pages always takes priority. Ignored when sitemap=true. |
| max_pages | int | No | Maximum number of pages to crawl (default: 20). |
| schema | object | No | Pydantic or Zod schema for structured output. |
| rules | object | No | Crawl rules object with optional fields: exclude (array of regex URL patterns), include_paths (array of path patterns to include, supports wildcards * and **), exclude_paths (array of path patterns to exclude, takes precedence over include_paths), same_domain (boolean, default: true). See below for details. |
| sitemap | bool | No | Use sitemap.xml for discovery (default: false). |
| webhook_url | string | No | URL to receive webhook notification on job completion. |
| wait_ms | int | No | Milliseconds to wait before scraping each page. Useful for pages with heavy JavaScript rendering that need extra time to load (default: 3000). |
For cost-effective content archival and when you only need clean markdown without AI processing, use the markdown conversion mode. This mode offers significant cost savings and is perfect for documentation, content migration, and simple data collection.
- 80% Cost Savings: Only 2 credits per page vs 10 credits for AI mode
- No AI/LLM Processing: Pure HTML to markdown conversion
- Clean Output: Well-formatted markdown with metadata extraction
- Fast Processing: No AI inference delays
- Perfect for: Documentation, content archival, site migration
from scrapegraph_py import Client
client = Client(api_key="your-api-key")
# Markdown conversion mode - no prompt needed
response = client.crawl(
url="https://scrapegraphai.com/",
extraction_mode=False, # False = Markdown conversion (NO AI/LLM)
depth=2,
breadth=None,
max_pages=5,
rules={
"include_paths": ["/docs/*", "/blog/**"],
"exclude_paths": ["/admin/*"],
"same_domain": True
}
)import { crawl } from 'scrapegraph-js';
const apiKey = 'your-api-key';
const url = 'https://scrapegraphai.com';
try {
// Markdown conversion mode - no prompt needed
const response = await crawl(apiKey, url, null, null, {
extractionMode: false, // false = Markdown conversion (NO AI/LLM)
depth: 2,
breadth: null,
maxPages: 5,
rules: {
include_paths: ['/docs/*', '/blog/**'],
exclude_paths: ['/admin/*'],
same_domain: true
}
});
console.log(response);
} catch (error) {
console.error(error);
}curl -X 'POST' \
'https://api.scrapegraphai.com/v1/crawl' \
-H 'accept: application/json' \
-H 'SGAI-APIKEY: your-api-key' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://scrapegraphai.com/",
"extraction_mode": false,
"depth": 2,
"breadth": null,
"max_pages": 5,
"rules": {
"include_paths": ["/docs/*", "/blog/**"],
"exclude_paths": ["/admin/*"],
"same_domain": true
}
}'You can control the crawl behavior with the rules object:
rules = {
"exclude": ["https://example.com/logout", "https://example.com/admin/*"], # Regex patterns for full URLs to exclude
"include_paths": ["/products/*", "/blog/**"], # Path patterns to include
"exclude_paths": ["/admin/*", "/api/**", "/private/*"], # Path patterns to exclude (takes precedence)
"same_domain": True # Only crawl links on the same domain
}| Field | Type | Default | Description |
|---|---|---|---|
| exclude | list | [] | List of URL patterns (regex) to exclude from crawling. Matches full URL. |
| include_paths | list | [] | (Optional) List of path patterns to include (e.g., ["/products/*", "/blog/**"]). Supports wildcards: * matches any characters, ** matches any path segments. If empty or not specified, all paths are included. |
| exclude_paths | list | [] | (Optional) List of path patterns to exclude (e.g., ["/admin/*", "/api/**"]). Supports wildcards: * matches any characters, ** matches any path segments. Takes precedence over include_paths. If empty or not specified, no paths are excluded. |
| same_domain | bool | True | Restrict crawl to the same domain |
llm_result: Structured extraction based on your prompt/schemacrawled_urls: List of all URLs visitedpages: List of objects withurland extractedmarkdowncontent
You can retrieve the result of a crawl job by its task ID:
result = client.get_crawl_result(task_id="your-task-id")import { getCrawlResult } from 'scrapegraph-js';
const apiKey = 'your_api_key';
const taskId = 'your-task-id';
const result = await getCrawlResult(apiKey, taskId);| Parameter | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Yes | The ScrapeGraph API Key. |
| taskId | string | Yes | The crawl job task ID. |
Define exactly what data you want to extract from every page:
from pydantic import BaseModel, Field
class CompanyData(BaseModel):
name: str = Field(description="Company name")
description: str = Field(description="Description")
features: list[str] = Field(description="Features")
response = client.crawl(
url="https://example.com",
prompt="Extract company info",
schema=CompanyData,
depth=1,
breadth=None,
max_pages=5,
rules={
"include_paths": ["/about", "/company/*"],
"exclude_paths": ["/admin/*", "/private/**"],
"same_domain": True
}
)import { smartCrawler } from 'scrapegraph-js';
import { z } from 'zod';
const CompanySchema = z.object({
name: z.string().describe('Company name'),
description: z.string().describe('Description'),
features: z.array(z.string()).describe('Features')
});
const rules = {
include_paths: ['/about', '/company/*'],
exclude_paths: ['/admin/*', '/private/**'],
same_domain: true
};
const response = await smartCrawler(apiKey, url, prompt, 1, null, 5, CompanySchema, rules);SmartCrawler supports async execution for large crawls:
import asyncio
from scrapegraph_py import AsyncClient
async def main():
async with AsyncClient(api_key="your-api-key") as client:
task = await client.crawl(
url="https://scrapegraphai.com/",
prompt="Extract info about the company",
depth=2,
breadth=None,
max_pages=10,
rules={
"include_paths": ["/about", "/services/*"],
"exclude_paths": ["/admin/*", "/api/**"],
"same_domain": True
}
)
# Poll for result
result = await client.get_crawl_result(task["task_id"])
print(result)
if __name__ == "__main__":
asyncio.run(main())import { AsyncSmartCrawler } from 'scrapegraph-js';
const scraper = new AsyncSmartCrawler(apiKey);
const task = await scraper.crawl({
url,
prompt,
depth: 2,
breadth: null,
maxPages: 10,
rules: {
include_paths: ['/about', '/services/*'],
exclude_paths: ['/admin/*', '/api/**'],
same_domain: true
}
});
const result = await scraper.getResult(task.taskId);SmartCrawler performs advanced validation:
- Ensures either
urlorwebsite_htmlis provided - Validates HTML size (max 2MB)
- Checks for valid URLs and HTML structure
- Handles empty or invalid prompts
- Returns clear error messages for all validation failures
POST https://api.scrapegraphai.com/v1/crawl| Header | Description |
|---|---|
| SGAI-APIKEY | Your API authentication key |
| Content-Type | application/json |
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes* | Starting URL (*or website_html required) |
| website_html | string | No | Raw HTML content (max 2MB) |
| prompt | string | Yes | Extraction instructions |
| schema | object | No | Output schema |
| headers | object | No | Custom headers |
| number_of_scrolls | int | No | Infinite scroll per page |
| depth | int | No | Crawl depth |
| breadth | int | No | Maximum number of links to crawl per depth level. If null/undefined, unlimited (default). Controls the 'width' of exploration at each depth. Useful for limiting crawl scope on large sites. Note: max_pages always takes priority. Ignored when sitemap=true. |
| max_pages | int | No | Max pages to crawl |
| rules | object | No | Crawl rules object with optional fields: exclude (regex URL patterns), include_paths (path patterns to include), exclude_paths (path patterns to exclude), same_domain (boolean) |
| sitemap | bool | No | Use sitemap.xml |
| wait_ms | int | No | Milliseconds to wait before scraping each page. Useful for pages with heavy JavaScript rendering (default: 3000). |
{
"status": "success",
"result": {
"status": "done",
"llm_result": { /* Structured extraction */ },
"crawled_urls": ["..."],
"pages": [ { "url": "...", "markdown": "..." }, ... ]
}
}- Site-wide data extraction with smart understanding
- Product catalog crawling with structured output
- Legal/Privacy/Terms aggregation with AI parsing
- Research and competitive analysis with insights
- Multi-page blog/news scraping with content analysis
- Website documentation archival and migration
- Content backup and preservation (80% cheaper!)
- Blog/article collection in markdown format
- Site content analysis without AI overhead
- Fast bulk content conversion for CMS migration
- Be specific in your prompts for better results
- Use schemas for structured output validation
- Test prompts on single pages first
- Include examples in your schema descriptions
- Perfect for content archival and documentation
- No prompt required - set
extraction_mode: false - 80% cheaper than AI mode (2 credits vs 10 per page)
- Ideal for bulk content migration
- Set reasonable
max_pagesanddepthlimits - Use
ruleswithinclude_pathsandexclude_pathsto precisely control which pages to crawl - Use
excludefor full URL regex patterns when needed exclude_pathstakes precedence overinclude_paths- Always handle errors and poll for results
- Monitor your credit usage and rate limits
SmartCrawler supports webhook notifications for job completion. When you provide a webhook_url, you'll receive a POST request when the crawl finishes.
- Configure your webhook secret in the dashboard
- Provide a
webhook_urlin your crawl request - Verify incoming webhooks using the
X-Webhook-Signatureheader
response = client.crawl(
url="https://example.com",
prompt="Extract product data",
webhook_url="https://your-server.com/webhook"
)For detailed API documentation, see:
Comprehensive guides and tutorials Detailed API documentation Join our Discord community Check out our open-source projects Sign up now and get your API key to begin extracting data with SmartCrawler!