# Google, Bing & YouTube Autocomplete Trend Monitor (`johnatan029/keyword-trend-monitor`) Actor

Monitor Google, Bing and YouTube autocomplete for keyword changes. Get only new suggestions, confirmed losses, and meaningful rank moves with persistent per-source baselines, locale targeting, anti-noise thresholds, and free run summaries. No search volume or keyword difficulty is invented.

- **URL**: https://apify.com/johnatan029/keyword-trend-monitor.md
- **Developed by:** [Johnn Mottin](https://apify.com/johnatan029) (community)
- **Categories:** SEO tools, Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 trend events

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Track how autocomplete suggestions change on Google, Bing, and YouTube

Monitor the exact keyword terms you care about and receive structured events only when autocomplete changes.

This Actor keeps a persistent baseline for every **term × source**. After the first successful observation, it can report:

- a suggestion that appeared;
- a suggestion that disappeared and stayed absent long enough to be confirmed;
- a suggestion whose position moved by a meaningful amount.

Google, Bing, and YouTube are intentionally treated as independent monitoring sources. A Google suggestion is never compared against a Bing or YouTube baseline.

No search volume is invented. No CPC is estimated. No keyword-difficulty score is fabricated. No browser automation or LLM is used in runtime.

#### Key features

- **Google autocomplete monitoring**
- **Bing suggestion monitoring**
- **YouTube autocomplete monitoring**
- **Persistent term × source baselines**
- **NEW\_KEYWORD events**
- **Confirmed LOST\_KEYWORD events**
- **RANK\_CHANGE events**
- **Configurable minimum rank movement**
- **Consecutive-miss confirmation before loss**
- **Google/YouTube language targeting**
- **Google/YouTube country targeting**
- **Source-specific state by construction**
- **One autocomplete request per term × source**
- **No alphabet expansion**
- **Free first-run baseline**
- **Free RUN\_SUMMARY**
- **Health and source-contract checks**
- **Controlled pacing and retries**
- **Pay Per Event**
- **No fake search volume**

> **Unofficial community Actor. Not affiliated with, sponsored by, or endorsed by Google, Microsoft/Bing, YouTube, or Alphabet.** The Actor uses public autocomplete/suggestion routes. Source behavior, availability, ordering, and suggestions can change at any time.

***

### What this Actor is for

A keyword suggestion extractor answers:

> What autocomplete suggestions exist around this seed right now?

This Actor answers a different question:

> What changed in autocomplete since I last checked?

That distinction makes it useful for:

- SEO monitoring;
- brand-query monitoring;
- content research;
- YouTube topic monitoring;
- competitor-term monitoring;
- product and category research;
- long-running keyword intelligence;
- trend observation;
- automated SEO dashboards;
- alerting and scheduled workflows.

***

### Important: this is a monitor, not a keyword-expansion scraper

For every term, the Actor makes exactly one request per selected source.

It does **not** perform expansions such as:

```text
term a
term b
term c
...
term z
```

or question/preposition permutations.

That keeps the product lightweight and makes the monitored unit clear:

```text
one exact term
×
one autocomplete source
```

If you want broad keyword discovery, use the companion:

[Google, Bing & YouTube Keyword Suggest Scraper](https://apify.com/johnatan029/keyword-autocomplete-intelligence)

Use this Actor when you already know the terms you want to watch.

***

### Important: autocomplete trend does not mean search volume

Autocomplete changes can be useful as an observable search-interface signal.

They are **not** direct search-volume measurements.

This Actor does not return or invent:

```text
monthly search volume
CPC
keyword difficulty
paid difficulty
search intent score
Google Trends index
```

A `RANK_CHANGE` means the suggestion changed position in the autocomplete list returned by that source.

A `NEW_KEYWORD` means a suggestion was not present in the previous successful state and is present now.

A `LOST_KEYWORD` means it remained absent for the configured number of consecutive successful checks.

Nothing more is claimed.

***

### First run creates a free baseline

The first successful read of each term × source unit creates the baseline.

Example:

```text
term: coffee maker
source: google
current suggestions: 10
previous state: none
```

Result:

```text
baseline created
0 NEW_KEYWORD
0 LOST_KEYWORD
0 RANK_CHANGE
```

The Actor does not present the current list as if every suggestion had just appeared.

From the next successful observation onward, the list is diffed against persistent state.

***

### Source state is separated by construction

The same seed can look very different across engines.

For example:

```text
coffee maker / google
coffee maker / bing
coffee maker / youtube
```

are three different monitored units.

Their state keys and event identities are source-specific.

That means a Google list can never be diffed against a Bing list.

This prevents cross-engine differences from becoming false change events.

***

### Sources

#### Google

Google autocomplete uses the public suggestion route configured by the Actor.

For Google, the request includes:

```text
hl
gl
```

using the configured language and country.

***

#### YouTube

YouTube suggestions use the same public suggestion family with the YouTube dataset flag.

The configured language and country are also applied.

***

#### Bing

Bing uses the public OSJSON suggestion route implemented by this Actor.

The route does **not** receive the configured language/country parameters.

Therefore:

```text
language
country
```

affect Google and YouTube monitoring, not Bing.

***

### Who it's for

#### SEO teams

Monitor strategic seed terms and watch for:

- emerging autocomplete suggestions;
- disappearing suggestions;
- meaningful position changes.

#### Content teams

Watch category or question seeds that matter to editorial planning.

#### Brand teams

Monitor autocomplete around:

- company names;
- products;
- executives;
- branded queries.

The Actor does not classify a suggestion as positive or negative.

#### YouTube creators and video teams

Track topic autocomplete for the exact YouTube search seeds you care about.

#### Market and competitor researchers

Watch terms related to:

- products;
- software categories;
- competitors;
- industries;
- consumer problems.

#### Automation builders

Connect change events to:

- Slack;
- Microsoft Teams;
- email workflows;
- n8n;
- Make;
- Google Sheets;
- databases;
- SEO dashboards;
- custom applications;
- AI analysis downstream.

***

### How it works

For each term × source unit, the Actor:

1. validates and normalizes the seed term;
2. loads persistent state for that source-specific unit;
3. sends one autocomplete request;
4. validates the source response shape;
5. normalizes suggestions case-insensitively;
6. records each suggestion's 1-based position;
7. detects new suggestions;
8. updates consecutive-miss counters for absent suggestions;
9. confirms lost suggestions only after the configured miss threshold;
10. calculates rank deltas for suggestions present in both readings;
11. applies the event-type filter;
12. applies the result/runtime/billing caps;
13. writes admitted `CHANGE_EVENT` records;
14. advances state only after a successful source read;
15. writes a free `RUN_SUMMARY`;
16. stores operational `STATS`.

***

### Input

#### Recommended example

```json
{
  "terms": [
    "coffee maker",
    "crm software"
  ],
  "sources": [
    "google",
    "bing",
    "youtube"
  ],
  "language": "en",
  "country": "us",
  "eventTypes": [
    "NEW_KEYWORD",
    "LOST_KEYWORD",
    "RANK_CHANGE"
  ],
  "minRankDelta": 2,
  "lostAfterMisses": 2,
  "maxResults": 1000,
  "maxRuntimeMs": 300000,
  "requestDelayMs": 250
}
```

#### Input fields

| Field | Default | Description |
|---|---:|---|
| `terms` | required | Exact seed terms to monitor. Maximum 100 entries. |
| `sources` | `["google"]` | `google`, `bing`, and/or `youtube`. |
| `language` | `en` | Google/YouTube language such as `en`, `pt`, or `pt-br`. |
| `country` | `us` | Google/YouTube 2-letter country such as `us`, `br`, or `de`. |
| `eventTypes` | all three | Select which change events can be emitted. |
| `minRankDelta` | `2` | Minimum absolute position movement for `RANK_CHANGE`. |
| `lostAfterMisses` | `2` | Consecutive missing readings required before `LOST_KEYWORD`. |
| `maxResults` | `1000` | Maximum billable `CHANGE_EVENT` records. |
| `maxRuntimeMs` | `300000` | Hard runtime cap in milliseconds. |
| `requestDelayMs` | `250` | Request pacing delay before jitter. Range: 100–2,000 ms. |
| `debug` | `false` | Additional diagnostic logging. |

***

### Terms

Input terms are normalized by:

```text
trim
lowercase
collapse repeated whitespace
```

Example:

```text
"  CRM   Software "
```

becomes:

```text
crm software
```

Duplicate normalized terms are monitored only once.

Empty entries are ignored.

If no valid term remains, the input is rejected before billing begins.

***

### Sources

Example:

```json
{
  "sources": [
    "google",
    "youtube"
  ]
}
```

The same term becomes two independent units:

```text
google × term
youtube × term
```

Each has separate persistent state.

***

### Language

Examples:

```json
{
  "language": "en"
}
```

```json
{
  "language": "pt"
}
```

```json
{
  "language": "pt-br"
}
```

This setting affects Google and YouTube.

***

### Country

Use exactly two letters:

```json
{
  "country": "br"
}
```

Other examples:

```text
us
gb
de
fr
ca
au
```

This setting affects Google and YouTube.

Bing's public route used here does not consume the country setting.

***

### Event types

The Actor supports:

```text
NEW_KEYWORD
LOST_KEYWORD
RANK_CHANGE
```

You can monitor all three or only the event types relevant to your workflow.

***

### `NEW_KEYWORD`

A suggestion exists in the current reading and was not present in the previous successful state.

It is emitted immediately.

Example:

```json
{
  "recordType": "CHANGE_EVENT",
  "eventType": "NEW_KEYWORD",
  "changeKind": "ADDED",
  "entityId": "kw:google/en-us/crm software/crm software ai",
  "source": "google",
  "observedAt": "2026-08-26T17:30:00.000Z",
  "previousObservedAt": "2026-08-25T17:30:00.000Z",
  "previous": null,
  "current": {
    "suggestion": "crm software ai",
    "position": 6
  },
  "term": "crm software",
  "monitorSource": "google"
}
```

***

### Why new suggestions are immediate

A newly appearing suggestion is useful even if it later disappears.

The product therefore does not require two observations before emitting `NEW_KEYWORD`.

Losses use a stricter confirmation rule because a temporary missing suggestion can be source-side sampling noise.

***

### `LOST_KEYWORD`

A suggestion is not declared lost after one missing reading by default.

Instead, its state keeps:

```text
missesInARow
```

At the default:

```json
{
  "lostAfterMisses": 2
}
```

the flow is:

```text
run 1: suggestion present
run 2: missing → miss counter = 1 → no LOST_KEYWORD
run 3: missing → miss counter = 2 → LOST_KEYWORD
```

#### Example

```json
{
  "recordType": "CHANGE_EVENT",
  "eventType": "LOST_KEYWORD",
  "changeKind": "REMOVED",
  "source": "google",
  "term": "crm software",
  "previous": {
    "suggestion": "crm software free",
    "position": 8
  },
  "current": null,
  "confirmedAfterMisses": 2,
  "lostAfterMissesApplied": 2
}
```

After a confirmed loss, the suggestion leaves persistent state.

If it later appears again, it becomes a legitimate `NEW_KEYWORD`.

***

### Why loss confirmation exists

Autocomplete is not a transactional database.

A suggestion can temporarily disappear because of:

- source-side sampling;
- ranking reshuffling;
- transient source behavior;
- localization behavior.

Announcing a false loss can be more misleading than waiting for one additional reading.

The default anti-noise rule is therefore:

```text
2 consecutive absences
```

You can configure:

```text
1–10
```

according to your tolerance for latency versus noise.

***

### `RANK_CHANGE`

A suggestion present in both readings can emit a rank event when:

```text
absolute position delta >= minRankDelta
```

At the default:

```json
{
  "minRankDelta": 2
}
```

these examples behave as follows:

```text
position 4 → 5
delta = 1
ignored
```

```text
position 8 → 2
delta = -6
RANK_CHANGE
```

#### Example

```json
{
  "recordType": "CHANGE_EVENT",
  "eventType": "RANK_CHANGE",
  "changeKind": "CHANGED",
  "entityId": "kw:google/en-us/coffee maker/coffee maker walmart",
  "source": "google",
  "observedAt": "2026-08-16T21:14:09.812Z",
  "previousObservedAt": "2026-08-16T20:58:44.107Z",
  "changedFields": [
    "position"
  ],
  "previous": {
    "suggestion": "coffee maker walmart",
    "position": 4
  },
  "current": {
    "suggestion": "coffee maker walmart",
    "position": 1,
    "delta": -3
  },
  "term": "coffee maker",
  "monitorSource": "google",
  "minRankDeltaApplied": 2
}
```

***

### Rank delta sign

For:

```text
delta = current position - previous position
```

a negative delta means the suggestion moved closer to position 1.

Example:

```text
8 → 2
delta = -6
```

A positive delta means it moved lower in the returned list.

***

### Output

The default dataset contains:

```text
CHANGE_EVENT
RUN_SUMMARY
```

`CHANGE_EVENT` is the billable monitoring event.

`RUN_SUMMARY` is free.

***

### Core `CHANGE_EVENT` fields

| Field | Description |
|---|---|
| `recordType` | `CHANGE_EVENT`. |
| `eventType` | `NEW_KEYWORD`, `LOST_KEYWORD`, or `RANK_CHANGE`. |
| `changeKind` | `ADDED`, `REMOVED`, or `CHANGED`. |
| `entityId` | Stable source/term/suggestion identity. |
| `source` | `google`, `bing`, or `youtube`. |
| `observedAt` | Current observation timestamp. |
| `previousObservedAt` | Previous successful observation timestamp. |
| `changedFields` | Changed canonical fields when applicable. |
| `previous` | Previous suggestion state. |
| `current` | Current suggestion state. |
| `term` | Normalized monitored term. |
| `monitorSource` | Source-specific monitored unit. |
| `minRankDeltaApplied` | Rank threshold applied to a `RANK_CHANGE`. |
| `confirmedAfterMisses` | Consecutive misses that confirmed a loss. |
| `lostAfterMissesApplied` | Loss-confirmation threshold. |

***

### `RUN_SUMMARY`

Every run attempts to write one free summary.

It can include:

```text
recordsWritten
unitsRequested
unitsOk
unitsFailed
capReason
qualityAlert
sourceUnavailable
warnings
units
outcomeKind
eventsByType
baselinesCreated
requestsBySource
thresholds
locale
cost
pricingLabel
```

This keeps quiet monitoring runs visible even when no billable event occurs.

***

### Per-unit summary data

The `units` array in `RUN_SUMMARY` can expose information such as:

```text
source:term
status
suggestions
firstSight
newKeywords
lostKeywords
rankChanges
pendingMisses
```

This lets you distinguish:

```text
no change
```

from:

```text
source failure
```

or:

```text
baseline creation
```

***

### Request accounting

The design is intentionally lightweight:

```text
1 source request
per
term × source unit
```

Retries can increase the actual HTTP request count when the source returns a retryable failure.

The free summary exposes:

```text
requestsBySource
```

so request behavior remains auditable.

***

### Pacing and retry behavior

The Actor uses controlled request pacing with jitter.

Default:

```text
250 ms
```

Configurable range:

```text
100–2000 ms
```

Retryable conditions can include:

- timeout;
- network failure;
- applicable HTTP 429/5xx conditions.

Unexpected successful-response shapes become a controlled:

```text
API_CONTRACT_CHANGED
```

error rather than silently producing fake suggestions.

***

### Redirects and source walls

The suggestion client does not automatically follow redirects on these API routes.

A redirect that behaves like a consent/login/access wall is treated as a blocked source condition.

The Actor does not rotate identities or attempt to bypass an access control.

***

### Character encoding

Google suggestion responses can declare a non-UTF-8 character encoding for some locales.

The client reads the response charset from:

```text
Content-Type
```

and decodes accordingly.

If the declared charset is unavailable, it falls back to UTF-8.

This helps prevent mojibake in multilingual suggestion monitoring.

***

### Scheduling

This Actor is designed for recurring monitoring.

A practical starting point:

```text
daily
```

The best cadence depends on how quickly you care about autocomplete changes.

More frequent runs can surface changes sooner, but autocomplete can also contain short-lived movement.

The anti-noise settings help control this.

***

### Recommended scheduled workflow

1. Add the exact seed terms.
2. Select one or more sources.
3. Run once to establish free baselines.
4. Save the input as an Apify **Task**.
5. Open **Schedules**.
6. Choose the cadence.
7. Send future `CHANGE_EVENT` records downstream.

Possible destinations:

- Slack;
- Microsoft Teams;
- email workflows;
- Google Sheets;
- n8n;
- Make;
- webhooks;
- databases;
- SEO dashboards;
- internal applications.

***

### Example SEO-monitoring input

```json
{
  "terms": [
    "crm software",
    "project management software",
    "ai meeting notes"
  ],
  "sources": [
    "google"
  ],
  "language": "en",
  "country": "us",
  "minRankDelta": 2,
  "lostAfterMisses": 2,
  "maxResults": 200
}
```

A downstream workflow can:

- alert when a strategic autocomplete phrase appears;
- record a confirmed lost phrase;
- highlight large rank moves;
- maintain a change-history table;
- route selected events to an analyst;
- generate a weekly narrative with AI downstream.

***

### Example YouTube topic monitoring

```json
{
  "terms": [
    "ai tools",
    "home workout",
    "travel vlog"
  ],
  "sources": [
    "youtube"
  ],
  "language": "en",
  "country": "us",
  "eventTypes": [
    "NEW_KEYWORD",
    "RANK_CHANGE"
  ],
  "minRankDelta": 3
}
```

***

### Example cross-source monitoring

```json
{
  "terms": [
    "protein powder"
  ],
  "sources": [
    "google",
    "bing",
    "youtube"
  ]
}
```

This does **not** compare engines against each other.

It creates three independent timelines:

```text
protein powder / google
protein powder / bing
protein powder / youtube
```

***

### API

Run through the Apify API:

```bash
curl -s "https://api.apify.com/v2/acts/<YOUR_USERNAME>~keyword-trend-monitor/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "terms":["crm software","coffee maker"],
    "sources":["google","youtube"],
    "language":"en",
    "country":"us",
    "maxResults":200
  }'
```

Replace:

```text
<YOUR_USERNAME>
<YOUR_APIFY_TOKEN>
```

with your Apify account values.

***

### Integrations

Use with:

- Apify API;
- Tasks;
- Schedules;
- webhooks;
- n8n;
- Make;
- Google Sheets;
- Slack;
- Teams;
- databases;
- SEO dashboards;
- custom applications;
- AI agents downstream.

***

### Pricing

This Actor uses **Pay Per Event**.

The code uses two custom billing events:

```text
actor-start
trend-event
```

#### `actor-start`

Called once after valid input has been accepted.

Invalid input is rejected before the billing gate opens.

#### `trend-event`

Charged per delivered `CHANGE_EVENT`.

A billable event can be:

```text
NEW_KEYWORD
LOST_KEYWORD
RANK_CHANGE
```

The free `RUN_SUMMARY` does not pass through event billing.

The **Pricing** tab on the Actor page is always the authoritative source for current prices.

***

### What is free

Free by design:

```text
first baseline
unchanged suggestions
unconfirmed first loss miss
rank movement below minRankDelta
RUN_SUMMARY
```

If a scheduled run has no qualifying changes, there is no `trend-event` result charge.

The configured start event can still apply.

***

### Cost control

Primary controls:

```text
terms
sources
eventTypes
minRankDelta
lostAfterMisses
maxResults
maxRuntimeMs
requestDelayMs
```

#### Fewer events

Use:

- fewer seed terms;
- fewer sources;
- a larger `minRankDelta`;
- only the event types you need.

#### Faster loss detection

Use:

```json
{
  "lostAfterMisses": 1
}
```

but understand that this increases sensitivity to one-off source sampling.

#### Lower-noise loss detection

Use:

```json
{
  "lostAfterMisses": 3
}
```

or higher.

The tradeoff is slower loss confirmation.

***

### Run health

Operational statistics are persisted in:

```text
STATS
```

in the default Key-Value Store.

Depending on the run, they can include:

- HTTP requests;
- retries;
- charged results;
- charge errors;
- units completed;
- units failed;
- quality alerts;
- source availability;
- runtime;
- caps;
- cost metrics.

The Actor also keeps historical health signals for source-volume anomalies.

***

### Honest limits

#### Autocomplete is not a search-volume feed

The returned list is an autocomplete interface result.

Do not interpret position as monthly volume.

***

#### Rank is source order, not SEO ranking

`position` means position in the returned autocomplete suggestion list.

It is not:

- organic SERP position;
- YouTube video rank;
- Bing result rank;
- ad position.

***

#### Bing does not use the locale input in this implementation

The public Bing suggestion route used here does not receive `language` or `country`.

Google and YouTube do.

***

#### Source personalization and experimentation can exist

Public autocomplete behavior can vary because of source-side changes, experimentation, geography, timing, or other factors outside this Actor's control.

The Actor reports what the configured public route returned.

***

#### `LOST_KEYWORD` has intentional latency

At the default:

```text
lostAfterMisses = 2
```

a loss requires two consecutive missing readings.

With a daily schedule, that can mean roughly one additional day before confirmation compared with a one-miss policy.

***

#### A source failure does not update state

Persistent state advances only after a successful read.

A failed request therefore does not become a false missing-suggestion observation.

***

#### Exact seed only

The Actor does not expand a seed through alphabet suffixes.

Use the companion keyword suggestion extractor when you need broad discovery.

***

#### The current Actor does not store a full historical rank series

Persistent state stores the latest suggestion positions and miss counters needed for diffing.

The Dataset is where emitted change history should be retained.

***

#### Autocomplete result count is source-controlled

The Actor does not promise a fixed number of suggestions per term.

The source decides how many suggestions it returns.

***

#### Public routes can change

Google, Bing, or YouTube can change:

- response shape;
- rate limits;
- redirect behavior;
- encoding;
- suggestion logic.

The Actor includes explicit contract checks and controlled errors to surface such changes.

***

#### No sentiment or intent classification

The Actor does not classify autocomplete suggestions as:

- positive;
- negative;
- commercial;
- informational;
- transactional.

Use a separate downstream analysis step when needed.

***

#### No AI in runtime

All diff decisions are deterministic.

No LLM creates or interprets suggestions.

***

### FAQ

#### Do I need a Google account?

No.

#### Do I need a Bing account?

No.

#### Do I need a YouTube account?

No.

#### Do I need API keys?

No for the public suggestion routes used by this Actor.

#### Does it use browser automation?

No.

#### What happens on the first run?

Each term × source creates a baseline.

No baseline suggestion is billed as a change event.

#### Can I monitor 100 terms?

Yes.

The input accepts up to 100 normalized terms.

#### Can I monitor all three sources?

Yes.

#### Are Google, Bing and YouTube compared with each other?

No.

They are independent state timelines.

#### Can I use Brazilian Portuguese?

Yes.

For Google/YouTube:

```json
{
  "language": "pt-br",
  "country": "br"
}
```

#### Does the country affect Bing?

No.

#### What is a `NEW_KEYWORD`?

A suggestion present now that was not present in the previous successful state.

#### What is a `LOST_KEYWORD`?

A previously tracked suggestion that remained absent for the configured number of consecutive successful readings.

#### Why did a suggestion disappear but no loss event fire?

At the default, the first absence only increments the miss counter.

A second consecutive absence confirms the loss.

#### What is `RANK_CHANGE`?

A suggestion was present in both readings and moved at least `minRankDelta` positions.

#### Is rank change the same as Google Trends?

No.

#### Does the Actor return search volume?

No.

#### Does it return CPC?

No.

#### Does it return keyword difficulty?

No.

#### Can I schedule it?

Yes.

Daily is a practical starting cadence.

#### Are quiet runs charged per result?

No `trend-event` is created when there is no qualifying change.

The configured run-start event can still apply.

#### Is the summary charged?

No.

#### What am I charged for?

The custom start event shown in Pricing plus delivered `CHANGE_EVENT` records.

#### Is this affiliated with Google, Microsoft, Bing or YouTube?

No.

This is an independent community Actor using public autocomplete/suggestion routes.

***

### Support

For bugs, questions, or requested fields:

```text
johnatan291303@gmail.com
```

You can also use the **Issues** tab on the Actor page.

***

### Part of the JM Forge suite

Also from the same developer:

- [Google, Bing & YouTube Keyword Suggest Scraper](https://apify.com/johnatan029/keyword-autocomplete-intelligence) — broad keyword discovery and autocomplete expansion.
- **Brand News Monitor & GDELT Mention Alerts** — stateful global brand-news monitoring.
- **ATS Salary, Skills & Seniority Intelligence** — structured hiring intelligence from public ATS boards.

JM Forge Actors remain independent tools.

Use the extractor for broad keyword discovery.

Use this monitor for recurring autocomplete change intelligence.

# Actor input Schema

## `terms` (type: `array`):

One entry per term. Each term is checked with a single request per source — no alphabet expansion (use the extractor Actor for that).

## `sources` (type: `array`):

Google and YouTube honor language/country; the public Bing route does not take locale parameters.

## `language` (type: `string`):

2-letter code for Google/YouTube suggestions (e.g. en, pt, es).

## `country` (type: `string`):

2-letter code for Google/YouTube suggestions (e.g. us, br, de).

## `eventTypes` (type: `array`):

The first run for each term creates the baseline and emits nothing. From the second run on, only what changed.

## `minRankDelta` (type: `integer`):

A suggestion must move at least this many positions to produce RANK\_CHANGE. Position 4 to 5 is tail reshuffling; 8 to 2 is a signal.

## `lostAfterMisses` (type: `integer`):

A suggestion must be absent this many CONSECUTIVE runs before LOST\_KEYWORD fires. Anti-false-alarm design: one absence can be sampling on the source side.

## `maxResults` (type: `integer`):

Hard cap on billable events. The run stops gracefully and keeps what it collected.

## `maxRuntimeMs` (type: `integer`):

Hard time cap. The run stops gracefully when reached.

## `requestDelayMs` (type: `integer`):

Polite pacing against the public routes, inherited from the extractor. Floor 100 ms.

## `debug` (type: `boolean`):

Log each pacing wait and diff decision.

## Actor input object example

```json
{
  "terms": [
    "coffee maker",
    "crm software"
  ],
  "sources": [
    "google"
  ],
  "language": "en",
  "country": "us",
  "eventTypes": [
    "NEW_KEYWORD",
    "LOST_KEYWORD",
    "RANK_CHANGE"
  ],
  "minRankDelta": 2,
  "lostAfterMisses": 2,
  "maxResults": 1000,
  "maxRuntimeMs": 300000,
  "requestDelayMs": 250,
  "debug": false
}
```

# Actor output Schema

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

Default dataset containing billable CHANGE\_EVENT records and the free RUN\_SUMMARY.

## `stats` (type: `string`):

STATS record with requests, retries, billing counters, health signals, runtime, caps, and operational metrics.

# 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 = {
    "terms": [
        "coffee maker",
        "crm software"
    ],
    "sources": [
        "google"
    ],
    "language": "en",
    "country": "us",
    "eventTypes": [
        "NEW_KEYWORD",
        "LOST_KEYWORD",
        "RANK_CHANGE"
    ],
    "minRankDelta": 2,
    "lostAfterMisses": 2,
    "maxResults": 1000,
    "maxRuntimeMs": 300000,
    "requestDelayMs": 250,
    "debug": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("johnatan029/keyword-trend-monitor").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 = {
    "terms": [
        "coffee maker",
        "crm software",
    ],
    "sources": ["google"],
    "language": "en",
    "country": "us",
    "eventTypes": [
        "NEW_KEYWORD",
        "LOST_KEYWORD",
        "RANK_CHANGE",
    ],
    "minRankDelta": 2,
    "lostAfterMisses": 2,
    "maxResults": 1000,
    "maxRuntimeMs": 300000,
    "requestDelayMs": 250,
    "debug": False,
}

# Run the Actor and wait for it to finish
run = client.actor("johnatan029/keyword-trend-monitor").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 '{
  "terms": [
    "coffee maker",
    "crm software"
  ],
  "sources": [
    "google"
  ],
  "language": "en",
  "country": "us",
  "eventTypes": [
    "NEW_KEYWORD",
    "LOST_KEYWORD",
    "RANK_CHANGE"
  ],
  "minRankDelta": 2,
  "lostAfterMisses": 2,
  "maxResults": 1000,
  "maxRuntimeMs": 300000,
  "requestDelayMs": 250,
  "debug": false
}' |
apify call johnatan029/keyword-trend-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,johnatan029/keyword-trend-monitor"
        }
    }
}

```

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/jSlvBduf6S62Y1zBB/builds/cNHOUE74PDsv2lxSl/openapi.json
