Open-Source Web Intelligence & Data Extraction Engine (Firecrawl & Perplexity Alternative)
A self-hostable Web Intelligence & Data Extraction Engine designed for LLMs, RAG pipelines, and agentic workflows. It provides a clean, unified API for scraping, crawling, structured data extraction, web search, screenshots, PDFs, and deep research synthesis.
π¬π§ English β’ πͺπΈ EspaΓ±ol β’ π¨π³ δΈζ β’ π―π΅ ζ₯ζ¬θͺ
- About Oley
- Key Features
- Quick Start
- Docker Deployment
- Environment Variables
- Unified API Endpoint: POST /api/fire
- Usage Examples
- Specialty & Streaming Routes
- SDK Clients
- Directory Structure
- License
Oley is a production-ready, open-source alternative to Firecrawl and Perplexity. It acts as a bridge between the raw web and Large Language Models (LLMs). It solves common challenges in web data harvesting, including client-side JS rendering, rate limiting, anti-bot protections, and parsing unstructured HTML into LLM-ready formats (like clean GFM Markdown or structured JSON).
- All-in-One Engine: No need for separate microservices for crawling, scraping, searching, or generating screenshots.
- Agent-Friendly: Automatically cleans up noise (ads, tracking scripts, navigation elements) to reduce LLM context token usage.
- Deep Research Capability: Built-in multi-agent planner that acts like Perplexity's deep search, returning structured facts with precise source citations.
-
Unified
/api/fireEndpoint: One simple interface to rule all actionsβauto-detects targets from your payload. - LLM Schema Extraction (Firecrawl Parity): Extract structured JSON data using custom schemas (e.g. products, reviews, pricing) with natural language prompt guidance.
- Deep Research Engine (Perplexity Parity): Expands queries, executes parallel web searches, scrapes relevant sources, and synthesizes citation-backed answers.
- Anti-Bot Stealth: Rotates user-agents, spoofs canvas/timezone fingerprints, connection parameters, and WebGL context using a randomized pool of real GPUs.
- Advanced Scraper Options: Injects custom cookies/headers, clicks/fills inputs, evaluates custom JS snippets, and waits for selectors before extraction.
- GFM Markdown Engine: Produces clean GitHub-Flavored Markdown tables, nested lists, and checkboxes from dynamic HTML pages.
-
$O(1)$ LRU Cache: Memory-efficient response cache with TTL configuration and route-specific cache invalidation support. - Live SSE Streaming: Stream tokens or research milestones in real-time.
- Zero Dependencies SDKs: Pre-packaged clients for TypeScript and Python.
- Clone the repository and navigate into it:
git clone https://github.com/Asno-dev/asno-ai.git oley && cd oley
- Copy and customize the environment configurations:
cp .env.example .env
- Install dependencies and launch the developer environment:
Your unified server is now running at
npm install npm run dev
http://localhost:3000.
To spin up the service in a containerized environment (which automatically sets up Chrome/Playwright dependencies):
docker compose up --buildCustomize your server behaviors by defining these keys inside your .env file:
PORT=3000 # Web server port
OLEY_API_KEY=your-api-key # Optional: Enforces Bearer token auth
RATE_LIMIT_PER_MIN=60 # Max requests per minute per IP
PUBLIC_URL=http://localhost:3000
# LLM Providers (Required for AI actions, schema extraction & deep research)
OPENAI_API_KEY=your_key
ANTHROPIC_API_KEY=your_key
GOOGLE_API_KEY=your_key
GROQ_API_KEY=your_key
MISTRAL_API_KEY=your_key
# Local LLM Support (Ollama)
OLLAMA_BASE_URL=http://localhost:11434/v1
OLLAMA_MODEL=llama3.1Submit requests to /api/fire to automatically route and run any intelligence job.
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
string |
- | Target URL for scraping, screenshot, crawl, or extraction. |
query |
string |
- | Query term for web search or deep research. |
action |
string |
- | Explicit task: scrape, crawl, extract, llmExtract, search, screenshot, pdf, render, research, translate, etc. (Auto-detected if left empty). |
formats |
array |
["markdown"] |
Desired outputs: markdown, html, text, metadata, links, images, screenshot, pdf. |
renderJs |
boolean |
false |
Enable Playwright JS rendering context. |
stealth |
boolean |
false |
Apply Canvas, GPU, and timezone anti-fingerprint blocks. |
blockResources |
boolean |
false |
Block css/fonts/images from loading for speed. |
waitForSelector |
string |
- | Wait for CSS selector to appear in DOM before scraping. |
actions |
array |
- | Interactivity script: [{"type": "click", "selector": "#btn"}]. |
cookies |
array |
- | Inject context cookies: [{"name": "a", "value": "b", "domain": "..."}]. |
extractSchema |
object |
- | Shorthand JSON schema for structured extraction. |
prompt |
string |
- | Instructs the extraction parser in plain English. |
cache |
boolean |
true |
Enable |
ttl |
number |
300000 |
Custom cache duration in milliseconds. |
curl -X POST http://localhost:3000/api/fire \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/Asno-dev/asno-ai", "formats": ["markdown"]}'curl -X POST http://localhost:3000/api/fire \
-H "Content-Type: application/json" \
-d '{
"url": "https://github.com/Asno-dev/asno-ai",
"action": "llmExtract",
"extractSchema": {
"repositoryName": "string",
"starCount": "number",
"author": "string"
}
}'curl -X POST http://localhost:3000/api/fire \
-H "Content-Type: application/json" \
-d '{
"query": "superconductor news updates",
"action": "research",
"depth": "deep"
}'Invoke-RestMethod -Uri "http://localhost:3000/api/fire" `
-Method Post `
-ContentType "application/json" `
-Body '{"url": "https://github.com/Asno-dev/asno-ai", "formats": ["markdown"], "stealth": true}'Allows your clients to trace deep research progress iteratively.
curl -N -X POST http://localhost:3000/api/ai/research/stream \
-H "Content-Type: application/json" \
-d '{"query": "solid state battery breakthroughs"}'Emits live Event Source records (event: start, event: sources_found, event: answer, event: done).
Direct LLM completion streaming.
curl -N -X POST http://localhost:3000/api/ai/chat/stream \
-H "Content-Type: application/json" \
-d '{"prompt": "Write a Python script for binary search."}'Keep scrapers synchronized and discard stale cache entries instantly:
- Check Stats:
GET /api/cache/stats - Invalidate URL:
POST /api/cache/invalidate(payload:{"url": "https://url-to-invalidate.com"}) - Flush Cache:
POST /api/cache/clear
Oley includes clean client SDK wrappers for TS and Python under the sdks/ directory.
import { Oley } from 'oley';
const oley = new Oley({ baseUrl: 'http://localhost:3000' });
const result = await oley.fire({
url: 'https://example.com',
formats: ['markdown'],
stealth: true
});from oley import Oley
oley = Oley(base_url="http://localhost:3000")
res = oley.fire(
url="https://example.com",
formats=["markdown"],
stealth=True
)api/src/
index.ts # System Entry point & browser pool
routes.ts # REST router & SSE stream controllers
openapi.ts # OpenAPI 3.1.0 generator schema
core/
fire.ts # Unified request engine
scraper.ts # Playwright & Turndown GFM compiler
cache.ts # O(1) LRU caching layer
stealth.ts # Browser anti-fingerprint spoofing
research.ts # Multi-query deep research builder
synthesis.ts # BM25 ranker & Citation synthesize formatter
stream.ts # Server-Sent Events formatter
extract/
llm_extract.ts # LLM JSON-schema mapper
ai.ts # Summarization, translations, entities pipelines
