// 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

POST /api/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

POST /api/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: Standard Fetch

POST /api/crawl4ai/standard-fetch

Status: Coming Soon

// DuckDuckGo Search (Async)

POST /api/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 tasks
  • max_concurrent_searches - Maximum allowed concurrent searches
  • available_slots - Number of available execution slots
  • retry_after - Suggested retry time in seconds

You can adjust the limit by modifying max_concurrent_searches in config.json.

Check Task Status

GET /api/duckduckgo/search/status/{task_id}

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 start
  • processing - Search in progress
  • completed - Search finished successfully
  • failed - Search failed with error
  • cancelled - 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 reached
  • SERVICE_UNAVAILABLE (503) - Search service not initialized
  • TASK_NOT_FOUND (404) - Task ID does not exist
  • CANNOT_CANCEL (400) - Cannot cancel task (already completed or failed)

Cancel Search Task

POST /api/duckduckgo/search/cancel/{task_id}

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 /api/duckduckgo/search/tasks/active

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

POST /api/crawl

Generic crawling endpoint (maintained for backward compatibility).

// Helper Endpoints

Validate API Key

POST /api/validate-key

Get Available Tools

GET /api/tools

Download File

GET /download/{filename}

// 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