Sofya
About
One API giving AI agents web search, page fetch as markdown, AI extraction, and deep research tools.
Details
- Author
- Unknown
- Categories
- Search, Other, AI
Jump to
Everything you need to integrate Sofya into your AI agent.
Eligible GitHub accounts get 1,000 credits/month on the free tier. Need more?Buy creditsat $0.005 each.
curl -X POST https://sofya.co/v1/search \ -H "Authorization: Bearer ay_live_..." \ -H "Content-Type: application/json" \ -d '{"query": "latest AI news"}'
All API requests require an API key in theAuthorizationheader.
Authorization: Bearer ay_live_your_key_here
Connect Sofya directly to Claude Code, Cursor, or any MCP-compatible client. Your AI agent getssearch,fetch,extract, andresearchtools, no REST calls needed.
Go to yourdashboardand click the copy button for your client. The command is pre-filled with your API key.
claude mcp add --transport http sofya https://mcp.sofya.co/mcp \ --header "Authorization: Bearer ay_live_..."
{ "mcpServers": { "sofya": { "url": "https://mcp.sofya.co/mcp", "headers": { "Authorization": "Bearer ay_live_..." } } } }
[mcp_servers.sofya] url = "https://mcp.sofya.co/mcp" http_headers = { "Authorization" = "Bearer ay_live_..." }
Windsurf · ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "sofya": { "serverUrl": "https://mcp.sofya.co/mcp", "headers": { "Authorization": "Bearer ay_live_..." } } } }
{ "servers": { "sofya": { "type": "http", "url": "https://mcp.sofya.co/mcp", "headers": { "Authorization": "Bearer ay_live_..." } } } }
Your API key is sent via HTTP header. The AI model never sees it.
Web search with page content extraction and optional AI answers. 1-3 credits (+5 with AI answer).
Fetch URLs as clean markdown. 1 credit per URL.
AI-powered structured data extraction. 5 credits.
Multi-query deep research with AI synthesis. 25 credits.
Copy-paste these tool schemas into your Anthropic or OpenAI API calls. Your model gets Sofya's tools without writing any definitions yourself.
Pass this array as thetoolsparameter in your/v1/messagesrequest. When Claude returns atool_useblock, call the matching Sofya REST endpoint and return the result as atool_result.
[ { "name": "sofya_search", "description": "Search the web for current information. Returns extracted page content, not just snippets. Set topic='news' for current events. Set include_answer=true for an AI-synthesized answer (+5 credits). Returns: query, answer, results [{title, url, content, description, fetched, published_date}], search_depth, topic, elapsed_ms, credits_used, credits_remaining, altered_query.", "input_schema": { "type": "object", "required": ["query"], "properties": { "query": {"type": "string", "description": "The search query"}, "search_depth": {"type": "string", "description": "\"snippets\" (1 credit) or \"basic\" (3, default)"}, "max_results": {"type": "integer", "description": "Number of results, 1-20 (default 10)"}, "include_answer": {"type": "boolean", "description": "Add AI answer synthesized from results (+5 credits)"}, "topic": {"type": "string", "description": "\"general\" (default) or \"news\""}, "freshness": {"type": "string", "description": "\"day\", \"week\", \"month\", \"year\", or \"YYYY-MM-DD:YYYY-MM-DD\""}, "include_domains": {"type": "array", "items": {"type": "string"}, "description": "Only these domains (max 10)"}, "exclude_domains": {"type": "array", "items": {"type": "string"}, "description": "Exclude these domains (max 10)"} } } }, { "name": "sofya_fetch", "description": "Fetch one or more URLs and return their content as clean markdown. Supports web pages, PDF, DOCX, and other document formats. 1 credit per URL, max 10 URLs. Failed URLs are not charged. Returns: results [{title, url, content, raw_html, published_time, success, error}], credits_used, credits_remaining.", "input_schema": { "type": "object", "required": ["urls"], "properties": { "urls": {"type": "array", "items": {"type": "string"}, "description": "URLs to fetch (max 10)"}, "include_raw_html": {"type": "boolean", "description": "Include raw HTML source in response (default false)"} } } }, { "name": "sofya_extract", "description": "Fetch a URL and extract specific information using AI. Use when you need structured data (pricing, specs, contact info) rather than raw content. 5 credits. If the page has no usable text it returns empty content with usage.low_content=true instead of a fabricated answer. Returns: content, url, credits_used, credits_remaining, usage (input_tokens, output_tokens, content_chars, low_content).", "input_schema": { "type": "object", "required": ["url", "prompt"], "properties": { "url": {"type": "string", "description": "The URL to extract from"}, "prompt": {"type": "string", "description": "What to extract, e.g. \"list all pricing tiers with features\""} } } }, { "name": "sofya_research", "description": "Deep research on a topic. Decomposes query into sub-queries, searches and reads multiple sources in parallel, synthesizes a structured report with citations. 25 credits. Returns: query, report, sources [{title, url, fetched}], sub_queries, credits_used, credits_remaining, usage.", "input_schema": { "type": "object", "required": ["query"], "properties": { "query": {"type": "string", "description": "The research question or topic"}, "topic": {"type": "string", "description": "\"general\" (default) or \"news\""}, "freshness": {"type": "string", "description": "\"day\", \"week\", \"month\", \"year\", or \"YYYY-MM-DD:YYYY-MM-DD\""}, "max_sources": {"type": "integer", "description": "Max sources to use, 5-30 (default 20)"} } } } ]
Pass this array as thetoolsparameter in your/chat/completionsrequest. When the model returnstool_calls, call the matching Sofya REST endpoint and return the result as arole: "tool"message.
[ { "type": "function", "function": { "name": "sofya_search", "description": "Search the web for current information. Returns extracted page content, not just snippets. Set topic='news' for current events. Set include_answer=true for an AI-synthesized answer (+5 credits). Returns: query, answer, results [{title, url, content, description, fetched, published_date}], search_depth, topic, elapsed_ms, credits_used, credits_remaining, altered_query.", "parameters": { "type": "object", "required": ["query"], "properties": { "query": {"type": "string", "description": "The search query"}, "search_depth": {"type": "string", "description": "\"snippets\" (1 credit) or \"basic\" (3, default)"}, "max_results": {"type": "integer", "description": "Number of results, 1-20 (default 10)"}, "include_answer": {"type": "boolean", "description": "Add AI answer synthesized from results (+5 credits)"}, "topic": {"type": "string", "description": "\"general\" (default) or \"news\""}, "freshness": {"type": "string", "description": "\"day\", \"week\", \"month\", \"year\", or \"YYYY-MM-DD:YYYY-MM-DD\""}, "include_domains": {"type": "array", "items": {"type": "string"}, "description": "Only these domains (max 10)"}, "exclude_domains": {"type": "array", "items": {"type": "string"}, "description": "Exclude these domains (max 10)"} }, "additionalProperties": false } } }, { "type": "function", "function": { "name": "sofya_fetch", "description": "Fetch one or more URLs and return their content as clean markdown. Supports web pages, PDF, DOCX, and other document formats. 1 credit per URL, max 10 URLs. Failed URLs are not charged. Returns: results [{title, url, content, raw_html, published_time, success, error}], credits_used, credits_remaining.", "parameters": { "type": "object", "required": ["urls"], "properties": { "urls": {"type": "array", "items": {"type": "string"}, "description": "URLs to fetch (max 10)"}, "include_raw_html": {"type": "boolean", "description": "Include raw HTML source in response (default false)"} }, "additionalProperties": false } } }, { "type": "function", "function": { "name": "sofya_extract", "description": "Fetch a URL and extract specific information using AI. Use when you need structured data (pricing, specs, contact info) rather than raw content. 5 credits. If the page has no usable text it returns empty content with usage.low_content=true instead of a fabricated answer. Returns: content, url, credits_used, credits_remaining, usage (input_tokens, output_tokens, content_chars, low_content).", "parameters": { "type": "object", "required": ["url", "prompt"], "properties": { "url": {"type": "string", "description": "The URL to extract from"}, "prompt": {"type": "string", "description": "What to extract, e.g. \"list all pricing tiers with features\""} }, "additionalProperties": false } } }, { "type": "function", "function": { "name": "sofya_research", "description": "Deep research on a topic. Decomposes query into sub-queries, searches and reads multiple sources in parallel, synthesizes a structured report with citations. 25 credits. Returns: query, report, sources [{title, url, fetched}], sub_queries, credits_used, credits_remaining, usage.", "parameters": { "type": "object", "required": ["query"], "properties": { "query": {"type": "string", "description": "The research question or topic"}, "topic": {"type": "string", "description": "\"general\" (default) or \"news\""}, "freshness": {"type": "string", "description": "\"day\", \"week\", \"month\", \"year\", or \"YYYY-MM-DD:YYYY-MM-DD\""}, "max_sources": {"type": "integer", "description": "Max sources to use, 5-30 (default 20)"} }, "additionalProperties": false } } } ]
When the model calls a tool, map the tool name to the Sofya endpoint and forward the arguments:
# Python - handle tool calls from Claude or GPT TOOL_TO_ENDPOINT = { "sofya_search": "/v1/search", "sofya_fetch": "/v1/fetch", "sofya_extract": "/v1/extract", "sofya_research": "/v1/research", } def call_sofya(tool_name: str, args: dict) -> dict: import httpx resp = httpx.post( f"https://sofya.co{TOOL_TO_ENDPOINT[tool_name]}", headers={"Authorization": "Bearer ay_live_..."}, json=args, timeout=120, ) return resp.json()
POST/v1/search1-3 credits (+5 with answer)
Search the web. Returns page content, not just snippets. Choose a search depth to control the quality/cost tradeoff. Addinclude_answerto any depth for an AI-synthesized answer (+5 credits). This is a lightweight alternative to the 25-credit research endpoint.
Fetches pages, returns extracted content (~5000 chars per result).
{ "query": "string", // required "search_depth": "basic", // "snippets" or "basic" "max_results": 10, // 1-20 "include_answer": false, // AI answer from results (+5 credits). Combine with any depth for search + synthesis (e.g. basic = 8 credits) "include_domains": [], // e.g. ["reddit.com", "github.com"] "exclude_domains": [], // e.g. ["pinterest.com"] "topic": "general", // "general" or "news" "freshness": null // "day", "week", "month", "year", or "YYYY-MM-DD:YYYY-MM-DD" }
{ "query": "latest AI news", "answer": "According to...", // null unless include_answer "results": [ { "title": "...", "url": "...", "content": "Extracted page content...", "description": "SERP snippet", "fetched": true, // true if page was fetched, false if snippet only "published_date": "2026-03-08", // YYYY-MM-DD, normalized from page metadata or SERP (or null) "sublinks": [], "table": {} } ], "search_depth": "basic", "topic": "general", "elapsed_ms": 4200, "credits_used": 3, "credits_remaining": 997, "altered_query": null // if the query was auto-corrected }
topic:"general"(default) for web search, or"news"for news-specific search. Use"news"for current events, breaking news, politics, or any time-sensitive query. Returns articles with publication dates.
freshness:"day","week","month","year", or custom range"YYYY-MM-DD:YYYY-MM-DD"
curl -X POST https://sofya.co/v1/search \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ay_live_..." \ -d '{"query": "latest AI news", "search_depth": "basic"}'
import httpx resp = httpx.post("https://sofya.co/v1/search", headers={"Authorization": "Bearer ay_live_..."}, json={"query": "latest AI news", "search_depth": "basic"}) print(resp.json())
const resp = await fetch("https://sofya.co/v1/search", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer ay_live_..." }, body: JSON.stringify({ query: "latest AI news", search_depth: "basic" }) }); console.log(await resp.json());
Fetch one or more URLs and return their content as clean markdown.
{ "urls": ["string", ...], // required, max 10 "include_raw_html": false // optional - include raw HTML source }
{ "results": [ { "title": "Example Page", "url": "https://example.com", "content": "# Markdown content...", "raw_html": null, "published_time": null, // YYYY-MM-DD, extracted from page metadata when available (or null) "success": true, "error": null } ], "credits_used": 1, "credits_remaining": 999 }
curl -X POST https://sofya.co/v1/fetch \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ay_live_..." \ -d '{"urls": ["https://example.com"]}'
import httpx resp = httpx.post("https://sofya.co/v1/fetch", headers={"Authorization": "Bearer ay_live_..."}, json={"urls": ["https://example.com"]}) print(resp.json())
const resp = await fetch("https://sofya.co/v1/fetch", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer ay_live_..." }, body: JSON.stringify({ urls: ["https://example.com"] }) }); console.log(await resp.json());
Fetch a webpage and extract specific information using AI. Costs 5 credits. If the page has no usable text (empty or JavaScript-rendered body), the model is not called andcontentis returned empty withusage.low_content: truerather than a fabricated answer.
{ "url": "string", // required "prompt": "string" // required, what to extract }
{ "content": "Extracted information...", "url": "https://example.com", "credits_used": 5, "credits_remaining": 995, "usage": { "input_tokens": 90, "output_tokens": 24, "content_chars": 4820, "low_content": false } }
usage.content_charsis the number of characters of page text the model received;usage.low_contentis true when the page had too little text to extract from (the model was skipped). Gate on these to detect empty/unrenderable pages.
curl -X POST https://sofya.co/v1/extract \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ay_live_..." \ -d '{"url": "https://example.com", "prompt": "Summarize this page"}'
import httpx resp = httpx.post("https://sofya.co/v1/extract", headers={"Authorization": "Bearer ay_live_..."}, json={"url": "https://example.com", "prompt": "Summarize this page"}) print(resp.json())
const resp = await fetch("https://sofya.co/v1/extract", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer ay_live_..." }, body: JSON.stringify({ url: "https://example.com", prompt: "Summarize this page" }) }); console.log(await resp.json());
Deep research on any topic. Decomposes your query into sub-queries, searches and reads multiple sources in parallel, then synthesizes a structured report with citations. Costs 25 credits.
{ "query": "string", // required "topic": "general", // "general" or "news" "freshness": null, // "day", "week", "month", "year", or "YYYY-MM-DD:YYYY-MM-DD" "max_sources": 20 // 5-30 }
{ "query": "How do modern LLMs handle long context?", "report": "## Key Findings\n\n- ...", "sources": [ { "title": "Scaling Transformer Context Windows", "url": "https://arxiv.org/abs/...", "fetched": true } ], "sub_queries": [ "transformer context window scaling techniques", "RoPE positional encoding extensions" ], "credits_used": 25, "credits_remaining": 975, "usage": { "input_tokens": 12400, "output_tokens": 1850 } }
curl -X POST https://sofya.co/v1/research \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ay_live_..." \ -d '{"query": "How do modern LLMs handle long context?"}'
import httpx resp = httpx.post("https://sofya.co/v1/research", headers={"Authorization": "Bearer ay_live_..."}, json={"query": "How do modern LLMs handle long context?"}, timeout=120) print(resp.json())
const resp = await fetch("https://sofya.co/v1/research", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer ay_live_..." }, body: JSON.stringify({ query: "How do modern LLMs handle long context?" }) }); console.log(await resp.json());
Get your account info including credits, tier, and total requests.
{ "credits": 997, "plan_credits": 997, "purchased_credits": 0, "is_free_tier": true, "credits_reset_at": "2026-04-04T12:00:00Z", "total_requests": 3, "api_key": "ay_live_...", "last_login_method": "github", "email": "user@example.com", "github_username": "octocat" }
Get your recent credit transactions (top-ups). Returns the last 50.
[ { "id": "uuid", "type": "credit", "amount": 5000, "endpoint": "top-up", "balance_after": 6000, "created_at": "2026-02-22T12:00:00Z" } ]
Get your daily usage breakdown, per endpoint.
days=7 // 1-90, default 7 offset_days=0 // pagination offset in days
[ { "date": "2026-02-22", "endpoint": "/v1/search", "request_count": 312, "total_credits": 312 } ]
Buy credits (PAYG). Minimum purchase: 2,000 credits ($10). Redirects to payment page.
{ "credits": 5000 // required, minimum ~2000 }
{ "checkout_url": "https://checkout.creem.io/pay/..." }
REST API endpoints are rate limited to10 requests per second per API key. This applies to all/v1/*endpoints. MCP (/mcp) is rate limited to30 requests per second.
If you exceed the limit, the API returns429 Too Many Requestswith aRetry-Afterheader indicating how many seconds to wait before retrying.
HTTP/1.1 429 Too Many Requests Retry-After: 0.85 { "detail": "Rate limit exceeded. 10 requests per second." }
Rate-limited requests do not consume credits. Implement exponential backoff or respect theRetry-Afterheader for best results.
Sofya's public status page lives off-host atstatus.sofya.co. It probes the API every 60 seconds from a separate server so it keeps reporting accurately even if Sofya itself is down. All feeds are public, no API key needed.
- /api/v2/summary.json— Atlassian Statuspage-compatible. Drop-in for any tool that already reads status.anthropic.com, GitHub status, etc.
- /api/v2/status.json— Page metadata + overall indicator only. Cheapest poll if you only need up/down.
- /api/status.json— Sofya-native richer feed: per-component latency, 24h / 90d uptime, last error.
$ curl https://status.sofya.co/api/v2/status.json { "page": { "id": "sofya", "name": "Sofya Status", ... }, "status": { "indicator": "none", "description": "All Systems Operational" } }
Theindicatorfield follows the Statuspage convention:none(operational),minor(degraded), ormajor(down). Treat any non-nonevalue as cause to surface a notice to your users or back off retries.
Search global news using natural language. Webz.io News Search API returns the most relevant articles and content, with filters for source, country, language, date, sentiment, and category.
Research a person's public footprint from a name, phone, email, or username. Sourced public-web profiles for AI agents. Not a background check.
Best people search engine that reduces the time spent on talent discovery.
An MCP server that connects to Perplexity's Sonar API, enabling real-time web-wide research in conversational AI.
Official Tavily MCP server for AI search and content extraction, giving MCP clients web search, crawl, and extract tools.
Google for AI agents — live search across 25,000+ scored MCP servers, updated daily
DuckDuckGo web search + URL fetcher for AI agents. No API key needed for free tier (7 req/IP/day), Pro tier unlimited with API key.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




