Build 1of10

KINDAreplaces $29/mosaves $348/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A research tool that finds videos performing far above their own channel's normal range, where the engineering is entirely shaped by an API quota that makes search unaffordable and cheap list operations the only viable path.

estimated effort multi-daythe files for this build are in the project pack

CollectionPlaylist and video list operations, never searchCachingAggressive local storage of everything fetchedStatisticsComparison against a channel's own distribution, age adjustedSchedulingA daily budget spent deliberately across tracked channelsRuntimePython 3.12 with SQLite

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs collection and the statistics.

    Get it python.org or your package manager, then a virtual environment.

    Verify python3 --version prints 3.12 or higher

  2. free within the allowance; extensions require an audit

    Why The whole architecture follows from the allowance, and building before reading the quota costs a rewrite rather than a tuning pass.

    Get it Create a project, enable the API, and read the quota cost table before writing the fetch layer. open ↗

    Verify A list request and a search request are both issued and their unit costs confirmed against the documentation

  3. have readyfree

    Why The build is designed around tracking a chosen set rather than searching, so the set has to exist before the collection schedule makes sense.

    Get it List channels in your area of interest, including at least one with very few uploads and one with several hundred.

    Verify Fifty channel identifiers are recorded including a small and a large catalogue

  4. have readyfree, and it takes two weeks

    Why Velocity, which is the difference between a genuinely interesting video and an old one, requires a series rather than a single reading.

    Get it Run collection daily for two weeks before evaluating the outlier logic.

    Verify At least fourteen snapshots exist per tracked video

  5. decidefree

    Why A multiple of the median, a percentile and an age-adjusted percentile give different answers, and picking one afterwards means picking whichever produces the results you liked.

    Get it Decide the definition and the minimum catalogue size before running it against real channels.

    Verify A written definition exists including the minimum catalogue size

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- channels(id, external_id, title, subscriber_count, tracked_since, uploads_playlist_id)
- videos(id, channel_id, external_id, title, published_at, duration_seconds, first_seen_at)
- snapshots(video_id, at, views, likes, comments) · a series, because velocity matters more than a total
- baselines(channel_id, computed_at, median_views, quantiles_json, age_curve_json) · the channel's own distribution
- outliers(video_id, computed_at, ratio_to_median, age_adjusted_ratio, percentile, confidence)
- quota_ledger(day, operation, units, cumulative) · what the allowance was spent on
- A snapshot series is kept rather than only the latest count, because a video reaching a million views in a week and one reaching it over three years are entirely different findings.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DB_PATHrequired./research.dbChannels, videos and the snapshot series.
YOUTUBE_API_KEYsecretrequireda project API keySubject to the daily allowance, which shapes the whole build.
DAILY_QUOTA_UNITSrequired10000The allowance. Requests are budgeted against it before being issued.
ALLOW_SEARCHrequiredfalseA search costs a hundred units. Rationed or unavailable, never routine.
MIN_CATALOGUE_FOR_BASELINErequired30Below this no baseline is computed, because it would describe nothing.
SNAPSHOT_RETENTION_DAYSrequired730The series is the data. Keep it far longer than the latest reading.

The build, in order

  1. Spending the allowance deliberately

    Every request is budgeted and the day's allowance is never exhausted by accident.

    1. Refusing is cheaper than a quota error halfway through a run.

      Files src/quota.pytests/test_quota.py

    2. One unit against a hundred. This decides what the product can be.

      Files src/fetch.py

    3. So your accounting matches theirs rather than diverging quietly.

      Files src/quota.py

    done when · tick each as it passes
    watch out
    • A single loop calling search for each of a hundred channels exhausts the entire daily allowance in one run, and the failure arrives as a quota error partway through with half the data collected. Budget before the call, record the cost, and make search a rationed operation rather than a normal one.
  2. Tracking channels cheaply

    A hundred channels update daily inside the free allowance.

    1. One unit per page rather than a hundred per search.

      Files src/channels.py

    2. Fifty video identifiers per call rather than fifty calls.

      Files src/stats.py

    3. Their counts barely move and the allowance is better spent elsewhere.

      Files src/schedule.py

    done when · tick each as it passes
    watch out
    • Refetching a channel's entire history every day wastes the allowance on videos whose counts barely move, and leaves nothing for the new uploads that are the point. Fetch new uploads fully, sample older videos on a decaying schedule, and record when each was last seen.
  3. A baseline that is not the mean

    Each channel is compared against its own distribution rather than an average.

    1. One viral video drags a mean above the whole catalogue.

      Files src/baseline.pytests/test_baseline.py

    2. A week-old video has not had the time an old one has.

      Files src/age.py

    3. A baseline from six videos describes nothing.

      Files src/baseline.py

    done when · tick each as it passes
    watch out
    • Comparing against a channel's mean views makes almost everything look below average, because one viral video drags the mean above nearly the whole catalogue. Use the median and quantiles, which describe where a video actually sits among its siblings.
  4. Outliers with a confidence attached

    A flagged video is genuinely unusual for that channel rather than merely large.

    1. Percentile, not a bare multiple of the median.

      Files src/outliers.py

    2. Catalogue size and data recency. Fifteen videos is not four hundred.

      Files src/outliers.py

    3. A million views in a week is a different finding from over three years.

      Files src/velocity.py

    done when · tick each as it passes
    watch out
    • Reporting a ratio against the median without saying how many videos the median came from treats a channel with four hundred uploads and one with fifteen as equally reliable, which they are not. Attach a confidence derived from catalogue size and how recently the data was collected.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more social media.