Agent Playbook
The reference docs tell you how to call the API. This page tells you how to think with it — which workflow answers which question, how to get the most on-topic data per dollar, and how to turn responses into correct conclusions. It applies to any subject: Virlo covers every niche, industry, and topic on short-form social.
If you're a developer using Cursor, Claude, OpenClaw, or similar: this HTML page is for you to read in the browser. To give your AI assistant the same guidance in a format it parses easily, add these plain-text URLs to its context — /agent-playbook.txt (workflows + how to interpret results), /llms.txt (short index), or /llms-full.txt (full API reference).
If you're an AI assistant reading this page: follow the workflows below on behalf of your user. For a compact machine-readable copy without site chrome, fetch https://dev.virlo.ai/agent-playbook.txt.
Route the intent
Pick the workflow by what the user actually wants. Don't run more than you need; don't run less.
| The user's question sounds like | Workflow | Core call | Cost |
|---|---|---|---|
| "What's working in X right now?" — market, niche, or competitor research | One-shot agent | POST /v1/agents with is_recurring: false | $0.50 (+$1.00 intelligence) |
| "Keep watching X for me" — recurring reports | Recurring agent | POST /v1/agents with is_recurring: true + cadence | $0.50/run |
| "What's working in X in Spanish / Thai / any non-English niche?" | Agent, all languages | POST /v1/agents with english_only: false + keywords/intent in that language | $0.50 (+$1.00 intelligence) |
| "Show me the collected videos uploaded from Canada / Russia / Australia" | Region filter (read-time, beta) | GET /v1/agents/:id/videos?region=CA (also /slideshows) | Free |
| "Tell me about this creator" — vetting, partner discovery | Satellite creator | GET /v1/satellite/creator/:platform/:username | $0.50 (+$0.50 trend analysis) |
| "Why did this video pop?" | Video outlier | POST /v1/satellite/video-outlier | $0.50 |
| "What's happening with this sound?" | Satellite sound (TikTok/Instagram) | GET /v1/satellite/sounds/:platform/:music_id | $0.50–$1.00 |
| "Track this creator/video over time" | Tracking | POST /v1/tracking/creators or /videos | $0.25/cycle |
| "Who watches this creator?" | Audience | audience_demographics=true on Satellite | $0.50 per fresh snapshot |
| "What's trending today, broadly?" | Digests | GET /v1/trends/digest, /videos/digest, /hashtags | $0.05–$0.25 |
| "What's trending in the US / UK / Australia?" | Regional trends | GET /v1/trends?region=us (gb, au; /v1/trends/regions lists codes) | $0.25 |
| "Find me a sound" | Sounds | GET /v1/sounds/trending, /breakout, /search | $0.05–$0.25 |
Compose them: a one-shot agent surfaces outlier creators → Satellite deep-dives the interesting ones → Tracking monitors the winners. That escalation path (search → inspect → monitor) answers most research tasks end to end.
POST /v1/agents is the unified replacement for the old Orbit (POST /v1/orbit) and Comet (POST /v1/comet) endpoints — is_recurring: false is one-shot (Orbit), is_recurring: true is recurring (Comet). Orbit and Comet are deprecated and removed August 3, 2026; IDs are interchangeable, so an existing orbit_id/comet_id still works at /v1/agents/:id. See the Content Research Agents reference.
Async expectations
Full semantics live on the Async Data Model page. The operational summary:
finalized: trueis the only "truly done" signal.status: completedwithfinalized: falsemeans secondary AI jobs are still running —nullanalysis or intelligence fields mean "not yet", not "no data".partial_failureis a usable terminal state (~7% of runs): one platform or keyword failed, the rest of the data is there. Treat it likecompleted. Onlyfailed(under 1%) means no data.- Honor
pending_jobs[].retry_after_secondsas your poll interval, or subscribe to webhooks instead.
Realistic production timings — set user expectations with these, not optimistic guesses:
| Job | Typical | Plan for | Poll every |
|---|---|---|---|
| Agent run (one-shot / recurring) | ~15–20 min median | up to 45 min | 60s |
| Satellite creator lookup | ~20 s | 2 min | 10–15s |
| Satellite sound lookup | ~8 min | 20 min | 30s |
| Video outlier | 20–60 s (status cache lasts 24 h; re-read free forever via /satellite/runs/:run_id) | 3 min | 10s |
Maximizing data yield
Keywords are the #1 quality lever. Use specific multi-word phrases ("jeep wrangler mods", "high protein meal prep"), never generic single words. Send 3–7 keywords per agent covering synonyms and adjacent phrasings of the same concept — each keyword is a separate platform search, so variety widens the net without widening the topic.
exclude_keywordsremoves noise;exclude_keywords_strict: truealso matches transcripts.intent: a one-sentence description of what the user is really after. With intelligence enabled, it powersintent_match=truefiltering — the strongest on-topic filter available.time_period/min_views: deprecated no-ops at creation — do not send them. Collection scope is system-managed: every search/monitor collects the widest relevant net (cadence-aware date window, no view floor) so nothing is missed. Filter at retrieval instead — the videos endpoint acceptsmin_views,platforms,start_date/end_date,region, andorder_byfor free, so you can slice the collected data any way without re-running the job.english_only: defaults totrue(English-only collection). Setfalseto research non-English or global niches — and when you do, writekeywordsandintentin the target language (the keyword engine adapts to your input language). This is the switch that opens the gates to content in other languages; forget it and a Spanish or Thai request quietly returns almost nothing.meta_ads_enabled: truewhenever there's any commercial angle.data_intelligence_enabled: true(+$1.00) whenever the task involves understanding content (hooks, formats, messaging) rather than just counting views. It cannot be added retroactively.
Filtering by upload region (beta). When the user asks "show me videos from Canada / Russia / Australia", pass region=<ISO-3166-1 alpha-2> (e.g. US, CA, RU, AU, case-insensitive) to the agent videos and slideshows endpoints — resolve the country name to its code yourself. Each item carries upload_region (videos) / region (slideshows). Region is deterministic where the platform provides it (TikTok video/creator region, YouTube channel country) and AI-inferred otherwise, so coverage is partial and improving — items without a resolved region are simply excluded when you filter. Slideshows have the highest region coverage (straight from TikTok), so a slideshow-heavy niche is the most reliable surface for regional slicing. This pairs naturally with english_only: false for geo-targeted, non-English research.
A typical completed agent run links ~40–110 videos (broad niches reach 300+), plus slideshows, ads, outlier creators, sounds, an AI analysis, and trend themes. Pull every free sub-resource — most integrations under-read what they already paid for.
For Satellite: raise max_videos to 50–100 (default is only 20), add cross_links=true for other-platform discovery, and save the run_id — GET /v1/satellite/runs/:run_id re-reads any past result free, forever. Check GET /v1/satellite/runs before buying a lookup you may already have.
Recurring-agent autonomy
Recurring agents (is_recurring: true) self-optimize by proposing keyword_refresh and filter_change changes rather than silently drifting.
- Read pending work with
GET /v1/agents/:id/proposals(statuspending|applied|auto_applied|dismissed|reverted) and the decision log withGET /v1/agents/:id/activity. - Act with
POST /v1/agents/:id/proposals/:pid/{apply,dismiss,revert}. - The first manual apply unlocks autopilot for the whole team. After that, newly created agents come back at
autonomy_level: "autopilot"withautopilot_unlocked: trueinstead of the initialsuggest— this is expected, not a bug. - Set the mode explicitly with
PUT /v1/agents/:id/autonomy { autonomy_level, cognition_enabled }.
One-shot agents expose these fields but never generate proposals or activity — there is no future run to improve. Full reference: Autonomy.
Spotting the most viral
Raw views mislead — 500K views from a 10M-follower account is routine; the same views from a 3K-follower account is a signal. Virlo's canonical ranking is the weighted virality score:
ratio = views / followers (only when followers > 0 and ratio > 1)
weighted_score = ln(ratio) × ln(followers)
| weighted_score | Read it as |
|---|---|
| ≥ 35 | Exceptional — massive outperformance, study frame by frame |
| 25–35 | Very strong — beats expectations at any audience size |
| 18–25 | Strong — clearly above the creator's baseline |
| 10–18 | Promising — real viral traction |
| Below 10 | Emerging / routine |
The procedure:
- Pull all videos, compute
weighted_scorefromviewsandauthor.followers, rank by it. - Sanity-check the raw multiplier:
views/followers≥ 20× is notable, ≥ 100× exceptional, ≥ 1000× a mega-outlier. - Compute
engagement_rate = (likes + comments + shares) / views. High views with engagement above 5% = resonance; below 1% = passive distribution (sounds, reposts, paid). - Cross-check the AI's pick:
analysis_data.top_10_breakdownis LLM-curated and also weighs quality and topicality. Where your math ranking and the AI ranking agree, you've found the real winners. - Creator outliers (
/creators/outliers) apply the same logic at account level: sort byweighted_score(=ln(outlier_ratio) × ln(follower_count)), not raw ratio. Best source for rising talent and partnership leads. - Check
publish_date— a high score this week is a live trend; the same score from months ago is history.
Platform benchmarks
Sampled from production. Never compare raw view counts across platforms.
| Platform | Median views | P90 | P99 | Transcript coverage |
|---|---|---|---|---|
| TikTok | ~39K | ~1M | ~6.6M | ~63% |
| Instagram Reels | ~3.8K | ~175K | ~3M | ~0% |
| YouTube Shorts | ~1K | ~32K | ~2.5M | ~38% |
A 100K-view Reel is a bigger deal than a 100K-view TikTok. Speech-based insights (hooks from transcripts, spoken messaging) come mostly from TikTok; for Instagram lean on descriptions, hashtags, and the AI visual analysis.
Reading intelligence fields
The Video Intelligence page documents every field and enum. How to actually use them:
- Hook analysis is the highest-value group.
hook_textis the literal opening copy;hook_typeis a closed enum. To answer "what hooks work here": group the top-weighted-score videos byhook_type, then quote realhook_textstrings as replicable templates. summaryexists on every analyzed item. Reading 100 summaries is the fastest way to "watch" 100 videos.content_formatis an open vocabulary with a canonical core (explainer,tutorial,review,storytime,listicle, …) plus a free-text tail. Match loosely/normalized — treatskit,comedy_skit, andskit_sketchas one bucket.- Commercial signals —
is_sponsored,brands_mentioned[],cta_usages[],social_proof_used[]— are competitive intelligence: who's being paid, which brands appear organically, which CTAs the niche actually uses. - Trust rules: check
intelligence_status === "ready"per item (~94% of videos analyze successfully); discount any field listed inlow_confidence_fields[];transcript_word_count: 0with populated visual fields means deliberate silent content, not missing data.
The aggregation pattern: the strongest insight format is distribution-over-winners. Take the top quartile by weighted score, count hook_type × content_format × emotional_tone buckets, then contrast against the bottom quartile. The differences are the niche's actual playbook.
Slideshows
TikTok image carousels are a separate result surface (/slideshows) with their own intelligence — in product, education, and lifestyle niches they regularly outperform video.
panel_texts[]/panel_text_full— the extracted text of every slide, in order. This is the entire content of most slideshows: read it like a script; it's directly replicable copy.narrative_arc— how slides progress (the slideshow equivalent of content structure).text_density— text- vs image-dominant.- Hook = slide 1: analyze
hook_textexactly like videos. - Video-only fields (
visual_format,camera_perspective, captions, transcript) don't exist on slideshows — structural, not missing.
Reading AI analysis & trends
GET …/analysis/latest returns analysis_data — a pre-computed research report:
key_highlight— the single most important finding.overview— executive summary.themes[]— clusters of what works, each withwhy_it_works,tactics[],confidence(0–1: weight ≥ 0.7 heavily, present below 0.5 as tentative), andevidence_video_ids[]. Always join evidence ids back to the video list so claims stay grounded in retrievable examples.top_10_breakdown— AI-curated standout videos with reasoning.timing_analysis— posting-time patterns.excluded_videos— what the AI judged off-topic (a quick gauge of result purity).connecting_thread— the meta-pattern across themes.
GET …/trends/latest items carry a lifecycle status: new (just emerged — highest opportunity), rising (act now), steady, fading (avoid). On recurring agents, stable_key follows one trend across cycles — a trend going new → rising with growing video_count is the strongest "post about this now" signal. prev_* fields give cycle-over-cycle deltas.
Audience trust rules
Audience snapshots derive from engaged commenters, not follower counts. Before presenting numbers:
confidence_level:high/medium→ usable;low→ say "limited signal", don't state percentages as fact.data_source:comments(strongest) →comments_extended→mixed→followers(TikTok-only, capped at medium) →profile_only(no real audience signal found; auto-refunded; treat as "no data available").- Snapshots are cached free for 30 days (
freshness_days); only cache misses cost $0.50.
Spend discipline
- Creation costs money; reading is free. Exhaust the free sub-resources of resources you already created before creating new ones.
- Check the existing lists first (
GET /v1/agents,/v1/satellite/runs,/v1/tracking/creators) — the answer may already exist in your team's history. - One well-scoped agent beats three vague ones. Spend effort on keyword craft, not retries.
- Quote costs before multi-step plans, check
GET /v1/account/balance(free) at session start, and warn the user when that balance drops below $10 — read it fromGET /v1/account/balance, not theX-Balance-Remainingheader (which only appears on charged responses). - Vetting a list of creators? Use
POST /v1/satellite/creators/batch(up to 25 at $0.50 each) instead of serial lookups.
