Tutorial

How to Track YouTube Impression Decay with a Search API

Track how YouTube videos drop in search rankings over time using a search API. Build an impression decay tracker without YouTube Analytics access.

YouTube impressions decay after publish: videos peak in search visibility within days, then gradually drop as newer content competes. Tracking this decay helps creators understand their content's shelf life. This tutorial tracks search position over time using daily API queries instead of relying on YouTube Studio (which only shows your own videos).

Prerequisites

  • Python 3.8+
  • A Scavio API key
  • Video URLs or keywords to track

Walkthrough

Step 1: Track search position for a keyword

Query YouTube search daily and record where your video ranks.

Python
import requests, os, json
from datetime import date

H = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def track_position(keyword: str, target_channel: str) -> dict:
    resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'youtube', 'query': keyword}, timeout=10)
    results = resp.json().get('organic', [])
    
    for i, r in enumerate(results):
        if target_channel.lower() in r.get('channel', '').lower():
            return {'keyword': keyword, 'position': i + 1, 'date': date.today().isoformat(),
                    'title': r.get('title', ''), 'views': r.get('views', '')}
    
    return {'keyword': keyword, 'position': None, 'date': date.today().isoformat(), 'not_found': True}

Step 2: Build a daily tracking loop

Track multiple keywords daily and store position history.

Python
from pathlib import Path

def daily_rank_track(keywords: list, channel: str) -> dict:
    history_file = Path('yt_rank_history.json')
    history = json.loads(history_file.read_text()) if history_file.exists() else {}
    
    today = date.today().isoformat()
    today_data = []
    
    for kw in keywords:
        position = track_position(kw, channel)
        today_data.append(position)
    
    history[today] = today_data
    history_file.write_text(json.dumps(history, indent=2))
    
    return {'date': today, 'tracked': len(keywords), 'found': sum(1 for d in today_data if d.get('position')),
            'positions': today_data}

Step 3: Calculate decay rate

Analyze position history to compute impression decay curves.

Python
def calculate_decay(history: dict, keyword: str) -> dict:
    positions = []
    for day, data in sorted(history.items()):
        for entry in data:
            if entry.get('keyword') == keyword and entry.get('position'):
                positions.append({'date': day, 'position': entry['position']})
    
    if len(positions) < 2:
        return {'keyword': keyword, 'insufficient_data': True}
    
    first_pos = positions[0]['position']
    last_pos = positions[-1]['position']
    days_tracked = len(positions)
    
    decay_rate = (last_pos - first_pos) / days_tracked if days_tracked > 0 else 0
    
    return {
        'keyword': keyword,
        'first_position': first_pos,
        'current_position': last_pos,
        'days_tracked': days_tracked,
        'decay_rate_per_day': round(decay_rate, 2),
        'positions_lost': last_pos - first_pos,
        'trend': 'declining' if decay_rate > 0.1 else 'stable' if abs(decay_rate) < 0.1 else 'improving',
    }

Step 4: Generate decay report

Produce a summary report of which content is decaying fastest.

Python
def decay_report(history_file: str = 'yt_rank_history.json') -> dict:
    history = json.loads(Path(history_file).read_text())
    keywords = set()
    for day_data in history.values():
        for entry in day_data:
            if entry.get('keyword'):
                keywords.add(entry['keyword'])
    
    decays = [calculate_decay(history, kw) for kw in keywords]
    decays = [d for d in decays if not d.get('insufficient_data')]
    decays.sort(key=lambda d: d.get('decay_rate_per_day', 0), reverse=True)
    
    return {
        'total_keywords': len(decays),
        'fastest_decaying': decays[:3],
        'most_stable': [d for d in decays if d.get('trend') == 'stable'],
        'improving': [d for d in decays if d.get('trend') == 'improving'],
    }

Python Example

Python
import requests, os, json
from datetime import date

def track_yt_rank(keyword, channel):
    r = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'},
        json={'platform': 'youtube', 'query': keyword}).json()
    for i, v in enumerate(r.get('organic',[])):
        if channel.lower() in v.get('channel','').lower():
            return i + 1
    return None

JavaScript Example

JavaScript
async function trackYTRank(keyword, channel) {
  const r = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
    body: JSON.stringify({platform: 'youtube', query: keyword})
  });
  const results = (await r.json()).organic || [];
  const idx = results.findIndex(v => v.channel?.toLowerCase().includes(channel.toLowerCase()));
  return idx >= 0 ? idx + 1 : null;
}

Expected Output

JSON
A YouTube impression decay tracker that monitors search position daily and calculates decay rates per keyword, identifying content that needs refreshing.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+. A Scavio API key. Video URLs or keywords to track. A Scavio API key gives you 500 free credits per month.

Yes. The free tier includes 500 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Track how YouTube videos drop in search rankings over time using a search API. Build an impression decay tracker without YouTube Analytics access.