SKILL.md
Perplexity Deep Research API Automation
This skill automates research using Perplexity's Deep Research API with both synchronous and asynchronous modes.
Overview
The Perplexity Deep Research API provides programmatic access to comprehensive research:
- Conducts multi-step research process
- Searches across academic databases, official sources, peer-reviewed journals
- Synthesizes findings with proper citations
- Returns structured markdown-formatted reports
Modes:
- Sync (default): Blocking call, 30-120s typical, up to 10 minutes. Retries on failure.
- Async: Fire-and-poll. Submit returns immediately with job ID. Poll for results. No client-side timeout. Results stored 7 days.
Output: Comprehensive research report with inline citations and source links. Results are automatically saved to timestamped files. Metadata sidecar JSON includes citations, cost breakdown, and search results.
Focus Areas:
- Academic studies and peer-reviewed papers
- Meta-analyses and systematic reviews
- Official government/regulatory sources
- Authoritative industry reports
Prerequisites
- Perplexity API key in repository
.envor/Users/valorengels/.env - Python 3.x with
requestsandpython-dotenvinstalled - API key from: https://www.perplexity.ai/settings/api
API Key Setup
Check if API key exists:
grep PERPLEXITY_API_KEY .env 2>/dev/null || grep PERPLEXITY_API_KEY /Users/valorengels/.env 2>/dev/null || echo "PERPLEXITY_API_KEY not found"
If not found, add to repository .env file (preferred) or global .env file:
echo 'PERPLEXITY_API_KEY=pplx-your-api-key-here' >> .env
Complete Automation Workflow
Step 1: Verify API Key
grep PERPLEXITY_API_KEY .env 2>/dev/null || grep PERPLEXITY_API_KEY /Users/valorengels/.env 2>/dev/null || echo "PERPLEXITY_API_KEY not found"
Step 2: Prepare Research Prompt
Prompt format (3 lines, single newlines):
Research [TOPIC].
Focus on peer-reviewed studies, meta-analyses, systematic reviews, and official government/regulatory sources.
Provide comprehensive findings with full citations, sample sizes, methodological details, and source URLs.
Step 3: Run Research
Synchronous (default — blocking, waits for result):
cd /Users/valorengels/src/research/podcast/tools
python perplexity_deep_research.py \
--file ../episodes/[episode-dir]/prompts.md \
--output ../episodes/[episode-dir]/research/p2-perplexity.md
Async (fire-and-poll — no blocking, no client-side timeout):
# Submit and wait for result
python perplexity_deep_research.py --async \
--file ../episodes/[episode-dir]/prompts.md \
--output ../episodes/[episode-dir]/research/p2-perplexity.md
# Submit and return immediately (fire-and-forget)
python perplexity_deep_research.py --no-wait "Research prompt here"
# Output: Job ID: abc123
# Poll for results later
python perplexity_deep_research.py --job-id abc123 \
--output ../episodes/[episode-dir]/research/p2-perplexity.md
List all async jobs:
python perplexity_deep_research.py --list-jobs
Available CLI Options
| Option | Description |
|---|---|
--file FILEPATH |
Read prompt from file |
--output FILEPATH |
Write results to file |
--reasoning-effort LEVEL |
Effort: low, medium, high (default: high) |
--async |
Use async API (submit, poll, return result) |
--sync |
Force synchronous API (default) |
--no-wait |
Submit async job, return job ID immediately |
--job-id ID |
Poll an existing async job by ID |
--list-jobs |
List all async jobs for this API key |
--poll-interval SECS |
Seconds between poll attempts (default: 10) |
--timeout SECONDS |
Timeout in seconds (default: 600) |
--max-retries N |
Max retry attempts for sync mode (default: 3) |
--show-cost |
Display cost breakdown |
--quiet |
Minimal output |
--auto-save |
Auto-save output with timestamp (default when no --output) |
--no-auto-save |
Disable automatic file saving |
--log-dir DIR |
Directory for output/log files |
Step 4: Monitor Progress
Sync mode: Script will wait 30-120s (up to timeout), retry on failure, auto-save results.
Async mode: Script submits job and either polls until complete or returns job ID for later retrieval.
Step 5: Output Files
Research output:
research/p2-perplexity.md— Research content with citationsresearch/p2-perplexity.meta.json— Structured metadata (citations, cost, search results)research/p2-perplexity_log.txt— Progress log (sync mode)
Metadata JSON example:
{
"timestamp": "2026-02-11T10:30:00",
"model": "sonar-deep-research",
"usage": {
"prompt_tokens": 234,
"completion_tokens": 5678,
"total_tokens": 5912,
"citation_tokens": 1200,
"reasoning_tokens": 3400,
"search_queries": 15
},
"cost": {
"input_tokens": {"count": 234, "cost": 0.0005},
"output_tokens": {"count": 5678, "cost": 0.0454},
"total": 0.0894
},
"citations": ["https://...", "https://..."],
"search_results": [{"title": "...", "snippet": "...", "date": "..."}]
}
API Details
Synchronous API
Endpoint: POST https://api.perplexity.ai/chat/completions
Request:
{
"model": "sonar-deep-research",
"messages": [{"role": "user", "content": "Research prompt"}],
"reasoning_effort": "high"
}
Async API
Submit: POST https://api.perplexity.ai/async/chat/completions
{
"request": {
"model": "sonar-deep-research",
"messages": [{"role": "user", "content": "Research prompt"}],
"reasoning_effort": "high"
}
}
Response: {"id": "abc123", "status": "CREATED", "response": null}
Poll: GET https://api.perplexity.ai/async/chat/completions/{id}
Status values: CREATED → IN_PROGRESS → COMPLETED | FAILED
List: GET https://api.perplexity.ai/async/chat/completions
Results are stored for 7 days.
Cost Tracking
Pricing (as of 2025):
| Component | Cost |
|---|---|
| Input tokens | $2/M |
| Output tokens | $8/M |
| Citation tokens | $2/M |
| Reasoning tokens | $3/M |
| Search queries | $5/1K |
Typical deep research: $0.50-$1.00 per query.
Use --show-cost to display cost breakdown after research completes.
Error Handling
API Key Errors
Error: ERROR: PERPLEXITYAPIKEY not found
- Check
.envfile:grep PERPLEXITYAPIKEY .env - Get API key: https://www.perplexity.ai/settings/api
API Request Failures
| Error | Solution |
|---|---|
| 401 Unauthorized | API key invalid/expired. Regenerate at perplexity.ai |
| 429 Rate Limit | Wait 60s. Check usage limits |
| 500 Server Error | Wait 30s, retry. Check Perplexity status |
| Timeout (sync) | Use --async mode, increase --timeout, or reduce --reasoning-effort |
Async-Specific Errors
| Error | Solution |
|---|---|
| Job FAILED | Check error_message in response. Simplify prompt or retry |
| Job not complete after timeout | Use --job-id to poll again later (results stored 7 days) |
Integration with Podcast Workflow
Sync workflow (current default):
cd podcast/tools
python perplexity_deep_research.py \
--file "../episodes/YYYY-MM-DD-slug/prompts.md" \
--output "../episodes/YYYY-MM-DD-slug/research/p2-perplexity.md" \
--reasoning-effort high
Async workflow (fire-and-forget for parallel research):
cd podcast/tools
# Fire off Perplexity research (returns immediately)
python perplexity_deep_research.py --no-wait \
--file "../episodes/YYYY-MM-DD-slug/prompts.md"
# Output: Job ID: abc123
# ... run other research tools in parallel ...
# Retrieve results when ready
python perplexity_deep_research.py --job-id abc123 \
--output "../episodes/YYYY-MM-DD-slug/research/p2-perplexity.md"
Script Location
Path: /Users/valorengels/src/research/podcast/tools/perplexitydeepresearch.py
Comparison to Other Tools
| Feature | Perplexity | Gemini | GPT-Researcher |
|---|---|---|---|
| Speed | 30-120s | 3-10 min | 6-20 min |
| Cost | $$$ | $$ | $ (varies) |
| Academic Focus | High | Low | Medium |
| Async Support | Yes | Yes | Yes |
| Citations | Inline + structured | Inline | Comprehensive |
| API-Based | Yes | Yes | Yes |
Recommendation: Use Perplexity for Phase 1 academic research. Use --async for parallel research workflows.
Best Practices
- Always verify API key before running research
- Use high reasoning effort for podcast research (default)
- Use
--asyncfor parallel research — fire off Perplexity while running other tools - Use
--no-wait+--job-idfor true fire-and-forget workflows - Specify output file using
--outputfor organized file structure - Check
.meta.jsonfor structured citations and cost data - Use
--show-costto monitor API spending - Trust the async API — no client-side timeouts or retries needed
- Request citations explicitly in prompts
- Use
--syncas fallback if async has issues