# Research playbook

> How people and AI assistants pick the right Virlo workflow for a research question and read the results correctly: costs, timings, virality scoring, platform benchmarks, AI fields, and audience data.

Source: https://dev.virlo.ai/docs/agent-playbook
Markdown: https://dev.virlo.ai/docs/agent-playbook.md
Section: For AI assistants

## About the Virlo API (applies to every page)

- Base URL: `https://api.virlo.ai/v1`. Every request needs the header `Authorization: Bearer YOUR_API_KEY` (keys start with `virlo_tkn_`).
- Responses are JSON inside a `data` field, except the `/v1/webhooks` endpoints, which return the object or array directly. Field names are snake_case.
- Prices are in US dollars from a prepaid balance. 1 credit = $0.01. The `X-Cost` response header on each successful response is the exact charge. Errors are free.
- Slow jobs return an ID. Check its status every 15 seconds (or whatever `retry_after_seconds` says) until `finalized` is `true`.
- All docs pages: https://dev.virlo.ai/llms.txt. Every page in one file: https://dev.virlo.ai/llms-full.txt. MCP server for AI assistants: https://dev.virlo.ai/api/mcp/mcp.

---

How to pick the right Virlo workflow for a research question, in any niche, and how to read what comes back.

**At a glance**

- **What it does:** A field guide for researching short-form video, yourself or through an AI assistant.
- **You get back:** What to run, how long it takes, how to rank viral videos, and how to read AI fields.
- **Cost:** Reading this guide is free. Each workflow lists its price.

> **Note:** Working through an AI assistant? Give it the plain-text guide [`/agent-playbook.txt`](https://dev.virlo.ai/agent-playbook.txt). If it's connected to Virlo by MCP, [Available tools](https://dev.virlo.ai/docs/mcp#available-tools) names the tool behind each workflow.

## Pick the right workflow

Find your question. Swap `:id`-style parts for real values.

An **agent** (Content Research Agent) collects TikTok, YouTube, and Instagram videos for your keywords. **Data Intelligence** (+$1.00 per run) adds an AI breakdown of the videos worth studying. A creator lookup's $0.25 AI read is separate and covers fewer fields.

### Research a niche

| Question | Run this | Cost |
| - | - | - |
| "What's working in X right now?" | **One-time agent**: `POST /v1/agents` with `is_recurring: false` | $0.50 (+$1.00 with Data Intelligence) |
| "Keep watching X for me." | **Recurring agent**: `POST /v1/agents` with `is_recurring: true` and a `cadence` | $0.50 per run, first run included; it starts right away (+$1.00 per run with Data Intelligence). |
| "What's working in X in Spanish or Thai?" | **Agent, all languages**: `POST /v1/agents` with `english_only: false` | Same as any agent |
| "Only videos uploaded from Canada." | **Country filter (beta)**: `GET /v1/agents/:id/videos?region=CA` | Free |
| "What do these videos actually say?" | **Transcripts**: `GET /v1/agents/:id/videos?include_transcript=true` | Free |

### Look up or track one thing

| Question | Run this | Cost |
| - | - | - |
| "Tell me about this creator." | **Creator lookup**: `GET /v1/satellite/creator/:platform/:username` | $0.50 (+$0.50 trend analysis, +$0.25 for the lookup's own AI read of each video) |
| "Who watches this creator?" | **Audience**: `audience_demographics=true` on a creator lookup, or `POST /v1/tracking/creators/:id/audience-refresh` | $0.50 per new snapshot |
| "Why did this video pop?" | **Video outlier check** (one video against the creator's usual numbers): `POST /v1/satellite/video-outlier` | $0.50 |
| "What's happening with this sound?" | **Sound lookup** (TikTok, Instagram): `GET /v1/satellite/sounds/:platform/:music_id` | $0.50 to $1.00 |
| "What's working under #X?" | **Hashtag lookup** (TikTok, Instagram, YouTube Shorts): `GET /v1/satellite/hashtags/:platform/:hashtag` | $0.50 to $2.50 |
| "Track this creator or video." | **Tracking**: `POST /v1/tracking/creators` or `/v1/tracking/videos` | $0.25 per check, daily by default |

### Trends, sounds, and hooks

| Question | Run this | Cost |
| - | - | - |
| "What's trending today?" | **Digests**: `GET /v1/trends/digest`, `/v1/videos/digest`, `/v1/hashtags` | $0.05 to $0.25 |
| "What's starting to take off?" | **Emerging trends**: `GET /v1/trends/emerging` | $0.25 |
| "What's trending in the US, UK, Australia, or Singapore?" | **Regional trends**: `GET /v1/trends?region=us` (or `gb`, `au`, `sg`) | $0.25 |
| "Find me a sound." | **Sounds**: `GET /v1/sounds/trending`, `/breakout`, `/search` | $0.10 to $0.25 |
| "What hooks work in X?" | **Hooks**: `GET /v1/agents/:id/hooks` for your agent's niche, or `GET /v1/hooks/trending` | $0.25 (free on an agent with Data Intelligence, or while it has no hooks yet) |
| "Which kinds of hooks work best?" | **Hook types**: `GET /v1/hooks/types?sort=strong_hit_rate` | Free |
| "Where is this hook from?" | **Hook search**: `GET /v1/hooks/search?q=...` | $0.25 |
| "Write me hooks for X." | **Hook templates**: `GET /v1/hooks/library` | $0.10 (+$0.25 if you also call `/v1/hooks/trending`) |

Most research follows one path: a one-time agent finds outlier creators (creators whose views far beat their follower count), a creator lookup checks the best ones, and tracking follows the winners.

**Coming from Orbit or Comet?**

`POST /v1/agents` replaces **Orbit** (now `is_recurring: false`) and **Comet** (now `is_recurring: true`). Both are deprecated and scheduled for removal. The announced date was August 3, 2026, and they still respond today, so migrate now. Old IDs work at `/v1/agents/:id`. See the [migration guide](https://dev.virlo.ai/docs/agents#migrating-from-orbit-comet).

## How long things take

Agents and lookups run in the background. Start a job, check back at the pace in the table below until it's done (polling), then read the results. Or get a [webhook](https://dev.virlo.ai/docs/webhooks) when it finishes. More in [How results load](https://dev.virlo.ai/docs/async-data).

- **Done means `finalized: true`.** `status: completed` alone can mean the AI report is still being written. Empty (`null`) AI fields mean "not yet," not "no data." The exception is a video with `intelligence_status: "skipped"`: its `intelligence` will never arrive.
- **`partial_failure` is usable** (about 2% of runs). One platform or keyword failed, and the rest is there. Only `failed` (rare) means no data.
- Each status reply says when to check next (`pending_jobs[].retry_after_seconds`).

| Job | Typical | Plan for | Check every |
| - | - | - | - |
| Agent run | About 8 min (9 in 10 within 20 min) | 45 min | 15 to 60 s |
| Creator lookup | 15 to 40 s | 2 min | 10 to 15 s |
| Sound lookup | 1 to 2 min | 5 min | 10 to 15 s |
| Hashtag lookup | 1 to 3 min | 5 min | 10 to 15 s |
| Video outlier check | 20 to 60 s | 3 min | 10 s |

Trend analysis makes sound and hashtag lookups a little slower. The job status check stops working after 24 hours.

## Setting up an agent

**Keywords matter most.** Use specific phrases of two or more words ("jeep wrangler mods", not "jeep"). Send 7 to 12, the number `suggest-keywords` returns (50 at most); the price is the same. Cover synonyms of the _same_ idea: each keyword is its own search on each platform.

**Write a real intent.** One required sentence on what you want to find. With Data Intelligence on, AI checks each video against it, and `intent_match=true` keeps only the matches when you read videos. See the [Intent cookbook](https://dev.virlo.ai/docs/intent-cookbook).

**Exclude words that pull in the wrong topic**, like apple the fruit when you mean Apple the company. A few exclude words remove more junk than an extra keyword adds.

- Each is matched as a whole word against captions and hashtags. `exclude_keywords_strict` also checks what's said in the video.
- Use single words from the other meaning (`recipe`, `fruit`, `orchard`). Phrases like `apple the fruit` filter out almost nothing, and excluding your own topic (`apple`) removes everything.
- The free keyword helper (`POST /v1/agents/suggest-keywords`) returns a ready `exclude_keywords` list. Pass it straight through.

**Other settings:**

- **Don't send `time_period` or `min_views`.** `POST /v1/agents` rejects them with a `400` error (MCP tools ignore them). Filter when you read instead, for free: the videos endpoint takes `min_views`, `platforms`, `start_date`, `end_date`, `region`, and `order_by`.
- **`english_only`** is `true` by default. For non-English niches, set it to `false` and write the keywords and intent in that language, or you get almost nothing.
- **`meta_ads_enabled: true`** also collects matching ads from Meta's ad library at no extra cost, but a run can take up to about 45 minutes. Use it when a brand or product is involved.
- **`data_intelligence_enabled: true`** (+$1.00 per run) when you want to _understand_ content (hooks, formats, messaging), not just count views. You can't add it to a run afterward.

## Reading what you collected

**Read everything you paid for.** Reading is free. A one-time run keeps about 360 videos (later recurring runs about 200), plus slideshows, ads, outlier creators, sounds, an AI report, and trends. Once it's finished, start with `GET /v1/agents/:id/summary`, then read the full lists.

**Filter by upload country (beta).** Add `region` with a two-letter code (`US`, `CA`, any case) to the agent's `videos` or `slideshows` endpoint. A country name returns nothing, so convert it yourself. Coverage is partial: items with no known country drop out.

**Creator lookups:** add `include=videos,outliers` and raise `max_videos` to 50 to 100 (the default is 20; sound and hashtag lookups already default to 50). The price stays $0.50. `cross_links=true` finds the creator's profiles on other platforms.

**All lookups** (video outlier checks included) are saved. Re-read one free at `GET /v1/satellite/runs/:run_id`; the `run_id` is the job ID. Each paid lookup is saved as a new run with its own `run_id`, so a later lookup of the same creator, sound, or hashtag never overwrites an earlier one.

**Refunds.** Virlo refunds a failed creator, sound, or hashtag lookup in full, for example a handle that doesn't exist, or a lookup that stalls and is closed out as failed. The trend analysis surcharge comes back when no trends come out, the audience surcharge when no new snapshot was needed, and the Data Intelligence surcharge when the lookup had no posts to enrich or its analysis failed. The result or failed status then shows `credits_refunded`, in credits, and so does the saved run at `GET /v1/satellite/runs/:run_id`, even for a failed lookup. The hashtag depth surcharge comes back only when the whole lookup fails.

## How recurring agents improve themselves

After each run, a recurring agent tunes its own keywords so it keeps finding new videos. This is **autopilot**. It is on by default for every new agent, whether you make it through the API, over MCP, or in the Virlo app.

- **What it does:** rewords searches, adds keywords (up to 15 in all), adds short-lived keywords for breaking stories in the niche, and collects more widely after a thin run. Keyword changes must pass a quality check first.
- **What it never does:** remove a keyword or exclude term you set (returned as `pinned_keywords`), add charges, change the schedule, or pause the agent. Price per run is unchanged.
- **What changed and why:** `GET /v1/agents/:id/activity` (free) is the change log.
- **Breaking stories:** `GET /v1/agents/:id/events` (free). Each has a title, summary, importance score (0 to 10), and the keywords added.
- **Turn it off:** send `autopilot: false` when you create or update the agent, or `PUT /v1/agents/:id/autonomy` with `{ "autopilot": false }`. The agent then keeps its setup exactly as you set it. `cognition_enabled: false` stops self-review entirely, and the agent keeps collecting.
- **Proposals are deprecated.** `GET /v1/agents/:id/proposals` and its apply, dismiss, and revert calls still work for now. Read the activity log instead.

One-time agents don't change themselves. See [Autopilot](https://dev.virlo.ai/docs/agents/autopilot#autonomy).

## Spotting the most viral

Raw views mislead. 500,000 views is routine for an account with 10 million followers and huge for one with 3,000. So rank by the **Virality Score** (`weighted_score`), as Virlo does for outlier creators and hooks. It rewards beating the follower count by a wide margin, weighted by audience size so one lucky video from a tiny account doesn't top every list.

That 3,000-follower video (167x its followers) scores 41: exceptional. 3,000,000 views on a 1,000,000-follower account (3x) scores 15: promising. Below 1x there's no score (the hooks endpoints show a negative one).

| Virality Score | Read it as |
| - | - |
| 35 or more | Exceptional: study it frame by frame |
| 25 to 35 | Very strong |
| 18 to 25 | Strong |
| 10 to 18 | Promising |
| Below 10 | Emerging or routine |

**How the score is calculated**

```
ratio = views / followers              (only when followers > 0 and ratio > 1)
weighted_score = ln(ratio) × ln(followers)
exceptional: weighted_score ≥ 35
```

`ln` is the natural logarithm (`Math.log` in JavaScript, `math.log` in Python).

To find the real winners:

1. Rank all videos by this score. The videos list can't sort by it, so compute it from `views` and `author.followers`.
2. Check the plain multiplier: 20 times the follower count is notable, 100 times exceptional, 1,000 times a mega-outlier.
3. Compute `engagement_rate = (likes + comments + shares) / views`. Above 5% on a big video means people really reacted. Below 1% means passive spread (a popular sound, reposts, or paid promotion).
4. Compare with the AI's picks (`analysis_data.top_10_breakdown`), which also weigh quality and topic fit. Videos on both lists are the real winners.
5. For whole accounts, sort **creator outliers** (`GET /v1/agents/:id/creators/outliers`) by `weighted_score` (`ln(outlier_ratio) × ln(follower_count)`), not the raw ratio. They're the best source of rising talent and partnership leads.
6. Check `publish_date`: a high score this week is a live trend; from months ago, it's history.

## Platform benchmarks

Never compare raw views across platforms.

| Platform | Median views | Top 10% start at | Top 1% start at | Videos with a transcript |
| - | - | - | - | - |
| TikTok | \~39K | \~1M | \~6.6M | \~63% |
| Instagram Reels | \~3.8K | \~175K | \~3M | Almost none, \~40% with Data Intelligence |
| YouTube Shorts | \~1K | \~32K | \~2.5M | \~38% |

A 100K-view Reel is a bigger deal than a 100K-view TikTok. Spoken insights (hooks, messaging) come mostly from TikTok and YouTube. Instagram publishes no transcripts, so a Reel only has one when Data Intelligence transcribed its audio. Without it, lean on descriptions, hashtags, and the AI's visual analysis.

To read the words themselves, add `include_transcript=true` to [Get videos](https://dev.virlo.ai/docs/agents#agent-video-transcripts). TikTok and YouTube transcripts are mostly plain text (`source: "platform"`). Timestamps always come with the ones Virlo transcribed (`source: "transcribed"`), which includes every Instagram transcript, and with a small share of platform ones, so check `segments`.

## Reading Data Intelligence fields

With Data Intelligence on, each analyzed video gets AI-written fields ([full list](https://dev.virlo.ai/docs/intelligence)). Off-topic, year-old and underperforming videos are skipped. The ones that matter most:

- **Hooks.** `hook_text` is the exact opening line. `hook_type` is its style (`question`, `bold_claim`, `pov_setup`, and more). Use the [hooks endpoints](https://dev.virlo.ai/docs/hooks), or group your top videos by `hook_type` and quote real `hook_text` lines as templates.
- **`summary`** is on every analyzed item. Reading 100 summaries is the fastest way to "watch" 100 videos.
- **`content_format`** includes free-text values, so group close ones (`skit`, `comedy_skit`, `skit_sketch`).
- **Commercial signals** (`is_sponsored`, `brands_mentioned[]`, `cta_usages[]`) show paid posts, organic brand mentions, and the niche's calls to action.
- **Trust checks.** Use an item's fields only when `intelligence_status` is `"ready"`. `"skipped"` items were left out on purpose and never get fields. Discount anything in `low_confidence_fields[]`. `transcript_word_count: 0` with visual fields filled in means a silent video, not missing data.

**Find the winners' pattern.** Count each `hook_type`, `content_format`, and `emotional_tone` in the top 25% of videos by Virality Score, then in the bottom 25%. The differences are the niche's real playbook.

## Slideshows

TikTok image carousels (slideshows) come back separately from `/slideshows`, with their own AI fields. In product, education, and lifestyle niches they often beat video.

- `panel_texts[]` and `panel_text_full` hold every slide's text in order. That's usually the whole content, so read it like a script you can adapt.
- `narrative_arc` is how the slides progress. `text_density` says whether text or images dominate.
- The hook is slide 1. Read `hook_text` as you would for a video.
- Video-only fields (`visual_format`, `camera_perspective`, captions, transcript) are absent by design.

## Reading the AI report and trends

`GET /v1/agents/:id/analysis/latest` returns the AI report in `analysis_data`:

- `key_highlight` is the top finding, in one paragraph. `overview` holds the counts (`total_videos` analyzed, `avg_virality`).
- `themes[]` are groups of what works, each with `why_it_works`, `tactics[]`, a `confidence` from 0 to 1, and `evidence_video_ids[]`. Trust 0.7 and up, check 0.5 to 0.7 against their videos, and call anything lower tentative. Match evidence IDs to the video list so every claim points to real videos.
- `timing_analysis` shows posting-time patterns, `excluded_videos` what the AI judged off topic, and `connecting_thread` the pattern tying the themes together.

`GET /v1/agents/:id/trends/latest` returns trends, each with a `status`: `new` (just appeared, the biggest opportunity), `rising` (growing, act now), `steady` (holding), or `fading` (skip it). On recurring agents, `stable_key` follows one trend across runs, and the `prev_*` fields show the change since the last run. A trend moving from `new` to `rising` with a growing `video_count` is the strongest "post about this now" signal.

## Trusting audience data

Audience snapshots are built mainly from the people who **comment** on a creator's videos, not from the follower count. Before you share the numbers:

- **`confidence_level`:** `high` or `medium` is usable. For `low`, say "limited signal" and don't present the percentages as fact.
- **`data_source`,** strongest first: `comments`, `comments_extended`, `mixed`, `followers` (TikTok only, never above medium confidence), then `profile_only`. `profile_only` means no real signal and is refunded automatically. Treat it as "no data."
- **Cost:** a snapshot is reused free for 30 days (`freshness_days`). Only a new one costs $0.50. Asking again while one is being built returns that job for free.

## Spending wisely

- Starting work costs money, and so do instant data requests (trends, hashtags, sounds, hooks). Re-reading is free, so first check what your team already has: `GET /v1/agents`, `/v1/satellite/runs`, `/v1/tracking/creators`.
- One well-scoped agent beats three vague ones. Put the effort into keywords, not retries.
- Add up the cost before a plan with several paid steps, and check your balance first (`GET /v1/account/balance`, free). Top up if it's under $10. The `X-Balance-Remaining` header only appears on paid responses.
- Vetting many creators? `POST /v1/satellite/creators/batch` takes up to 25, at $0.50 for each creator it looks up. A creator looked up in the last 6 hours with at least the same options comes back from cache for free.
- `X-Cost` always shows the full charge. A refund for a failed lookup or an empty post collection arrives after the job ends, as its own row in your usage history.

---

More in For AI assistants:

- [MCP server](https://dev.virlo.ai/docs/mcp.md)
- [Connect an AI assistant](https://dev.virlo.ai/docs/ai-agents.md)
