Workflow recipes
Code for five research questions, with the cost and time of each. Replace YOUR_API_KEY with your key.
- What it does
- Answers one research question per recipe, call by call.
- You send
- A topic, a creator's handle, or a hashtag.
- You get back
- An AI report, top videos, ads, standout creators, trends, or hashtag stats.
- Cost
- $0.15 to $1.25 per recipe as written, before add-ons. A recurring agent then costs $0.50 per run until you pause or delete it. Reading an agent's videos, ads, creators, and report is free; hashtag and trend lists charge every time. A successful response's
X-Costheader shows its cost.
An agent (Content Research Agent) collects matching videos and writes an AI report, once or on a schedule. A lookup checks one creator, video, sound, or hashtag.
- What works in my niche?
- Why did a creator's video take off?
- What is trending, and can I keep watching it?
- Which hashtags are biggest?
- What works in Spanish, or in Mexico?
Full niche analysis
A one-time agent searches TikTok, YouTube, Instagram, and Meta ads, then reports what is working.
- Cost
- $0.50, charged when you create the agent, even if the run fails. $1.50 with Data Intelligence: AI notes on hook and format for many, not all, videos.
- How long
- Half of all runs are done in under 8 minutes, and 9 in 10 in under 20. Broad runs like this take longer.
1. Create a one-time agent ($0.50)
Describe what you want (intent) and add keywords, or get them free from Suggest keywords.
Create agent
curl -X POST https://api.virlo.ai/v1/agents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"is_recurring": false,
"intent": "Find what is working in Jeep Wrangler mods content right now",
"name": "Jeep Wrangler Mods Research",
"keywords": ["jeep wrangler mods", "jeep wrangler accessories", "jeep upgrades"],
"platforms": ["youtube", "tiktok", "instagram"],
"meta_ads_enabled": true
}'
2. Wait until it's done (free)
Check again every 30 seconds until finalized is true (report written) and last_run_at is set (creators scored). A partial_failure run (one keyword or platform failed) is still usable; a failed run is not.
Check status
deadline = time.time() + 60 * 60 # stop waiting after an hour (rare)
while True:
agent = requests.get(
f'https://api.virlo.ai/v1/agents/{agent_id}',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
).json()['data']
if agent['latest_run']['status'] == 'failed':
raise Exception('The run failed.')
# finalized: videos collected and the AI report written
# (latest_run.status "completed" alone only means videos are collected).
# last_run_at: set about a minute later, when creator scoring is done.
if agent['finalized'] and agent['last_run_at']:
break
if time.time() > deadline:
# Check again later. Creating a new agent would charge you again.
raise TimeoutError('Still running after an hour.')
print(f"{agent['stage']}: {agent['progress_pct']}%") # e.g. "collecting: 40%"
time.sleep(30)
# analysis is only the headline. The full report (themes, tactics, posting times,
# top 10 videos) is in analysis_data, also at GET /v1/agents/:id/analysis/latest.
report = agent['analysis_data'] or {}
print(agent['analysis']) # the main takeaway, in one or two sentences
for theme in report.get('themes', []):
print(f"- {theme['name']}: {theme['why_it_works']}")
# Example output, from a latte art agent:
# The most impactful insight for creators is the overwhelming success of 'progress journey' content, ...
# - Progress Journey Latte Art: Documenting daily or incremental improvements creates a relatable narrative, ...
Or use the content_research_agent.run.completed webhook. It can arrive up to a minute before creator scoring ends, so check last_run_at first.
3. Read the results (free)
Standout creators get far more views than their follower count predicts.
Read results
# Free, including the filters (min_views, start_date, end_date, platforms, region).
# The 50 most-viewed videos
videos = requests.get(
f'https://api.virlo.ai/v1/agents/{agent_id}/videos',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'limit': 50, 'order_by': 'views', 'sort': 'desc'}
).json()['data']['videos']
# Meta ads (needs meta_ads_enabled at create time)
ads = requests.get(
f'https://api.virlo.ai/v1/agents/{agent_id}/ads',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'limit': 50}
).json()['data']['ads']
# Standout creators ("creator outliers"), best Virality Score first.
# weighted_score = ln(avg_views / followers) x ln(followers)
# 35+ exceptional, 25-35 very strong, 18-25 strong, 10-18 promising
outliers = requests.get(
f'https://api.virlo.ai/v1/agents/{agent_id}/creators/outliers',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'limit': 20, 'order_by': 'weighted_score', 'sort': 'desc'}
).json()['data']['outliers']
for creator in outliers[:5]:
print(f"{creator['platform']}: {creator['follower_count']:,} followers, "
f"{creator['avg_views']:,.0f} avg views, score {creator['weighted_score']}")
print(f" {creator['creator_url']}")
# Example output:
# instagram: 1,791 followers, 475,807 avg views, score 41.81
# https://www.instagram.com/...
4. Optional: profile a creator ($0.50 to $1.00)
Run the Creator deep dive on their handle ($0.50, or $1.00 with its step 2). TikTok and Instagram creator_urls end with the handle; on YouTube, open the link and copy the @handle.
for creator in outliers[:3]:
handle = creator['creator_url'].rstrip('/').split('/')[-1].lstrip('@')
# On YouTube this is often a channel ID (/channel/UC...), not a handle.
print(creator['platform'], handle) # tiktok outside.kev
Creator deep dive
Size up a creator, then see if their top recent video is a real breakout.
- Cost
- $1.00: $0.50 per lookup, charged when it starts. A failed creator lookup, such as for a handle that doesn't exist, is refunded; a failed video check isn't.
- How long
- About a minute. Each lookup usually takes 20 to 40 seconds.
1. Look up the creator ($0.50)
Creator lookup
curl "https://api.virlo.ai/v1/satellite/creator/tiktok/khaby.lame?include=videos,outliers&max_videos=20" \
-H "Authorization: Bearer YOUR_API_KEY"
2. Check their top recent video ($0.50)
This checks the most-viewed of the 20 recent videos the lookup read, not necessarily their all-time top.
Video outlier check
# The most-viewed of the recent videos the lookup read
top_video = max(creator['videos'], key=lambda v: v['views'])
response = requests.post(
'https://api.virlo.ai/v1/satellite/video-outlier',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={'url': top_video['url'], 'platform': 'tiktok'}
)
video_job_id = response.json()['data']['job_id']
while True:
result = requests.get(
f'https://api.virlo.ai/v1/satellite/video-outlier/status/{video_job_id}',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
).json()['data']
if result['status'] == 'completed':
break
if result['status'] == 'failed':
raise Exception(result['error'])
time.sleep(10)
analysis = result['result']['analysis']
print(f"Outlier score: {analysis['outlier_score']}") # views / the creator's median views
print(f"Percentile: {analysis['percentile']}") # % of their recent videos it beat
print(f"Label: {analysis['performance_label']}") # average | above_average | viral | mega_viral
# Both results are saved. Reopen either for free with GET /v1/satellite/runs/{job_id},
# so keep both IDs. A new paid lookup of the same creator gets its own ID; old runs stay.
outlier_score is views divided by the creator's median views (up to 100 recent videos): mega_viral is 10x or more, viral 3 to 10x, above_average 1.5 to 3x, average under 1.5x.
Trend monitoring setup
Find today's trends, research one, then keep watching it with a recurring agent.
- Cost
- $1.25 to start ($0.25 trends, $0.50 one-time agent, $0.50 first recurring run), or $0.75 without the one-time agent. Then $0.50 per run.
- How long
- Seconds, plus one agent run (up to about 20 minutes).
1. Get today's trends ($0.25)
Worldwide trends, unless you add region=us (or gb, au, sg).
Get trends
import requests
API = 'https://api.virlo.ai/v1'
headers = {'Authorization': 'Bearer YOUR_API_KEY'}
digest = requests.get(f'{API}/trends/digest', headers=headers).json()['data']
for group in digest:
print(group['local_date']) # the list's date. Don't use 'title', which can be a day off.
for item in group['trends']:
print(f" #{item['ranking']}: {item['trend']['name']}")
2. Research one trend ($0.50)
Get free keyword ideas and start a one-time agent, then read results as in the Full niche analysis.
Research a Trend
trend_name = digest[0]['trends'][0]['trend']['name'] # or pick one from the list
intent = f'Find what is working in short videos about {trend_name}'
# Keyword ideas (free)
suggestion = requests.post(
f'{API}/agents/suggest-keywords',
headers=headers,
json={'intent': intent}
).json()['data']
# Before you pay for a run, check that suggestion['quality']['passes'] is True.
# One-time agent ($0.50). Optional: skip it to start at $0.75, but keep the keyword ideas.
agent = requests.post(
f'{API}/agents',
headers=headers,
json={
'is_recurring': False,
'intent': intent,
'keywords': suggestion['keywords'],
'exclude_keywords': suggestion['exclude_keywords'], # words that point to other topics
}
).json()['data']
agent_id = agent['id']
3. Keep watching it ($0.50 per run)
Create a new agent with is_recurring: true and a cadence: daily, weekly, monthly, or a custom schedule (cron format), at most once a day.
Creating it is free, but its first run starts at once. Each run costs $0.50 when it finishes. A partial_failure run is charged; a failed run isn't. These charges aren't in any header, so check your balance. To stop them, pause (Update agent, active: false) or delete the agent.
Create recurring agent
# Your balance must cover the first run ($0.50), or this returns a 402 error.
monitor = requests.post(
f'{API}/agents',
headers=headers,
json={
'is_recurring': True,
'cadence': 'weekly', # runs early each Sunday, UTC
'name': f'Weekly watch: {trend_name}',
'intent': intent,
'keywords': suggestion['keywords'],
'exclude_keywords': suggestion['exclude_keywords'],
}
).json()['data']
print(f"Agent ID: {monitor['id']}")
print(f"Next scheduled run: {monitor['next_run_at']}") # the first run has already started
Hashtag research
See which hashtags had the most-viewed videos posted in the last 30 days.
- Cost
- $0.05 per call: $0.15 for steps 1 to 3, or $0.25 adding YouTube and Instagram. Empty lists are billed; a hashtag with no videos (
404) is free. - How long
- A few seconds per call.
Numbers count only videos Virlo has collected, so compare hashtags with each other, not with platform totals.
1. Top hashtags ($0.05)
Top lists need both dates (YYYY-MM-DD, at most 90 days apart). Views are the current totals of videos posted in that range.
Top hashtags
import requests
from datetime import date, timedelta
headers = {'Authorization': 'Bearer YOUR_API_KEY'}
end = date.today().isoformat()
start = (date.today() - timedelta(days=30)).isoformat()
hashtags = requests.get(
'https://api.virlo.ai/v1/hashtags',
headers=headers,
params={'start_date': start, 'end_date': end, 'limit': 20, 'order_by': 'views', 'sort': 'desc'}
).json()['data']
# Generic tags like #fyp lead. Hashtags come back lowercase, without the #.
for tag in hashtags[:5]:
print(f"#{tag['hashtag']}: {tag['count']:,} videos, {tag['total_views']:,} views")
2. One hashtag's numbers ($0.05)
Skip the dates for all-time numbers.
Hashtag performance
perf = requests.get(
'https://api.virlo.ai/v1/hashtags/fyp/performance', # no # in the path
headers=headers,
params={'start_date': start, 'end_date': end}
).json()['data']
print(f"#fyp: {perf['video_count']:,} videos, {perf['total_views']:,} views, avg {perf['avg_views']:,.0f} views/video")
3. Top hashtags on one platform ($0.05)
Top TikTok hashtags
# YouTube and Instagram: /v1/youtube/hashtags and /v1/instagram/hashtags
tiktok = requests.get(
'https://api.virlo.ai/v1/tiktok/hashtags',
headers=headers,
params={'start_date': start, 'end_date': end, 'limit': 10, 'order_by': 'views', 'sort': 'desc'}
).json()['data']
for tag in tiktok[:3]:
print(f"#{tag['hashtag']}: {tag['count']:,} videos, {tag['total_views']:,} views")
# Example output (videos posted Aug 25 to Sep 23, 2026):
# #fyp: 31,049 videos, 5,162,705,739 views
# #viral: 9,971 videos, 1,693,054,907 views
# #funny: 4,276 videos, 1,242,478,023 views
For a hashtag's videos, use a hashtag lookup ($0.50 to $2.50).
Research in another language or country
Research a niche in any language, then narrow results to one country.
- Cost
- $0.50, charged when you create the agent ($1.50 with Data Intelligence). Country filters are free.
- How long
- The same as a Full niche analysis.
- Set
english_only: falsewhen you create the agent, or it keeps only English. Write the name, intent, and keywords in your language; Virlo builds its search terms in that language. English may still appear (there's no language filter). regionwhen you read results: a two-letter code likeMX, any case.Mexicoreturns no results, not an error.
Country data is in beta. Items with no known country are left out of filtered results. TikTok slideshows (swipeable photo posts) almost always have one; Instagram videos rarely do.
1. Create an all-languages agent ($0.50)
Create agent
curl -X POST https://api.virlo.ai/v1/agents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"is_recurring": false,
"intent": "Investigar el contenido viral de fútbol en Latinoamérica",
"name": "Fútbol LATAM",
"keywords": ["goles de fútbol", "jugadas de fútbol", "resumen de partido"],
"platforms": ["tiktok", "instagram"],
"english_only": false
}'
2. Wait, then filter by country (free)
Videos carry the country as upload_region, slideshows as region; both are null when unknown.
Filter by region
# Videos uploaded from Mexico
curl -G https://api.virlo.ai/v1/agents/{agent_id}/videos \
-H "Authorization: Bearer YOUR_API_KEY" \
-d region=MX \
-d order_by=views \
-d sort=desc \
-d limit=50
# Slideshows uploaded from Argentina
curl -G https://api.virlo.ai/v1/agents/{agent_id}/slideshows \
-H "Authorization: Bearer YOUR_API_KEY" \
-d region=AR \
-d limit=50
