INTEGRATION GUIDE
Add web reading to your AI agent in 5 minutes
One API call. Any public URL. Your agent gets structured intelligence โ entities, summary, confidence score โ ready to reason over.
Quick Start
Get your first result in under 2 minutes.
1
Get your free API key
Go to project-ghost-lilac.vercel.app โ enter your email โ get an instant
ghost_sk_... key. No credit card. Free plan includes 100 requests/month.2
Make your first API call
POST any public URL to
/distill with your key in the Authorization header.3
Use the structured response
Get back title, summary, entities, confidence score, and tokens saved โ all ready for your agent to reason over.
cURL
Python
JavaScript
Terminal
curl -X POST https://project-ghost-production.up.railway.app/distill \ -H "Authorization: Bearer ghost_sk_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://apple.com"}'
import requests response = requests.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": "Bearer ghost_sk_YOUR_KEY"}, json={"url": "https://apple.com"} ) data = response.json() print(data["title"]) print(data["signals_data"]["decision_signal"]["business_intent"]) print(data["tokens_saved"])
const response = await fetch( "https://project-ghost-production.up.railway.app/distill", { method: "POST", headers: { "Authorization": "Bearer ghost_sk_YOUR_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://apple.com" }) } ); const data = await response.json(); console.log(data.signals_data.decision_signal.business_intent);
Response Format
Every successful call returns this structure.
{
"url": "https://apple.com",
"title": "Apple",
"tokens_saved": "80.7%",
"signals_data": {
"decision_signal": {
"business_intent": "Apple promotes its latest hardware...",
"priority_score": 8,
"category": "Technology"
},
"items": [
{ "title": "MacBook Pro", "entities": ["Apple", "M5"], "impact_score": 9 }
],
"integrity_layer": {
"confidence_score": 0.87,
"is_high_integrity": true
}
},
"_usage": { "plan": "free", "used": 1, "limit": 100, "remaining": 99 }
}
"url": "https://apple.com",
"title": "Apple",
"tokens_saved": "80.7%",
"signals_data": {
"decision_signal": {
"business_intent": "Apple promotes its latest hardware...",
"priority_score": 8,
"category": "Technology"
},
"items": [
{ "title": "MacBook Pro", "entities": ["Apple", "M5"], "impact_score": 9 }
],
"integrity_layer": {
"confidence_score": 0.87,
"is_high_integrity": true
}
},
"_usage": { "plan": "free", "used": 1, "limit": 100, "remaining": 99 }
}
LangChain Integration
Add Ghost as a custom tool your LangChain agent can call.
Python
Python ยท LangChain
from langchain.tools import tool import requests GHOST_KEY = "Bearer ghost_sk_YOUR_KEY" @tool def read_webpage(url: str) -> dict: """Read any public URL and extract structured intelligence. Returns title, summary, entities, and confidence score. Use this when you need to understand what a webpage is about.""" response = requests.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": GHOST_KEY}, json={"url": url} ) data = response.json() sd = data.get("signals_data", {}) return { "title": data.get("title"), "summary": sd.get("decision_signal", {}).get("business_intent"), "entities": [e for item in sd.get("items", []) for e in item.get("entities", [])], "confidence": sd.get("integrity_layer", {}).get("confidence_score"), "tokens_saved": data.get("tokens_saved") } # Add to your agent tools = [read_webpage] agent = initialize_agent(tools, llm, agent="zero-shot-react-description") agent.run("Research what OpenAI is currently working on")
OpenAI Agents SDK
Use Ghost as a function tool with the OpenAI Agents SDK.
Python ยท OpenAI Agents
from agents import Agent, function_tool import requests GHOST_KEY = "Bearer ghost_sk_YOUR_KEY" @function_tool def read_webpage(url: str) -> str: """Read any public URL and get structured intelligence about it.""" res = requests.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": GHOST_KEY}, json={"url": url} ).json() sd = res.get("signals_data", {}) intent = sd.get("decision_signal", {}).get("business_intent", "No summary") entities = [e for i in sd.get("items",[]) for e in i.get("entities",[])] return f"""Title: {res.get('title')} Summary: {intent} Entities: {', '.join(entities[:8])} Confidence: {sd.get('integrity_layer',{}).get('confidence_score')}""" agent = Agent( name="Research Agent", instructions="You research topics by reading web pages using the read_webpage tool.", tools=[read_webpage] ) from agents import Runner result = await Runner.run(agent, "What is Stripe building right now?") print(result.final_output)
Cursor / Claude Desktop (MCP)
Add Ghost directly as an MCP tool โ no code needed.
What this does: Your Cursor or Claude Desktop agent gets a
distill_web tool it can call on any URL automatically during a conversation.
JSON ยท MCP Config
{
"mcpServers": {
"project-ghost": {
"url": "https://project-ghost-production.up.railway.app/mcp",
"transport": "http"
}
}
}
Where to add this: Cursor โ Settings โ MCP Servers โ paste config. Claude Desktop โ claude_desktop_config.json โ add mcpServers block.
CrewAI Integration
Add Ghost as a tool for any CrewAI agent.
Python ยท CrewAI
from crewai_tools import BaseTool import requests class GhostWebReader(BaseTool): name: str = "Web Intelligence Reader" description: str = "Read any public URL and extract structured intelligence including entities, summary and confidence score" def _run(self, url: str) -> str: res = requests.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": "Bearer ghost_sk_YOUR_KEY"}, json={"url": url} ).json() sd = res.get("signals_data", {}) return str({ "title": res.get("title"), "summary": sd.get("decision_signal",{}).get("business_intent"), "entities": [e for i in sd.get("items",[]) for e in i.get("entities",[])], }) # Use in your crew researcher = Agent( role="Web Researcher", goal="Research topics by reading websites", tools=[GhostWebReader()] )
Raw Python / JavaScript
No framework? Use Ghost directly in any script.
Python
JavaScript
Python Async
Python
import requests def ghost_read(url: str, api_key: str) -> dict: """Read any URL and get structured intelligence.""" res = requests.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": f"Bearer {api_key}"}, json={"url": url}, timeout=30 ) res.raise_for_status() return res.json() # Usage result = ghost_read("https://openai.com", "ghost_sk_YOUR_KEY") sd = result["signals_data"] print(f"Title: {result['title']}") print(f"Summary: {sd['decision_signal']['business_intent']}") print(f"Entities: {[e for i in sd['items'] for e in i['entities']]}") print(f"Tokens saved: {result['tokens_saved']}")
async function ghostRead(url, apiKey) { const res = await fetch( "https://project-ghost-production.up.railway.app/distill", { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" }, body: JSON.stringify({ url }) } ); return res.json(); } // Usage const data = await ghostRead("https://openai.com", "ghost_sk_YOUR_KEY"); const { decision_signal, items, integrity_layer } = data.signals_data; console.log(decision_signal.business_intent); console.log(items.flatMap(i => i.entities)); console.log(`Confidence: ${integrity_layer.confidence_score}`);
import asyncio import httpx async def ghost_read(url: str, api_key: str) -> dict: async with httpx.AsyncClient(timeout=30) as client: res = await client.post( "https://project-ghost-production.up.railway.app/distill", headers={"Authorization": f"Bearer {api_key}"}, json={"url": url} ) return res.json() # Read multiple URLs concurrently async def research_multiple(urls: list, api_key: str): tasks = [ghost_read(url, api_key) for url in urls] return await asyncio.gather(*tasks) results = asyncio.run(research_multiple( ["https://openai.com", "https://anthropic.com"], "ghost_sk_YOUR_KEY" ))
Plans & Limits
Every response includes your current usage in the
_usage field.
Plan Free Developer Startup
Requests 100/mo 2,000/mo 10,000/mo
Price Free โน499 (~$6) โน1,999 (~$24)
Key Instant On request On request
Requests 100/mo 2,000/mo 10,000/mo
Price Free โน499 (~$6) โน1,999 (~$24)
Key Instant On request On request
Error Handling
Handle these common responses in your agent.
# 401 โ Missing or invalid API key
{ "error": "API key required" }
# 429 โ Rate limit exceeded
{ "error": "Rate limit exceeded", "remaining": 0 }
# 200 but site was blocked
{ "title": "Blocked", "signals_data": { "error": "Scraper blocked" } }
{ "error": "API key required" }
# 429 โ Rate limit exceeded
{ "error": "Rate limit exceeded", "remaining": 0 }
# 200 but site was blocked
{ "title": "Blocked", "signals_data": { "error": "Scraper blocked" } }
Tip: Always check
data.title !== "Blocked" and data.signals_data.error before using the response. Sites with enterprise Cloudflare protection may be blocked.
Ready to integrate?
Get your free API key instantly โ 100 requests/month, no credit card.
โก Get Free API Key โ