Satellite - Creator Trend Analysis

The creator lookup ships with an optional trend_analysis=true flag that runs an LLM over the creator's body of work and returns a trends block — the same shape Satellite sound lookups already use. You get a corpus summary plus per-trend time_windows[], a resurged flag, and a momentum metric, with evidence_video_ids that map back to the videos[] array in the same response.


When to use it

trend_analysis is meant for playbook extraction — answering "what does this creator actually do, and how has their pattern evolved?" Useful when:

  • You need to brief a team on a competitor or partner creator before a collab.
  • You want to spot eras a creator left behind and came back to (resurgences).
  • You need format/hook ideas grounded in evidence rather than vibes.
  • You're building automation that ingests creators as inputs and needs structured pattern signals.

If you only need stats, hashtags, outliers, or audience data, skip this flag — the base lookup already covers all of that and saves you $0.50.


Pricing & deep fetch

  • $0.50 base for the lookup itself.
  • + $0.50 surcharge when trend_analysis=true. Same feature key (satellite_trend_analysis) as sound trends, so the price stays consistent across satellite domains.
  • Stackable with the audience surcharge — audience_demographics, audience_geography, and trend_analysis can all ride on a single call.
  • When trend_analysis=true:
    • max_videos is floored to 100 (the cap). Higher signal = better trends.
    • The videos[] payload is implicitly included so evidence_video_ids can be resolved client-side without a second call.
  • Re-reads via GET /v1/satellite/runs/:run_id are free, forever. Trends are persisted with the run, so you can revisit a creator's analysis you ran six months ago without spending another credit.

Enabling trend_analysis

Request

GET
/v1/satellite/creator/:platform/:username?trend_analysis=true
curl -G https://api.virlo.ai/v1/satellite/creator/youtube/mkbhd \
  -H "Authorization: Bearer {token}" \
  -d trend_analysis=true

The MCP equivalent: pass trend_analysis: true to the lookup_creator tool.


When trend_analysis=true and the corpus has at least 10 videos, the completed response carries a trends object on the result:

{
  "data": {
    "status": "completed",
    "finalized": true,
    "result": {
      "username": "mkbhd",
      "platform": "youtube",
      "profile": { /* ... */ },
      "stats": { /* ... */ },
      "videos": [ /* 100 videos */ ],
      "trends": {
        "analyzed": true,
        "summary": "MKBHD's playbook centers on first-look hardware reviews shot in his signature studio aesthetic, anchored by quarterly retrospectives and a recurring podcast-style long-form column.",
        "status": "ok",
        "model_used": "google/gemini-2.5-flash",
        "cost_usd": 0.0123,
        "tokens_used": 18234,
        "trends": [
          {
            "name": "Quarterly smartphone retrospectives",
            "description": "A recurring 'X months later' reflection format where MKBHD revisits flagship phones to deliver a longitudinal verdict.",
            "tactics": ["Title leads with months elapsed", "Same studio b-roll signature", "Direct-to-camera open"],
            "confidence": 0.91,
            "video_count": 6,
            "evidence_video_ids": ["abc123", "def456", "ghi789", "..."],
            "time_windows": [
              {
                "start_date": "2025-08-12",
                "end_date": "2025-11-04",
                "video_count": 3,
                "total_views": 12400000,
                "total_likes": 410000,
                "total_comments": 28000,
                "total_shares": 4100,
                "avg_views": 4133333,
                "description": "Pre-iPhone-17 retrospective wave"
              },
              {
                "start_date": "2026-02-09",
                "end_date": "2026-04-21",
                "video_count": 3,
                "total_views": 19800000,
                "total_likes": 620000,
                "total_comments": 41000,
                "total_shares": 7200,
                "avg_views": 6600000,
                "description": "Resurgence with the Galaxy S26 and Pixel 11 comparison cycle"
              }
            ],
            "resurged": true,
            "momentum": "stronger"
          }
        ]
      },
      "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "credits_charged": 100
    }
  }
}

trends top-level fields

  • Name
    analyzed
    Type
    boolean
    Description
    Always true when trend_analysis=true was on the request.
  • Name
    summary
    Type
    string
    Description
    1-2 sentence read of the creator's overall playbook across the analyzed videos.
  • Name
    status
    Type
    string
    Description
    ok when analysis ran cleanly. insufficient_corpus when fewer than 10 videos were available (no charge for the surcharge — see below). skipped when trend_analysis was not set.
  • Name
    model_used
    Type
    string | null
    Description
    The LLM that produced the trends (Gemini 2.5 Flash by default, Claude Haiku 4.5 as automatic fallback).
  • Name
    cost_usd
    Type
    number | null
    Description
    LLM cost in USD. Operational diagnostic.
  • Name
    tokens_used
    Type
    number | null
    Description
    Total prompt + completion tokens.
  • Name
    trends
    Type
    array
    Description
    The deduplicated trend list. May be empty when the model couldn't find coherent patterns.

Per-trend fields

  • Name
    name
    Type
    string
    Description
    Short, replicable label (e.g. "Quarterly smartphone retrospectives").
  • Name
    description
    Type
    string
    Description
    1-2 sentence explanation of the format, hook, or pillar.
  • Name
    tactics
    Type
    string[]
    Description
    0-5 concrete tactics the model observed (e.g. "Title leads with months elapsed").
  • Name
    confidence
    Type
    number
    Description
    0-1, how strongly the evidence supports this trend.
  • Name
    video_count
    Type
    integer
    Description
    Total evidence videos across all windows.
  • Name
    evidence_video_ids
    Type
    string[]
    Description
    Platform external IDs. These map back to videos[] in the same response — look up the matching ID to get the title, views, URL, etc.
  • Name
    time_windows
    Type
    object[]
    Description
    One window per coherent stretch of evidence. Computed mechanically from real publishDates after the LLM picks IDs — date hallucination is impossible.
  • Name
    resurged
    Type
    boolean
    Description
    true iff there are ≥2 disjoint windows (e.g. a format the creator did, dropped, then revived).
  • Name
    momentum
    Type
    string | null
    Description
    stronger, weaker, or similar comparing the latest window's avg_views to the prior window (±15% deadband). null for single-window trends.

Insufficient corpus

When the creator has fewer than 10 fetched videos, we skip the LLM entirely and emit:

{
  "trends": {
    "analyzed": true,
    "summary": "",
    "trends": [],
    "status": "insufficient_corpus",
    "model_used": null,
    "cost_usd": null,
    "tokens_used": null
  }
}

This is intentional: small corpora produce noisy, low-confidence trends. The base lookup still charges $0.50 and the trend surcharge is still billed (we already paid for the deep fetch and pipeline setup), but the result is unambiguous so you can decide whether to retry on a different creator.


Worked example

Resolving an evidence video from inside a trend is a simple .find() on the same response:

const result = poll.data.result
const trend = result.trends.trends[0]

const evidenceVideos = trend.evidence_video_ids
  .map((id) => result.videos.find((v) => v.id === id))
  .filter(Boolean)

console.log(`Trend "${trend.name}" — ${trend.resurged ? 'resurged' : 'continuous'}`)
console.log(`Momentum: ${trend.momentum ?? 'n/a (single window)'}`)
for (const window of trend.time_windows) {
  console.log(`  ${window.start_date} -> ${window.end_date}: ${window.video_count} videos, ${window.avg_views.toLocaleString()} avg views — ${window.description}`)
}
for (const v of evidenceVideos) {
  console.log(`  - ${v.publishDate?.slice?.(0, 10) ?? v.publishDate} | ${v.views.toLocaleString()} views | ${v.url}`)
}

Durable runs

Every creator lookup — with or without trend_analysis — yields a run_id you can re-read for free via:

  • GET /v1/satellite/runs/:run_id — full persisted result, including the trends block when it was paid for.
  • GET /v1/satellite/runs?type=creator_lookup — list your team's creator lookups.
  • GET /v1/satellite/runs/:run_id/videos — paginated videos[] (useful when trend_analysis=true returns up to 100 videos).

See Re-read Past Runs → for the full reference. To get fresh data, start a new lookup — that will cost credits again.

Was this page helpful?