# Build a YouTube Influencer Finder with Explainable Scoring in Python

A **YouTube influencer finder** should not rank creators by subscriber count alone. A useful result explains why a channel fits the niche, whether it still publishes, how recent videos perform, and which business-contact route the creator made public.

This guide builds that reviewable workflow in Python. The search starts from a niche rather than a list of channel URLs, returns one row per channel, and exposes both an `opportunityScore` and the evidence behind it.

## Start with the decision you need to make

Imagine you sell a B2B automation product. A channel with 200,000 subscribers looks attractive until you discover that it has not uploaded in six months. A smaller channel may publish every week, reach 8,000 viewers per recent video, cover the exact niche, and list a public partnership email.

Subscriber count is one signal. It is not a prospecting decision.

A practical creator shortlist needs at least these dimensions:

- niche fit;
- target language and geography;
- recent activity;
- publishing cadence;
- recent median views;
- engagement when public counts make it calculable;
- public business-contact availability and provenance.

The final score should remain inspectable. If a metric is unavailable, the system should say so instead of silently turning the missing value into zero.

## Run a bounded creator search

Install the Apify client:

```bash
pip install apify-client
```

Load the API token from an environment variable. Do not paste it into the script or commit it to Git.

```bash
export APIFY_API_TOKEN="your-token-from-the-apify-console"
```

The token value above is a shell example, not a credential. Retrieve the real value from your own Apify integrations page and keep it private.

Now run a small search:

```python
import os

from apify_client import ApifyClient


client = ApifyClient(os.environ["APIFY_API_TOKEN"])

run_input = {
    "preset": "qualified_shortlist",
    "niches": ["AI automation", "B2B SaaS"],
    "languages": ["en"],
    "countries": ["US", "CA", "GB"],
    "worldwideLanguageMode": False,
    "minSubscribers": 5_000,
    "maxSubscribers": 250_000,
    "minVideosPerMonth": 1,
    "lastUploadWithinDays": 60,
    "minRecentMedianViews": 1_000,
    "contentFormats": ["long-form", "Shorts"],
    "requirePublicBusinessContact": False,
    "maxChannels": 10,
    "videosAnalyzedPerChannel": 10,
    "maximumSearchCalls": 12,
}

run = client.actor("kazkn/youtube-creator-lead-finder").call(
    run_input=run_input,
)

creators = client.dataset(run["defaultDatasetId"]).list_items().items
```

The limits matter. Multi-niche, multi-language, and multi-country discovery can expand quickly. Start with a small result count and search budget, inspect the output, then widen one dimension at a time.

## Inspect the ranking instead of trusting it

Print the score together with the reasons and warnings:

```python
import json


for creator in creators:
    review = {
        "channelName": creator.get("channelName"),
        "channelUrl": creator.get("channelUrl"),
        "lastUploadAt": creator.get("lastUploadAt"),
        "estimatedVideosPerMonth": creator.get("estimatedVideosPerMonth"),
        "recentMedianViews": creator.get("recentMedianViews"),
        "publicBusinessEmail": creator.get("publicBusinessEmail"),
        "contactSourceUrl": creator.get("contactSourceUrl"),
        "opportunityScore": creator.get("opportunityScore"),
        "opportunityReasons": creator.get("opportunityReasons", []),
        "warnings": creator.get("warnings", []),
    }
    print(json.dumps(review, ensure_ascii=False, indent=2))
```

This is the difference between a ranking and a black box. The score helps order the review queue; the surrounding fields help decide whether the ranking makes sense for the campaign.

## What the score measures

The current scoring model uses seven components:

| Component | Maximum weight | Evidence used |
|---|---:|---|
| Niche fit | 25 | Overlap between requested and detected niches |
| Language and geography | 15 | Primary language plus declared or inferred geography |
| Recent activity | 15 | Most recent sampled upload against the requested limit |
| Publishing cadence | 10 | Estimated videos per month against the requested range |
| Recent performance | 15 | Recent median views against the requested range |
| Engagement | 10 | Calculable public engagement against the requested minimum |
| Public contact | 10 | Public contact evidence with source provenance |

Known components are scored against their weight. Unknown components stay unknown. The final value is produced only when at least 70% of the total component weight has usable evidence, then the earned points are rescaled across that known evidence.

That rule prevents two common mistakes:

1. treating a hidden metric as a failed metric;
2. presenting a precise score when too little evidence exists.

When coverage is insufficient, `opportunityScore` remains `null`. The warnings and component evidence still show what is missing.

## Why recent median views beat one viral video

Average views can be distorted by a single breakout upload. Median views are less sensitive to that outlier and usually provide a better first-pass picture of a channel's recent baseline.

That does not make the median perfect. The value depends on the bounded video sample, the content mix, seasonality, and the age of each upload. Keep `videosAnalyzedPerChannel` visible in the input and compare the median with:

- the last upload date;
- videos published in the last 30 and 90 days;
- the estimated monthly cadence;
- the Shorts, long-form, and live ratios;
- warnings about unavailable public metrics.

The goal is not to manufacture certainty. It is to make the shortlist cheaper to review without hiding uncertainty.

## Keep declared and inferred geography separate

Search region, channel country, and creator location are not interchangeable.

When YouTube exposes a declared country, store it as `declaredCountry`. When public signals support only an inference, keep those values in `inferredCountries` with `countryConfidence`. Never overwrite a declared field with a guess.

The same discipline applies to language. A discovery query can guide the search, but it does not prove the creator's primary language. Keep `primaryLanguage`, `detectedLanguages`, and `languageConfidence` visible.

If the campaign targets French-speaking creators worldwide, use:

```python
run_input = {
    "preset": "qualified_shortlist",
    "niches": ["AI agents"],
    "languages": ["fr"],
    "countries": [],
    "worldwideLanguageMode": True,
    "maxChannels": 10,
    "videosAnalyzedPerChannel": 10,
    "maximumSearchCalls": 12,
}
```

This searches by language without pretending every result is located in France.

## Treat public contacts as evidence, not enrichment

A creator lead is more useful when the output preserves where a contact came from.

For each accessible public contact, keep:

- the contact type and value;
- the exact source URL;
- the collection timestamp;
- the public status;
- a confidence level when relevant.

The YouTube Data API does not expose YouTube's protected business-email field. The workflow used here extracts only professional addresses and linked profiles that the creator explicitly publishes in accessible public channel text. It does not guess email patterns, bypass CAPTCHA, sign in, or enrich private addresses.

A missing contact is therefore an honest result. Check `warnings` before deciding whether to exclude the channel or review another public route manually.

## Export the shortlist for review

Each qualified creator is written as one Dataset item, deduplicated by `channelId` inside the run. You can export the result to CSV, JSON, or Excel from Apify, or send the rows into a spreadsheet or CRM through the API.

Keep human review between discovery and outreach. The Dataset prepares research evidence; it does not decide whether a message is appropriate for a specific creator.

## Try the workflow

The public [Active YouTube Influencer Discovery Tool](https://apify.com/kazkn/youtube-creator-lead-finder/examples/active-youtube-influencer-discovery-tool?utm_source=hashnode&utm_medium=organic_content&utm_campaign=youtube_creator_finder_seo_20260826&utm_content=explainable_scoring_task) opens with a bounded configuration you can edit.

For the complete input contract, limitations, output fields, and live pricing, see [YouTube Creator Lead Finder](https://apify.com/kazkn/youtube-creator-lead-finder?utm_source=hashnode&utm_medium=organic_content&utm_campaign=youtube_creator_finder_seo_20260826&utm_content=explainable_scoring_actor).

Use the score to order the queue. Use the reasons, source URLs, warnings, and recent-performance fields to decide who actually belongs in it.

