Overview
Tako Deep Search provides high-recall, reasoned data retrieval. Unlike Fast Search, Deep Search runs a full research pipeline — searching across multiple data sources, reasoning over results, and assembling comprehensive knowledge cards. It typically takes 30 seconds to several minutes.
Because Deep Search exceeds Django’s 60-second worker timeout, it always runs asynchronously. You get back a task_id and poll for results.
How async delegation works
You can trigger deep search from any knowledge search endpoint — the behavior is the same:
| Endpoint | What happens with search_effort: "deep" |
|---|
POST /v1/knowledge_search | Returns 202 with task_id (transparent delegation) |
POST /v1/knowledge_search/stream | Returns 202 with task_id (transparent delegation) |
POST /v1/knowledge_search/async | Returns 202 with task_id (explicit async endpoint) |
All three return the same 202 response and use the same polling endpoint. fast and medium efforts continue to return results synchronously (200) on the sync and stream endpoints.
search_effort: "auto" is resolved server-side before the async check. If auto resolves to deep, the request is delegated to async just like an explicit deep request.
Walkthrough
1. Submit a Deep Search request
You can use any of the three endpoints above. The explicit async endpoint is recommended for clarity:
curl -X POST https://tako.com/api/v1/knowledge_search/async \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": {
"text": "How has NVIDIA revenue grown compared to AMD over the last 5 years?",
"search_effort": "deep"
}
}'
Or use the standard sync endpoint — it returns 202 automatically for deep search:
curl -X POST https://tako.com/api/v1/knowledge_search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": {
"text": "How has NVIDIA revenue grown compared to AMD over the last 5 years?",
"search_effort": "deep"
}
}'
Response (202 Accepted):
{
"task_id": "abc-123-def-456",
"status": "pending",
"message": "Deep search requires async processing. Use /api/v1/knowledge_search/async/status/ to poll."
}
2. Poll for results
Use the task_id to check progress. Include since_index to get only new events since your last poll.
curl -X GET "https://tako.com/api/v1/knowledge_search/async/status?task_id=abc-123-def-456&since_index=0" \
-H "Authorization: Bearer YOUR_API_KEY"
Response (in progress):
{
"task_id": "abc-123-def-456",
"status": "in_progress",
"created_at": "2025-03-24T10:30:00Z",
"events": [
{"id": 0, "data": {"event_type": "progress", "message": "Searching data sources..."}},
{"id": 1, "data": {"event_type": "progress", "message": "Analyzing results..."}}
]
}
Response (completed):
{
"task_id": "abc-123-def-456",
"status": "completed",
"created_at": "2025-03-24T10:30:00Z",
"result": {
"knowledge_cards": [
{
"title": "NVIDIA vs AMD Revenue Growth",
"description": "NVIDIA revenue has grown 3.5x over the past 5 years...",
"embed_url": "https://tako.com/embed/xyz-789",
"image_url": "https://tako.com/api/v1/image/xyz-789/",
"webpage_url": "https://tako.com/card/xyz-789",
"sources": ["SEC Filings", "Yahoo Finance"]
}
]
}
}
3. Full example (Python)
import requests
import time
API_KEY = "YOUR_API_KEY"
BASE = "https://tako.com/api"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# Submit deep search (works with any endpoint)
resp = requests.post(
f"{BASE}/v1/knowledge_search",
headers=HEADERS,
json={
"inputs": {
"text": "How has NVIDIA revenue grown compared to AMD over the last 5 years?",
"search_effort": "deep",
}
},
)
# Handle both sync (200) and async (202) responses
if resp.status_code == 200:
# Fast/medium search returned synchronously
print("Got results:", resp.json())
elif resp.status_code == 202:
# Deep search delegated to async
task_id = resp.json()["task_id"]
print(f"Task submitted: {task_id}")
# Poll for results
since_index = 0
while True:
status_resp = requests.get(
f"{BASE}/v1/knowledge_search/async/status",
headers=HEADERS,
params={"task_id": task_id, "since_index": since_index},
)
data = status_resp.json()
# Process new events
for event in data.get("events", []):
print(f" [{event['id']}] {event['data']}")
since_index = event["id"] + 1
if data["status"] == "completed":
print("Done!")
result = data["result"]
for card in result.get("knowledge_cards", []):
print(f" Card: {card['title']}")
print(f" Embed: {card['embed_url']}")
break
elif data["status"] == "failed":
print(f"Failed: {data.get('error')}")
break
time.sleep(5)
Search effort options
| Effort | Behavior | Typical latency |
|---|
fast | Sync response (200) | 1–5 seconds |
medium | Sync response (200) | 5–15 seconds |
deep | Async delegation (202) | 30s – several minutes |
auto | Resolved server-side to fast, medium, or deep based on query complexity | Varies |
Status values
| Status | Meaning |
|---|
pending | Task is queued |
in_progress | Pipeline is running |
completed | Results are ready in the result field |
failed | Something went wrong — check the error field |
Poll every 5–10 seconds. Use since_index to avoid re-fetching events you’ve already seen.
When to use Deep Search
- Complex analytical queries (“Compare X vs Y over time”)
- Queries requiring data from multiple sources
- Research and report generation workflows
- When recall and data quality matter more than latency
For quick lookups where speed matters, use Fast Search instead.
Using Deep Search via MPP
Deep Search is also available via the Machine Payments Protocol (MPP) at /api/mpp/v1/threads/deep. This allows AI agents to pay per-request without API keys. The polling pattern is the same — submit to the paid endpoint, then poll the free status endpoint using the receipt token. See the MPP docs for details.