<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Greta Holt</title>
    <description>The latest articles on DEV Community by Greta Holt (@gretaholt).</description>
    <link>https://dev.to/gretaholt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4136714%2F433dcdc1-3254-4b04-b87d-d246fb7c4965.png</url>
      <title>DEV Community: Greta Holt</title>
      <link>https://dev.to/gretaholt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gretaholt"/>
    <language>en</language>
    <item>
      <title>Virlo in 2026: What It Is, What the API Costs, and a Python Starter</title>
      <dc:creator>Greta Holt</dc:creator>
      <pubDate>Wed, 07 Oct 2026 03:12:42 +0000</pubDate>
      <link>https://dev.to/gretaholt/virlo-in-2026-what-it-is-what-the-api-costs-and-a-python-starter-9pd</link>
      <guid>https://dev.to/gretaholt/virlo-in-2026-what-it-is-what-the-api-costs-and-a-python-starter-9pd</guid>
      <description>&lt;p&gt;A few months ago someone left a comment under a popular Virlo tutorial asking which part of Virlo the author had used: "comet/orbit/etc?" Nobody answered. If you go looking for Comet or Orbit today you'll find both labeled deprecated in Virlo's docs, which says a lot about how fast this product has moved since January.&lt;/p&gt;

&lt;p&gt;I do data plumbing for a couple of small creator agencies. Virlo comes up in almost every planning call now, usually as "can we just pull this from Virlo?", so I spent some time reading the current docs end to end and wiring it into a scratch project. This is the write-up I wish I'd had: what Virlo is in October 2026, how the API bills you, a Python starter that tracks its own spend, and where I reach for something else.&lt;/p&gt;

&lt;p&gt;Quick disclosure on that last part: Virlo is a discovery tool, and for the narrower job of watching what one named competitor posts on TikTok each week, I use &lt;a href="https://reachara.com/?utm_source=devto&amp;amp;utm_medium=ugc&amp;amp;utm_campaign=gretaholt&amp;amp;utm_content=virlo-intro" rel="noopener noreferrer"&gt;Reachara&lt;/a&gt;. More on that split near the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is Virlo, exactly?
&lt;/h2&gt;

&lt;p&gt;Virlo's homepage calls it social listening for TikTok, Reels and Shorts. In practice it's a large database of short-form videos (the homepage says 14.7M+ outlier videos) plus an AI layer that explains why they worked.&lt;/p&gt;

&lt;p&gt;The core idea is the &lt;strong&gt;outlier&lt;/strong&gt;: a video that beat its own creator's usual views. Their example is a creator who normally gets about 2.5K views and suddenly gets 2.8M. That video ranks above a big account having a normal week. It's the right instinct, because raw view counts mostly tell you who is already famous.&lt;/p&gt;

&lt;p&gt;On top of that sit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content research agents.&lt;/strong&gt; You describe a niche in a sentence, the agent writes search terms, and it pulls matching videos across TikTok, Instagram and YouTube, once or on a schedule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breakdowns.&lt;/strong&gt; Hook, format and angle per video, plus a copilot called Vee that answers questions like "best hooks in my niche this week".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outputs.&lt;/strong&gt; Scripts, creative briefs, and reports exported as PDF, Excel, CSV or JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The site also lists competitor tracking, Meta Ads Library research and audience insights read from comments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The app and the API are separate products
&lt;/h2&gt;

&lt;p&gt;This tripped up two people I work with, so it's worth stating plainly. The Virlo &lt;strong&gt;app&lt;/strong&gt; is a subscription; the homepage lists Starter at $49/month (2,000 credits), Pro at $199/month (12,000 credits) and Enterprise from $499/month, each with a 7-day $0 trial. The &lt;strong&gt;Virlo API&lt;/strong&gt; is separate, and you don't need an app subscription to use it. You add funds to a prepaid balance that never expires and pay per successful request.&lt;/p&gt;

&lt;p&gt;The API lives at &lt;code&gt;https://api.virlo.ai/v1&lt;/code&gt; and authenticates with a bearer key that starts with &lt;code&gt;virlo_tkn_&lt;/code&gt;. You need a balance before you can generate a key, and the key is shown once.&lt;/p&gt;

&lt;p&gt;Here's what the calls I care about cost, from the billing docs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;What it returns&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/account/balance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your balance&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/trends/digest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Today's 15 to 20 trending topics for a region&lt;/td&gt;
&lt;td&gt;$0.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/hashtags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Top hashtags for a date range (max 90 days)&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/hashtags/:hashtag/performance&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One hashtag's video count, views, likes, comments&lt;/td&gt;
&lt;td&gt;$0.05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/videos/digest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Most-viewed videos of the last 48 hours&lt;/td&gt;
&lt;td&gt;$0.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /v1/satellite/video-outlier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Did this one video beat its creator's baseline?&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;POST /v1/agents&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A content research agent run&lt;/td&gt;
&lt;td&gt;$0.50, or $1.50 with Data Intelligence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Errors are free, and re-reading results you already paid for is free. Every successful response carries an &lt;code&gt;X-Cost&lt;/code&gt; header with the exact charge in dollars, which is the single most useful thing in the whole API for anyone who has to explain a bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened to Orbit and Comet?
&lt;/h2&gt;

&lt;p&gt;They were Virlo's older agent endpoints: Orbit for one-time research, Comet for recurring. Both now sit under "Legacy (deprecated)" in the docs, which point you to &lt;code&gt;POST /v1/agents&lt;/code&gt; instead. One endpoint now covers both cases with an &lt;code&gt;is_recurring&lt;/code&gt; flag. A one-time agent is charged when you create it; a recurring agent is free to create and charged $0.50 after each run. The rate-limit docs add that the old agent endpoints go as low as 2 requests per minute, while the replacement has the normal limit. If an older tutorial or your own code still calls &lt;code&gt;/v1/orbit&lt;/code&gt; or &lt;code&gt;/v1/comet&lt;/code&gt;, migrate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Python starter that watches its own spend
&lt;/h2&gt;

&lt;p&gt;This is the script I start every Virlo experiment from. It checks the balance (free), pulls today's US trends (25 cents), checks one hashtag (5 cents), handles &lt;code&gt;429&lt;/code&gt;s the way the docs describe, and adds up &lt;code&gt;X-Cost&lt;/code&gt; so I know what the run cost.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.virlo.ai/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VIRLO_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;spent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;GET a Virlo endpoint, honour Retry-After on 429, and tally X-Cost.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;spent&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retry-After&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# 402 = balance too low, 404 = hashtag has no videos
&lt;/span&gt;        &lt;span class="n"&gt;spent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Cost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;still rate limited on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/account/balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;balance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# free
&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/trends/digest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_exemplars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# $0.25
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;| local_date:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;local_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trends&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;momentum&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not measured yet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ranking&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;trend&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; [&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/hashtags/mealprep/performance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# $0.05, no '#' in the path
&lt;/span&gt;          &lt;span class="n"&gt;start_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-07-08&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-10-05&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hashtag&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; videos, avg &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;avg_views&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; views&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;this run cost $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;spent&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set &lt;code&gt;VIRLO_API_KEY&lt;/code&gt; in your environment and run it. Everything in the response lives under &lt;code&gt;data&lt;/code&gt;, field names are snake_case, and &lt;code&gt;momentum&lt;/code&gt; can be &lt;code&gt;null&lt;/code&gt; until Virlo has measured a trend, hence the &lt;code&gt;or {}&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Details that will bite you
&lt;/h2&gt;

&lt;p&gt;These are all in the docs, but scattered across pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The daily trend list rolls over at 7:00 New York time.&lt;/strong&gt; Call before that and you get yesterday's list, even if &lt;code&gt;title&lt;/code&gt; says today. Check &lt;code&gt;local_date&lt;/code&gt;, not &lt;code&gt;title&lt;/code&gt;. Trends are added again at 13:00 and 19:00.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashtag ranges max out at 90 days&lt;/strong&gt;, and stats start on 1 June 2024. A 91-day range returns a &lt;code&gt;400&lt;/code&gt; with &lt;code&gt;invalid_date_range&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never put &lt;code&gt;#&lt;/code&gt; in the path.&lt;/strong&gt; A raw &lt;code&gt;#&lt;/code&gt; breaks the URL; use the bare tag or &lt;code&gt;%23&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's no &lt;code&gt;platform&lt;/code&gt; parameter on hashtags.&lt;/strong&gt; For one platform, call &lt;code&gt;/v1/tiktok/hashtags&lt;/code&gt;, &lt;code&gt;/v1/youtube/hashtags&lt;/code&gt; or &lt;code&gt;/v1/instagram/hashtags&lt;/code&gt;. Passing &lt;code&gt;platform&lt;/code&gt; gets you a &lt;code&gt;400&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top-hashtag lists aren't niche-specific&lt;/strong&gt;, so &lt;code&gt;fyp&lt;/code&gt; and &lt;code&gt;shorts&lt;/code&gt; lead. For niche hashtags the docs point you to a content research agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;count&lt;/code&gt; is Virlo's count, not TikTok's.&lt;/strong&gt; It's how many videos in Virlo's data used the tag in your dates. Views freeze about a week after posting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The outlier check charges every time.&lt;/strong&gt; Creator, sound and hashtag lookups are served free from cache for 6 hours; the video outlier check isn't, and it's billed even if the check fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits are per key, per endpoint&lt;/strong&gt;, resetting on the clock in UTC. Hashtag stats and trends allow 50 requests a minute; creator lookups and outlier checks only 5.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AI-assistant workflows there's also an MCP server, which the developer site says exposes 46 tools to clients like Claude, Cursor and VS Code. I haven't moved anything to it yet, but it's the obvious next step for anyone already living in an agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I stop using Virlo
&lt;/h2&gt;

&lt;p&gt;Virlo is excellent at the question "what's working in this niche right now?" It's less suited, at least for my clients, to "what did our competitor post on TikTok this week, and did any of it travel?" You can approximate it with tracking and agents, but you end up writing the glue: deciding which hashtags the competitor actually lives under, re-running, diffing.&lt;/p&gt;

&lt;p&gt;That narrower job is what Reachara is built for. You name a competitor by website, @handle or hashtag; it infers up to 12 TikTok hashtags their videos run under, sweeps them on a schedule (weekly on the entry plan, daily above it), and ranks posts by plays divided by the posting account's followers. It's TikTok-only, it starts at $99/month for two monitored competitors with no free tier, and it doesn't do audience demographics or ad spend, which it says up front. For broad discovery, Virlo. For a fixed watchlist of rivals on TikTok, Reachara.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Virlo free?&lt;/strong&gt;&lt;br&gt;
The app has a 7-day $0 trial, then starts at $49/month. The API has no subscription; you prepay a balance and most requests cost $0.50 or less. The balance check and re-reads of paid results are free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Virlo have an API?&lt;/strong&gt;&lt;br&gt;
Yes, at &lt;code&gt;https://api.virlo.ai/v1&lt;/code&gt;, with 25+ endpoints for trends, creators, hashtags, sounds, hooks and research agents, plus webhooks and an MCP server. Docs are at dev.virlo.ai.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What platforms does Virlo cover?&lt;/strong&gt;&lt;br&gt;
TikTok, YouTube Shorts and Instagram Reels, with the Meta Ad Library available inside research agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What replaced Virlo Orbit and Comet?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;POST /v1/agents&lt;/code&gt;. Set &lt;code&gt;is_recurring&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; for what Orbit did and &lt;code&gt;true&lt;/code&gt; for what Comet did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;If you're evaluating Virlo for a team, start with the balance check and one trends call; the whole quickstart costs a quarter. Keep the &lt;a href="https://dev.virlo.ai/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; open, because the pricing table and rate limits are spelled out there more precisely than anywhere else. And if the real ask turns out to be "keep an eye on these three competitors on TikTok," look at &lt;a href="https://reachara.com/?utm_source=devto&amp;amp;utm_medium=ugc&amp;amp;utm_campaign=gretaholt&amp;amp;utm_content=virlo-outro" rel="noopener noreferrer"&gt;Reachara&lt;/a&gt; before you build that pipeline yourself.&lt;/p&gt;

</description>
      <category>api</category>
      <category>python</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
