// Overview
LeoAPI provides REST API endpoints for web crawling via HTTP requests. All API endpoints require a valid API Key for authentication.
Base URL: https://leoapi.fun
// API URL Structure
LeoAPI uses a hierarchical URL structure to organize different crawling tools and their features:
/api/{tool}/{target_type}
Examples:
- /api/crawl4ai/infinite-scroll
- /api/crawl4ai/md-file
- /api/crawl4ai/links
- /api/crawl (legacy endpoint)
Recommended: Use tool-specific endpoints for better clarity and type safety.
// Crawl4AI: Infinite Scroll
Advanced web crawler for pages with infinite scroll functionality. Automatically scrolls and extracts content until no new content is found or max scrolls is reached.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
string | Yes | API Key |
url |
string | Yes | Target URL to crawl |
scroll_mode |
string | No | Scroll mode: "auto" (default) or "manual" |
max_scrolls |
integer | No | Maximum scroll count (default: 20, only used when scroll_mode is "manual") |
Request Examples
curl -X POST https://leoapi.fun/api/crawl4ai/infinite-scroll \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-your-api-key-here",
"url": "https://example.com",
"scroll_mode": "auto"
}'
// Crawl4AI: MD File
Crawl pages and generate structured markdown file. Supports depth crawling (0-3 levels).
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
string | Yes | API Key |
url |
string | Yes | Target URL to crawl |
crawling_depth |
integer | No | Crawling depth (0-3), default: 0 |
Request Example
curl -X POST https://leoapi.fun/api/crawl4ai/md-file \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-your-api-key-here",
"url": "https://example.com",
"crawling_depth": 1
}'
Success Response
{
"success": true,
"task_id": "crawl_20251201_120000_File",
"status": "completed",
"data": {
"filename": "crawl_20251201_120000_File.md",
"download_url": "https://leoapi.fun/download/crawl_20251201_120000_File.md",
"file_size": 15000,
"crawl_stats": {
"total_pages": 5,
"crawling_depth": 1,
"duration_seconds": 12.5
}
},
"message": "Crawl completed successfully",
"timestamp": "2025-12-01T12:00:12Z"
}
// Crawl4AI: Links
Extract all internal and external links from pages. Supports depth crawling.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
string | Yes | API Key |
url |
string | Yes | Target URL to crawl |
crawling_depth |
integer | No | Crawling depth (0-3), default: 0 |
Request Example
curl -X POST https://leoapi.fun/api/crawl4ai/links \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-your-api-key-here",
"url": "https://example.com",
"crawling_depth": 0
}'
// Crawl4AI: Standard Fetch
Status: Coming Soon
// DuckDuckGo Search
Multi-search engine aggregation with Google Custom Search API compatible output format. Search the web using multiple search engines powered by ddgs (Dux Distributed Global Search).
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
string | Yes | API Key |
search_query |
string | Yes | Search query (supports operators like site:, intitle:, etc.) |
language |
string | No | Language code (default: "en") |
search_engine |
string | No | Search engine backend (default: "auto"). See available engines below. |
max_results |
integer | No | Maximum results to return (0-1000, default: 10). Use 0 for unlimited mode (continues until no new results). Actual results may vary due to ad filtering and deduplication. |
keywords |
string | No | Additional keywords (comma-separated, optional) |
Available Search Engines
| Value | Name | Description |
|---|---|---|
auto |
Auto (All Engines) | Aggregate results from all available engines (Recommended) |
brave |
Brave Search | Privacy-focused search engine by Brave |
duckduckgo |
DuckDuckGo | Privacy-focused search engine |
mojeek |
Mojeek | Independent search engine |
wikipedia |
Wikipedia | Free encyclopedia |
yahoo |
Yahoo | Yahoo Search |
yandex |
Yandex | Russian search engine |
bing |
Bing | Microsoft Bing (News search) |
annasarchive |
Anna's Archive | Books and academic papers |
Supported Languages
en (English), zh-CN (Chinese Simplified), zh-TW (Chinese Traditional), ja (Japanese), ko (Korean), fr (French), de (German), es (Spanish), it (Italian), pt (Portuguese), ru (Russian)
Request Example
curl -X POST https://leoapi.fun/api/duckduckgo/search \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-your-api-key-here",
"search_query": "site:linkedin.com/in senior software engineer Python San Francisco",
"language": "en",
"search_engine": "auto",
"max_results": 20
}'
Search Tips:
- Use
site:operator to limit search to specific domain (e.g.,site:linkedin.com/in) - Use
intitle:to search in page titles - Use quotes for exact phrase matching (e.g.,
"Senior Engineer") - Combine multiple keywords for better results
Success Response
{
"success": true,
"data": {
"kind": "customsearch#search",
"queries": {
"request": [{
"title": "LeoAPI Search - ...",
"totalResults": "10",
"searchTerms": "...",
"count": 10,
"startIndex": 1
}]
},
"searchInformation": {
"searchTime": 0.523,
"formattedSearchTime": "0.52",
"totalResults": "10",
"formattedTotalResults": "10"
},
"items": [
{
"kind": "customsearch#result",
"title": "Example Title",
"htmlTitle": "Example Title",
"link": "https://example.com",
"displayLink": "example.com",
"snippet": "Example description...",
"htmlSnippet": "Example description...",
"formattedUrl": "https://example.com/page",
"htmlFormattedUrl": "https://example.com/page",
"pagemap": {
"metatags": [{
"og:title": "Example Title",
"og:description": "Example description",
"og:url": "https://example.com"
}]
}
}
]
},
"message": "Search completed successfully",
"timestamp": "2026-01-04T12:00:00Z"
}
Error Response
{
"success": false,
"error": "API_KEY_ERROR",
"message": "Invalid API Key",
"timestamp": "2026-01-04T12:00:00Z"
}
Note: Output format is compatible with Google Custom Search API for easy integration with existing tools and workflows.
Important: For unlimited mode (max_results=0) or large result sets, use the async endpoint to avoid timeout issues.
// DuckDuckGo Search (Async)
Asynchronous search endpoint for long-running searches. Creates a background task and returns immediately with a task ID. Use this endpoint for unlimited mode (max_results=0) or when expecting long execution times to avoid timeout issues in N8N or other automation tools.
Recommended for: Unlimited searches, large result sets (>100), or when using automation tools like N8N that may have timeout limits.
Concurrency Limit: The system limits concurrent async search tasks to 5 by default (configurable via max_concurrent_searches in config.json). When the limit is reached, new requests will return a 429 Too Many Requests error. Please retry after the suggested time.
Request Parameters
Same as synchronous endpoint. See DuckDuckGo Search above for parameter details.
Request Example
curl -X POST https://leoapi.fun/api/duckduckgo/search/async \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-your-api-key-here",
"search_query": "site:linkedin.com/in senior software engineer",
"language": "en",
"search_engine": "yahoo",
"max_results": 0
}'
Success Response (Task Created)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"status_url": "/api/duckduckgo/search/status/550e8400-e29b-41d4-a716-446655440000",
"message": "Search task created successfully",
"timestamp": "2026-01-06T12:00:00Z"
}
Error Response (Concurrency Limit Reached)
{
"success": false,
"error": "TOO_MANY_REQUESTS",
"message": "Maximum concurrent search limit reached (5). Please try again later.",
"current_active_tasks": 5,
"max_concurrent_searches": 5,
"available_slots": 0,
"retry_after": 30,
"timestamp": "2026-01-07T12:00:00Z"
}
Concurrency Limit: When the maximum number of concurrent search tasks (default: 5) is reached, the API returns a 429 Too Many Requests error. The response includes:
current_active_tasks- Current number of active search tasksmax_concurrent_searches- Maximum allowed concurrent searchesavailable_slots- Number of available execution slotsretry_after- Suggested retry time in seconds
You can adjust the limit by modifying max_concurrent_searches in config.json.
Check Task Status
Status Response (Processing)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"current_count": 15,
"target_count": 50,
"message": "Crawling... 15/50 results",
"start_time": "2026-01-06T12:00:00Z",
"timestamp": "2026-01-06T12:00:15Z"
}
Note: current_count shows the number of results found so far. For unlimited mode (max_results=0), target_count is not included.
Status Response (Unlimited Mode - Processing)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"current_count": 127,
"message": "Crawling... Found 127 results so far",
"start_time": "2026-01-06T12:00:00Z",
"timestamp": "2026-01-06T12:00:15Z"
}
Status Response (Completed)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"current_count": 50,
"target_count": 50,
"message": "Search completed: 50/50 results",
"start_time": "2026-01-06T12:00:00Z",
"completed_at": "2026-01-06T12:02:30Z",
"duration_seconds": 150.5,
"results": {
"kind": "customsearch#search",
"queries": { ... },
"searchInformation": { ... },
"items": [ ... ]
},
"timestamp": "2026-01-06T12:02:30Z"
}
Status Response (Unlimited Mode - Completed)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"current_count": 342,
"message": "Unlimited crawl completed: Found 342 results",
"start_time": "2026-01-06T12:00:00Z",
"completed_at": "2026-01-06T12:05:20Z",
"duration_seconds": 320.5,
"results": {
"kind": "customsearch#search",
"queries": { ... },
"searchInformation": { ... },
"items": [ ... ]
},
"timestamp": "2026-01-06T12:05:20Z"
}
Status Response (Failed)
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"current_count": 0,
"message": "Search failed: ...",
"error": "Error message here",
"start_time": "2026-01-06T12:00:00Z",
"completed_at": "2026-01-06T12:00:05Z",
"timestamp": "2026-01-06T12:00:05Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
current_count |
integer | Number of results found so far (updated in real-time during crawling) |
target_count |
integer | Target number of results (only present when max_results > 0) |
status |
string | Task status: "pending", "processing", "completed", or "failed" |
message |
string | Current status message (updates during processing) |
N8N Integration Example
// Step 1: Create async search task
HTTP Request Node:
Method: POST
URL: https://leoapi.fun/api/duckduckgo/search/async
Body: {
"api_key": "={{$credentials.leoapi.api_key}}",
"search_query": "={{$json.query}}",
"max_results": 0
}
// Step 2: Wait and poll for status
Wait Node: 10 seconds
// Step 3: Check status
HTTP Request Node:
Method: GET
URL: https://leoapi.fun/api/duckduckgo/search/status/={{$json.task_id}}
// Step 4: If status is "processing", loop back to Wait Node
// Step 5: If status is "completed", use $json.results
// Step 6: If status is "failed", handle error
Task Status Values:
pending- Task created, waiting to startprocessing- Search in progresscompleted- Search finished successfullyfailed- Search failed with errorcancelled- Task was cancelled by user
Polling Recommendation: Poll every 5-10 seconds. For unlimited searches, expect longer processing times.
Error Codes:
TOO_MANY_REQUESTS(429) - Maximum concurrent search limit reachedSERVICE_UNAVAILABLE(503) - Search service not initializedTASK_NOT_FOUND(404) - Task ID does not existCANNOT_CANCEL(400) - Cannot cancel task (already completed or failed)
Cancel Search Task
Cancel an active (pending or processing) search task. Partial results will be saved if available.
Cancel Request Example
curl -X POST https://leoapi.fun/api/duckduckgo/search/cancel/550e8400-e29b-41d4-a716-446655440000
Cancel Success Response
{
"success": true,
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelled",
"message": "Task cancellation requested successfully",
"cancelled_at": "2026-01-07T12:00:00Z",
"timestamp": "2026-01-07T12:00:00Z"
}
Cancel Error Response
{
"success": false,
"error": "CANNOT_CANCEL",
"message": "Cannot cancel task with status 'completed'. Only pending or processing tasks can be cancelled.",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"current_status": "completed",
"timestamp": "2026-01-07T12:00:00Z"
}
Query Active Tasks
Get a list of all active (pending or processing) search tasks with their current status and progress.
Query Active Tasks Request Example
curl -X GET https://leoapi.fun/api/duckduckgo/search/tasks/active
Query Active Tasks Response
{
"success": true,
"total_active_tasks": 3,
"statistics": {
"pending": 1,
"processing": 2,
"total": 3
},
"tasks": [
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"start_time": "2026-01-07T12:00:00Z",
"current_count": 15,
"target_count": 50,
"message": "Crawling... 15/50 results",
"search_query": "site:linkedin.com/in senior software engineer",
"search_engine": "yahoo",
"max_results": 50
}
],
"timestamp": "2026-01-07T12:00:15Z"
}
// n8n Workflow Integration
LeoAPI response format is optimized for n8n workflow automation.
Configuration Example
{
"method": "POST",
"url": "https://leoapi.fun/api/crawl4ai/infinite-scroll",
"body": {
"api_key": "={{$credentials.leoapi.api_key}}",
"url": "={{$json.target_url}}",
"scroll_mode": "auto"
}
}
// Legacy Crawl Endpoint
Generic crawling endpoint (maintained for backward compatibility).
// Helper Endpoints
Validate API Key
Get Available Tools
Download File
// Rate Limits & Notes
- Crawl tasks are executed synchronously - requests will wait until crawl completes
- Crawl time depends on target website and scroll count, typically 30-120 seconds
- Recommended to set reasonable HTTP request timeout (at least 300 seconds)
- Generated files are automatically deleted after 3 days retention period
// Contact & Support
For questions or suggestions, please contact us:
- GitHub Issues
- Email: yaoge.shi@gmail.com