# YouTube Monetization Checker for Scripts & Titles (`ultimatemc/youtube-script-monetization-checker`) Actor

Check YouTube titles, descriptions, tags and scripts for words that can get a video demonetized, before you upload. For creators, editors and AI script tools. Flags profanity, violence, adult, drugs, firearms and sensitive topics, with likely ad state (yellow or red $), quote, timestamp and a fix.

- **URL**: https://apify.com/ultimatemc/youtube-script-monetization-checker.md
- **Developed by:** [Ultimate Foresight Inc](https://apify.com/ultimatemc) (community)
- **Categories:** Videos, For creators, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**YouTube Monetization Checker** scans your video **titles, descriptions, tags, thumbnail text and full scripts or transcripts** for wording that often leads to **limited ads (yellow $) or no ads (red $)** under YouTube's advertiser-friendly content guidelines, before you upload. For every video you get a likely ad state, the guideline category, the exact words flagged, where they appear (title, opening seconds or body, with a timestamp for timed transcripts) and a rewrite hint. Click **Start** with the prefilled example to see a result in a few seconds.

> **A pre-check, not a YouTube decision.** This is a fixed, rule-based text checker built from YouTube's public [advertiser-friendly content guidelines](https://support.google.com/youtube/answer/6162278). A flag means "review this"; a clean result does **not** guarantee full monetization. YouTube also judges the picture, audio, thumbnail image and overall context, which this tool can't see. Not affiliated with YouTube or Google.

### What does YouTube Monetization Checker do?

- ✅ Checks text against **24 rules** grouped by YouTube's own topic names (inappropriate language, violence, adult, shocking, harmful acts and misinformation, hateful and incendiary content, recreational drugs, firearms, controversial issues, sensitive events, enabling dishonest behavior, tobacco), plus **made-for-kids** checks
- ✅ **Placement-aware**, like YouTube: titles and thumbnail text are judged more strictly, and profanity in the **opening seconds** (default 30) is reported separately
- ✅ **Timestamps** for each flag when you pass a timed transcript (`[{"text", "start"}]`)
- ✅ **Context setting** (educational, news, documentary, music, comedy, gaming) softens the categories where YouTube says context matters
- ✅ Avoids common false-positive traps: "killer recipe", "Suicide Squad", "weed killer", "killer whale", "glue gun", "lean protein", "high scores", "photo shoot"
- ✅ Returns `riskLevel`, `adSuitabilityEstimate`, `categoriesFlagged`, and per issue `category`, `severity`, `field`, `placement`, `quote`, `timestamp`, `context`, `guidelineUrl` and `rewriteHint`
- ✅ Bulk: paste many videos, or point it at the dataset of a YouTube video or transcript scraper. Export as JSON, CSV or Excel

### Who is it for?

- 🎬 **YouTubers and video editors** checking a script or title before recording or uploading
- 🏢 **Agencies and multi-channel networks** that review many scripts per week
- 🤖 **AI script generators and content pipelines** that need an automated monetization gate
- 📚 **Channel auditors** checking a back catalog of transcripts for risky wording

### How to check a YouTube script for demonetization risk

1. Click **Try for free** or **Start**. The input is prefilled with two example videos.
2. Replace them with your own videos in **Videos**: a `title`, and optionally `description`, `tags`, `thumbnailText` and `script` (plain text or a timed transcript). For quick checks, use **Scripts** or **Titles** instead.
3. Set **Content context** (for example `educational` or `gaming`) and **Made for kids** if they apply.
4. Click **Start**. Each video becomes one row in the results table.
5. Download the results or fetch them through the API.

### Input example

This is the prefilled input:

```json
{
  "videos": [
    {
      "id": "v1",
      "title": "This F*CKING boss fight is INSANE",
      "description": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
      "tags": [
        "gaming",
        "boss fight"
      ],
      "script": "What the fuck. Okay okay, we go left here and grab the shield. This boss has three phases."
    },
    {
      "id": "v2",
      "title": "Killer sourdough recipe: dead simple, no knead",
      "description": "Shot on a phone in my kitchen. Hell yes, it works.",
      "script": "Today we make a killer loaf. Shoot, I forgot the salt. Let it rest overnight."
    }
  ]
}
```

With a timed transcript (gives exact timestamps) and a context:

```json
{
  "videos": [
    {
      "id": "ep12",
      "title": "My honest review",
      "script": [
        {
          "text": "welcome back everyone",
          "start": 0
        },
        {
          "text": "this part is where it gets crazy",
          "start": 95.2
        }
      ]
    }
  ],
  "contentContext": "gaming",
  "madeForKids": false,
  "openingSeconds": 30
}
```

From the dataset of a YouTube or transcript scraper (fields such as title, description, tags, transcript, captions and subtitles are detected automatically; `fieldMap` is optional):

```json
{
  "datasetId": "YOUR_TRANSCRIPT_SCRAPER_DATASET_ID",
  "fieldMap": {
    "title": "videoTitle",
    "script": "subtitlesText"
  },
  "contentContext": "educational"
}
```

### Output example

This is real output from the prefilled input above (run on 2026-10-21), not trimmed:

```json
[
  {
    "videoId": "v1",
    "url": null,
    "title": "This F*CKING boss fight is INSANE",
    "riskLevel": "high",
    "adSuitabilityEstimate": "likely no ads (red)",
    "issueCount": 3,
    "categoriesFlagged": [
      "Firearms-related content",
      "Inappropriate language"
    ],
    "issues": [
      {
        "ruleId": "firearm_sales_mods",
        "category": "Firearms-related content",
        "severity": "high",
        "field": "description",
        "placement": "body",
        "quote": "promo code SAVE10 at our gun",
        "occurrences": 1,
        "context": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
        "guidelineUrl": "https://support.google.com/youtube/answer/6162278",
        "rewriteHint": "Facilitating gun or ammo sales, modifications (bump stocks, auto conversions, 80% lowers, high-capacity magazines) or build instructions earns no ads. Reviews and range demos without sales links or mods are treated more leniently."
      },
      {
        "ruleId": "masked_profanity",
        "category": "Inappropriate language",
        "severity": "medium",
        "field": "title",
        "placement": "title/thumbnail",
        "quote": "F*CKING",
        "occurrences": 1,
        "context": "This F*CKING boss fight is INSANE",
        "guidelineUrl": "https://support.google.com/youtube/answer/6162278",
        "rewriteHint": "Abbreviated or obscured profanity in the video is generally fine, but a masked strong word in the title can still be treated as profanity. Consider a cleaner title."
      },
      {
        "ruleId": "strong_profanity",
        "category": "Inappropriate language",
        "severity": "medium",
        "field": "script",
        "placement": "opening",
        "quote": "fuck",
        "occurrences": 1,
        "context": "What the fuck. Okay okay, we go left here and grab the shield. ...",
        "guidelineUrl": "https://support.google.com/youtube/answer/6162278",
        "rewriteHint": "Strong profanity in the title/thumbnail or opening is a common reason for no or limited ads. Bleep or mute it in the video, keep it out of the title and first seconds, or swap in a milder word."
      }
    ],
    "contentContext": "general",
    "madeForKids": false,
    "scriptWordCount": 18,
    "disclaimer": "Automated text pre-check based on YouTube's public advertiser-friendly content guidelines. Flags are possible issues, not YouTube decisions; a clean result does not guarantee full monetization. YouTube also reviews the video, audio, thumbnail image and context, which this tool does not see."
  },
  {
    "videoId": "v2",
    "url": null,
    "title": "Killer sourdough recipe: dead simple, no knead",
    "riskLevel": "none found",
    "adSuitabilityEstimate": "no issues found (still not a guarantee)",
    "issueCount": 0,
    "categoriesFlagged": [],
    "issues": [],
    "contentContext": "general",
    "madeForKids": false,
    "scriptWordCount": 15,
    "disclaimer": "Automated text pre-check based on YouTube's public advertiser-friendly content guidelines. Flags are possible issues, not YouTube decisions; a clean result does not guarantee full monetization. YouTube also reviews the video, audio, thumbnail image and context, which this tool does not see."
  }
]
```

**How to read `riskLevel`:** `high` = commonly earns no ads (red $). `medium` = commonly earns limited ads (yellow $). `low` = usually fine, but review it. `none found` = no wording issue detected (still not a guarantee).

### How much does it cost to check YouTube videos?

This Actor uses **pay-per-event** pricing:

- **$0.02 per video** (one result row per video)
- a tiny Actor start fee of **$0.00005** per run
- plus the small Apify **platform usage** of the run, paid by you. For the prefilled 2-video example this was about **$0.0001** (256 MB, about 3 seconds).

So **100 videos cost about $2.00** and **1,000 videos about $20**, plus a few cents or less of platform usage. You pay only for videos actually checked. Apify lets you set a maximum cost per run so a large batch can never exceed your budget.

### Use it through the API, integrations or AI agents

- **API:** run it and get results in one call:
  `POST https://api.apify.com/v2/acts/ultimatemc~youtube-script-monetization-checker/run-sync-get-dataset-items` with your Apify token and the input JSON as the body. Client libraries for JavaScript and Python are on the **API** tab.
- **AI agents (MCP):** add `https://mcp.apify.com?tools=ultimatemc/youtube-script-monetization-checker` to Claude, Cursor, ChatGPT or any MCP client, and your agent can check a script or title for monetization risk before publishing as a tool. See [Apify MCP server](https://docs.apify.com/mcp).
- **Chain it after a scraper:** pass the `datasetId` of another Actor's run, or trigger this Actor with a webhook when the scraper finishes.
- **Automation:** schedule runs, trigger webhooks, or connect Make, Zapier, n8n, Google Sheets and other integrations from Apify Console.

### FAQ

#### Does a clean result guarantee my video will be fully monetized?

No. It means none of the rules matched the text. YouTube also reviews the video, audio, thumbnail image and context, and makes the final decision.

#### Does it watch or listen to my video?

No. It only reads the text you give it. To check spoken words, pass a script or a transcript (for example from a YouTube transcript scraper).

#### Does it use AI?

No. It's rule-based (keywords and patterns), so the same text always gets the same result, and every flag links to the guideline page. No text is sent to any outside service.

#### Which languages are supported?

English only.

#### How current are the rules?

They are our own paraphrased patterns written from YouTube's public guideline page, checked on 2026-10-21. YouTube changes its guidelines and enforcement, so always confirm on the linked page.

### Limitations

- Text only. It doesn't see images, video, audio, thumbnails or tone.
- English only, keyword-based. It can't fully understand sarcasm, quotes or negation (beyond fact-check wording such as "we debunk this myth").
- A news explainer about a violent event can still get a `medium` flag unless you set `contentContext` to `news`.
- Not legal advice, and not affiliated with or endorsed by YouTube or Google.

### Data and privacy

The checker makes no network calls. Your text is processed only during the run and saved only to your own Apify dataset.

### Other tools by Ultimate Foresight

- [Ad Copy Policy Checker for Meta, Google & TikTok](https://apify.com/ultimatemc/ad-copy-policy-checker): checks ad text against Facebook, Instagram, Google Ads and TikTok ad policies before you submit.
- [H-1B Visa Sponsor Checker & Score for Job Listings](https://apify.com/ultimatemc/h1b-visa-sponsor-score): adds Department of Labor H-1B sponsorship history and a 0-100 score to company names or job listings.
- [Chain vs Independent Labeler for Google Maps Leads](https://apify.com/ultimatemc/chain-vs-independent-labeler): labels local businesses as chain, franchise or independent.
- [Etsy & eBay Listing Policy & Banned Item Checker](https://apify.com/ultimatemc/etsy-ebay-listing-policy-checker): pre-checks marketplace listings for prohibited items, counterfeit wording and off-platform contact.
- [Job Scam Detector & Trust Score for Job Postings](https://apify.com/ultimatemc/job-posting-trust-score): scores job postings 0-100 for scam and ghost-job signals.
- [SAM.gov Amendment & Opportunity Change Tracker](https://apify.com/ultimatemc/sam-gov-opportunity-change-detector): shows what changed between versions of a SAM.gov notice: deadlines, set-asides, NAICS and attachments.
- [Product Recall Checker for Brands, UPCs & Products](https://apify.com/ultimatemc/product-recall-matcher): matches your brands, products, UPCs or model numbers against CPSC, FDA and NHTSA recalls.
- [App Store & Google Play Listing Policy Checker](https://apify.com/ultimatemc/app-store-listing-policy-checker): pre-checks app names, subtitles and descriptions against Apple and Google Play metadata rules.

Found a false positive or a missed phrase? Open an issue on the **Issues** tab with the text, and we'll review the rule.

# Actor input Schema

## `videos` (type: `array`):

Array of objects: {"id", "title", "description", "tags" (list or comma string), "thumbnailText", "script" (plain text OR a transcript list like \[{"text": "...", "start": 12.5}]), "contentContext", "madeForKids"}. Transcript lists give exact timestamps.

## `scripts` (type: `array`):

One script or transcript per entry (plain text).

## `titles` (type: `array`):

One video title per entry. Titles are judged more strictly than the script, as on YouTube.

## `datasetId` (type: `string`):

Apify dataset with video or transcript items (e.g. output of a YouTube or transcript scraper). Fields title/description/text/tags/hashtags/transcript/captions/script are detected automatically; override with Field map.

## `fieldMap` (type: `object`):

Override field names in dataset items, e.g. {"title": "videoTitle", "script": "subtitlesText"}. Keys: title, description, tags, script.

## `contentContext` (type: `string`):

YouTube says context matters. Educational/news/documentary lowers violence, drug and controversial-topic flags one level; music lowers language/drug/adult; comedy lowers language; gaming lowers violence.

## `madeForKids` (type: `boolean`):

If on, also checks scary/mature themes and negative behavior aimed at kids, and raises mature-theme flags one level.

## `openingSeconds` (type: `integer`):

Matches in the first N seconds of the script are reported as 'opening' (profanity at the start is judged more strictly). Plain-text scripts are timed at Words per minute.

## `wordsPerMinute` (type: `integer`):

Speaking speed used to estimate the opening window for plain-text scripts.

## `maxItems` (type: `integer`):

Maximum number of videos to check in this run.

## Actor input object example

```json
{
  "videos": [
    {
      "id": "v1",
      "title": "This F*CKING boss fight is INSANE",
      "description": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
      "tags": [
        "gaming",
        "boss fight"
      ],
      "script": "What the fuck. Okay okay, we go left here and grab the shield. This boss has three phases."
    },
    {
      "id": "v2",
      "title": "Killer sourdough recipe: dead simple, no knead",
      "description": "Shot on a phone in my kitchen. Hell yes, it works.",
      "script": "Today we make a killer loaf. Shoot, I forgot the salt. Let it rest overnight."
    }
  ],
  "contentContext": "general",
  "madeForKids": false,
  "openingSeconds": 30,
  "wordsPerMinute": 150,
  "maxItems": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "videos": [
        {
            "id": "v1",
            "title": "This F*CKING boss fight is INSANE",
            "description": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
            "tags": [
                "gaming",
                "boss fight"
            ],
            "script": "What the fuck. Okay okay, we go left here and grab the shield. This boss has three phases."
        },
        {
            "id": "v2",
            "title": "Killer sourdough recipe: dead simple, no knead",
            "description": "Shot on a phone in my kitchen. Hell yes, it works.",
            "script": "Today we make a killer loaf. Shoot, I forgot the salt. Let it rest overnight."
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ultimatemc/youtube-script-monetization-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "videos": [
        {
            "id": "v1",
            "title": "This F*CKING boss fight is INSANE",
            "description": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
            "tags": [
                "gaming",
                "boss fight",
            ],
            "script": "What the fuck. Okay okay, we go left here and grab the shield. This boss has three phases.",
        },
        {
            "id": "v2",
            "title": "Killer sourdough recipe: dead simple, no knead",
            "description": "Shot on a phone in my kitchen. Hell yes, it works.",
            "script": "Today we make a killer loaf. Shoot, I forgot the salt. Let it rest overnight.",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ultimatemc/youtube-script-monetization-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "videos": [
    {
      "id": "v1",
      "title": "This F*CKING boss fight is INSANE",
      "description": "Full run, no commentary. Use promo code SAVE10 at our gun store partner.",
      "tags": [
        "gaming",
        "boss fight"
      ],
      "script": "What the fuck. Okay okay, we go left here and grab the shield. This boss has three phases."
    },
    {
      "id": "v2",
      "title": "Killer sourdough recipe: dead simple, no knead",
      "description": "Shot on a phone in my kitchen. Hell yes, it works.",
      "script": "Today we make a killer loaf. Shoot, I forgot the salt. Let it rest overnight."
    }
  ]
}' |
apify call ultimatemc/youtube-script-monetization-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ultimatemc/youtube-script-monetization-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zMJq7HEfE7GdIYzjY/builds/dvZ5iccZMEKJauCGX/openapi.json
