Google News Scraper — $0.20/1K | Articles & URLs avatar

Google News Scraper — $0.20/1K | Articles & URLs

Pricing

from $0.20 / 1,000 news records

Go to Apify Store
Google News Scraper — $0.20/1K | Articles & URLs

Google News Scraper — $0.20/1K | Articles & URLs

Search Google News by keyword and date across 13 editions. Export headlines, direct URLs and optional descriptions/images. $0.20/1K + $0.0015/start; platform included.

Pricing

from $0.20 / 1,000 news records

Rating

0.0

(0)

Developer

Monkey D. Scraping

Monkey D. Scraping

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

2

Monthly active users

4 days ago

Last modified

Categories

Share

Search Google News by keyword, country edition and publication date. Export article headlines, publishers, dates, Google News links and matching searches to CSV, Excel or JSON. Add direct article URLs, publisher descriptions and image URLs when you need an enriched press review.

Use this Google News scraper for brand monitoring, competitor news tracking, media monitoring and historical news research across 13 country/language editions. Custom date ranges can span multiple years, with up to 300 articles per keyword and 20 keywords per run. These are request limits, not guaranteed coverage. No Google News API key is required; programmatic Apify calls use your Apify token.

Price: $0.20 per 1,000 saved news records + $0.0015 per run start, with platform usage included at 128 MB. Both collection modes have the same result price. Check the current Pricing tab before running.

Two collection modes: Simple for a quick news feed; Advanced for custom dates, expanded coverage and publisher metadata. Start with ten articles to check the coverage for your keyword.

Automate your news sheet: Google News to Google Sheets with n8n, with step-by-step setup and an importable workflow.

What can you collect?

NeedChooseOutput
Recent news headlinesSimple + past day, week or monthHeadlines, publishers, publication dates and Google News links
Publisher article URLsEnable Get direct article linksDirect article URLs where resolution succeeds
Historical news by dateAdvanced + Custom dates + both datesMatching news across automatically split date windows
More than 100 articles per keywordAdvanced + Search more date windowsUp to 300 articles per keyword, subject to available results
Descriptions and imagesAdvanced + Get publisher descriptions and imagesAvailable page metadata, with explicit status for missing fields

Common questions

Can I search Google News across multiple years? Yes. Use Advanced mode, Custom dates and both date fields. Ranges can cover up to 3,660 days, with no future dates. Google News availability and collection limits mean this is not a complete historical archive.

Does this include full article text? No. Optional enrichment returns publisher descriptions and image URLs, not full text or AI summaries. Some publishers block access or expose no usable metadata.

How much does a test cost? Up to 10 saved records cost $0.0035 including startup; up to 300 cost $0.0615. Platform usage at 128 MB is included. An empty run still costs $0.0015. Unavailable optional metadata does not make a saved record free.

Is this the official Google News API? No. This is an independent Actor accessed through the Apify API. Export its dataset or use the n8n workflow below to update Google Sheets.

Quick start

  1. Replace the example keyword with your brand, company or topic.
  2. Keep Maximum articles per keyword at 10 for your first test.
  3. Choose the country edition and News from period, set your run spending cap, then start the Actor.
  4. Open the News headlines dataset view, check Collection summary, and export the dataset as CSV or Excel.

The four main fields are enough for a headlines search. Open Optional: publisher article links and enable Get direct article links when your workflow needs the publisher URL.

{
"queries": ["Microsoft"],
"edition": "en-US",
"period": "week",
"maxItemsPerQuery": 10,
"resolveArticleUrls": false
}

The first-run Console example uses the United States / English edition and 10 articles. API requests that omit edition or maxItemsPerQuery use Italy / Italian and 50 articles per keyword. Keep these fields explicit to reproduce the example. Set resolveArticleUrls to true when you need direct publisher links.

Choose from the 13 supported country/language editions listed below. The edition selects Google News localization; it does not guarantee that every publisher is based in that country. Headlines retain the language supplied by the source.

Brand and competitor news: multiple searches, one sheet

For a first press review, collect two related searches in one run. Paste this input in Console, replace the example brands, and set Maximum cost per run to $0.01 in run options:

{
"mode": "simple",
"queries": ["Microsoft", "OpenAI"],
"edition": "en-US",
"period": "week",
"maxItemsPerQuery": 10,
"resolveArticleUrls": false
}

This requests up to 10 articles per search, at most 20 unique saved records: up to $0.0055 including startup at 128 MB. The $0.01 cap is a ceiling, not the expected charge. An empty run still costs $0.0015. Fewer available articles or overlap can reduce the record charge.

In News headlines, review the headline, publication date, publisher, All matching searches (matchedQueries) and Google News link. Export CSV or Excel for a one-off review. To keep a sheet updated, use the existing n8n workflow: put both queries in its Configuration node and set maxTotalChargeUsd to 0.01. Its default $0.005 cap is too small for this 20-record example.

The same Google News article ID is saved once per run and retains all matching searches. For example, one row may match both Microsoft and OpenAI: it counts as one article and one record charge, but contributes to both search counts. Separate articles about the same story can remain separate rows. This is a review of returned coverage, not an exhaustive press archive or a verified share-of-voice measurement.

For recurring use, the workflow updates existing IDs and appends new ones. It does not prevent the Actor from collecting and charging for the same article again in later runs. Validate one manual run before setting up your own schedule.

Choose the result you need

Your goalSettingWhat to expect
Review headlines in a spreadsheetLeave Get direct article links offHeadlines, publishers, dates and Google News links; a small first run
Link your dashboard to publisher articlesEnable Get direct article linksThe same news records, with a verified publisher URL where resolution succeeds; unresolved URLs remain null
Keep a reusable news sheetFollow the n8n guideA workflow that stores and updates rows; the Actor alone does not remember previous runs

Simple mode returns headlines and optional direct links. Advanced mode can also read descriptions and image URLs from public publisher-page metadata. Neither mode includes full article text, sentiment or automatic alerts. All modes currently cost the same per saved news record; direct links and publisher metadata take additional work.

Advanced coverage and publisher metadata

Select Advanced and enable Search more date windows to search beyond a single saturated feed. Articles repeated across windows or keywords are deduplicated within the run. The maximum is 300 articles per keyword; it is a requested limit, not a promised yield. RUN_SUMMARY reports feedsRequested, feedsAtCapacity, coverageLimitedQueries and duplicatesAcrossWindows. coverageExhaustive remains false. complete reports processing status, not an exhaustive archive.

{"mode":"advanced","queries":["Microsoft"],"edition":"en-US","period":"week","expandCoverage":true,"maxItemsPerQuery":300}

To collect publisher metadata, enable enrichArticles. It automatically enables direct links and can process the collected records across up to 20 keywords × 300 articles, within the time and spending limits. Descriptions and image URLs may be absent: inspect enrichmentStatus, publisherFetchedAt, and the enriched/unavailable counts in RUN_SUMMARY. TLS failures, timeouts, HTTP refusals and absent metadata are distinguished where observed. A record is charged even when its optional metadata is unavailable. Pages are read up to a bounded prefix; metadata later in a large page can be missed. No full text or paywall bypass is provided.

{"mode":"advanced","queries":["Microsoft"],"edition":"en-US","period":"week","maxItemsPerQuery":50,"enrichArticles":true}

Supported editions: Italy/Italian, US/English, UK/English, Germany/German, France/French, Spain/Spanish, Canada/English, Canada/French, Australia/English, India/English, Brazil/Portuguese, Netherlands/Dutch and Japan/Japanese. These select Google News editions, not a guarantee about each publisher's location.

Three copy-and-paste starting points

Quick headlines — 10 recent results, up to $0.0035 including startup:

{"queries":["Microsoft"],"edition":"en-US","period":"week","maxItemsPerQuery":10}

Enriched press review — up to 300 records, up to $0.0615 including startup:

{"mode":"advanced","queries":["Microsoft"],"edition":"en-US","period":"week","maxItemsPerQuery":300,"expandCoverage":true,"enrichArticles":true,"processingBudgetSeconds":900}

Historical research — inclusive custom dates, automatically split when needed:

{"mode":"advanced","queries":["\"Mario Calabresi\""],"edition":"it-IT","period":"custom","dateFrom":"2025-01-01","dateTo":"2026-10-17","maxItemsPerQuery":300,"expandCoverage":true,"resolveArticleUrls":false}

These are requested maxima, not guaranteed yields. For the two 300-record examples, set a spending cap of $0.07 or higher to allow the full requested output. For enriched runs use a run timeout of at least 930 seconds with the default 900-second processing budget. Existing saved tasks may retain an older 120-second timeout: update their run options for larger collections. No schedule is created automatically.

Precise names and optional headline filters

Broad queries such as Calabresi Milano can match unrelated news about people from Calabria. Start with "Mario Calabresi" for an exact name, and keep wider election-context searches separate if you want both kinds of coverage. includeTitleTerms: ["Mario Calabresi"] requires that literal phrase in the headline; excludeTitleTerms: ["Lotta Continua"] removes matching headlines. These are case-insensitive lexical filters, not AI classification. They are off by default and may remove relevant articles whose headline does not contain the name. Counts in filteredByTitleOccurrences include repeated observations across windows, not unique discarded articles.

Understand limits before re-running

Open Results and limits by query (QUERY_SUMMARY) for each query's article count, item-limit flag, date windows explored, pending windows, saturation and suggested next step. RUN_SUMMARY.queryResults contains the same details. A saturated day cannot be subdivided further. At most 16 RSS feeds are fetched per query, and collection has a 120-second budget inside the overall processing budget. Historical windows are visited newest first; a record or time limit may leave older dates unvisited. Narrow the date range and run those windows separately when you need to investigate further. The Actor does not promise all historical articles.

URL resolution uses four workers. Publisher metadata is cached by exact resolved URL (fragment ignored, query parameters preserved), with at most two concurrent metadata requests per host. Legal/contact boilerplate descriptions are discarded conservatively and the next metadata description is tried. Missing optional fields remain explicit; publisherDescriptionsAvailable and publisherImagesAvailable count them separately. enriched means at least one of these fields exists, not necessarily both.

processingBudgetSeconds limits work, while the platform timeout is respected with a reserve for saving results. not_attempted_time_limit differs from rate-limit and customer-spending-limit statuses. A short timeout can still leave partial data. complete refers to processing of the requested bounded output, not exhaustive source coverage. Review it before importing; titles shared by distinct article IDs are not automatically deleted.

Input validation lists all detected issues in one error, including actionable changes, instead of making you discover one constraint per run.

Measured example: coverage, speed and price

Observed on 16 October 2026, version 0.1.19, at 128 MB. These are samples from this Actor, not a guarantee or a head-to-head competitor benchmark.

Input: Microsoft, en-US, past weekUnique recordsRuntimeResult detailsCustomer price at the listed rate
Simple, maximum 1001004.24 sOne RSS feed$0.0215
Advanced, expanded coverage, maximum 3003008.79 sSeven feeds; 265 repeated records removed across date windows$0.0615
Advanced, publisher metadata, maximum 505028.73 s50 direct URLs; 36 records with both description and image$0.0115

The expanded sample shared 98 IDs with the simple sample and added 202; two simple-sample IDs were absent after the final limit. Live results change between runs. Fourteen metadata records were unavailable: four timeouts, eight HTTP403, one HTTP401 and one page without metadata. Missing metadata does not waive the saved-record fee. Coverage is not exhaustive.

Reproduce it: use the two Advanced JSON examples above. For the baseline use mode: "simple", queries: ["Microsoft"], edition: "en-US", period: "week", maxItemsPerQuery: 100, with direct links disabled. Set API run options to memory=128, timeout=120, and a maximum charge of $0.03, $0.07 or $0.02 respectively. Runtime is the Apify run duration; prices include startup and saved records, not a monthly Apify subscription. Output counts and availability may differ when you repeat the search.

Ready-to-run example tasks

Open an example below and choose Try for free to create your own task in Apify Console, then replace its keywords with your own. All three use the United States / English edition and the past 7 days.

Example taskWhat you getMaximum example cost per run
Monitor brand and competitor newsMicrosoft and Google headlines, publishers, dates and verified direct article links; up to 20 records$0.0055
Try Google News: 10 AI headlinesArtificial intelligence headlines, publishers, dates and Google News links; up to 10 records$0.0035
Get article descriptions and imagesAdvanced mode: up to 10 Microsoft news records with direct URLs and optional publisher descriptions/images; unavailable fields are explicit$0.0035

All three saved examples use a $0.01 run spending cap. The cap is a limit, not the example charge. Example costs include startup and platform usage. Searches can return fewer records; optional direct links may remain unverified. Repeated runs may include the same articles. Changing the keywords or record limits changes coverage and can change the cost.

What can you use it for?

  • Brand and competitor monitoring: collect recent mentions of companies or products for a review dashboard.
  • Media research: compare headlines and publishers covering the same topic.
  • Market intelligence: follow industry, technology or economic news in a selected edition.
  • News automation: export structured records or pass them to the next step of an API workflow.

Repeated runs collect matching news again. This version deduplicates within a run; it does not remember previously collected articles or emit only new mentions.

Check news quality before importing

Read RUN_SUMMARY.complete before sending results to a reporting workflow. If some feed items have invalid dates, missing required fields or invalid article identifiers, verified articles remain available but complete is false. invalidFeedItems counts rejected item occurrences across fetched feeds; queriesWithInvalidItems counts affected searches. In expanded coverage, the same malformed source item may be encountered in more than one date window, so this is not a unique-article count.

A genuinely empty, verified feed is different from a feed containing rejected items. The supplied n8n workflow already stops on incomplete output before writing to Google Sheets. Inspect the existing results and summary before retrying: another run may collect and charge for the same valid articles again. Even complete: true does not mean exhaustive coverage; check feed saturation and collection limits separately.

Output

FieldMeaning
titleHeadline supplied by Google News
publisherSource publication
publishedAtPublication timestamp supplied by the feed, normalized to UTC
articleUrlVerified publisher article link when requested and resolved; otherwise null
articleUrlResolvedWhether the direct article link was verified
articleUrlStatusResolution status or reason it could not be verified
googleNewsUrlOriginal Google News article link
publisherHomepagePublisher homepage, separate from the article link
matchedQueriesKeywords that matched the same news item in this run
collectedAtCollection time in UTC

Example output shape (illustrative values):

{
"title": "Example company announces a new product",
"publisher": "Example Publisher",
"publishedAt": "2026-10-10T08:00:00+00:00",
"articleUrl": "https://publisher.example/news/new-product",
"articleUrlResolved": true,
"articleUrlStatus": "resolved",
"matchedQueries": ["example company"],
"edition": "en-US"
}

With direct links disabled, articleUrl is null and articleUrlStatus is not_requested. The original googleNewsUrl is included in both modes. With direct links enabled, results are saved in small batches as links are processed; arrival order can differ from publication order. Sort by publishedAt if your workflow needs newest-first output.

Search examples

GoalKeyword or topic
Follow a brandMicrosoft
Follow a company with several words"example company"
Focus on a publicationbitcoin site:reuters.com
Follow an industry topicrenewable energy

Use News from for the past 24 hours, 7 days or 30 days. In Advanced mode, choose Custom dates and set dateFrom and dateTo (inclusive UTC dates, at most 3660 days, starting in 1970 or later and ending no later than today; intervals longer than 366 days are automatically split). Inline when:, before: and after: operators are rejected to keep the chosen period consistent. Google News determines matching and coverage; requesting 100 articles does not guarantee 100 results.

Limits and incomplete results

Runs accept up to 20 keywords. Simple mode supports 100 articles per keyword; Advanced with expandCoverage supports up to 300. Searches can return fewer articles than requested. Direct links and metadata no longer have a separate requested-record cap. They process the collected records within processingBudgetSeconds (default 900, range 60–3600). Choose a small first run to measure availability and time before requesting thousands of records.

A direct link is retained only when its publisher hostname matches the source declared by the feed. That checks attribution, not the article's availability or full text. Missing, blocked or mismatched links remain null. If requested data cannot be verified, the run reports a failure and preserves any collected records. Check RUN_SUMMARY for completeness before using partial results.

Dates outside the selected period are filtered. A valid empty search is distinguished from an HTTP or parsing failure. This Actor does not provide full article text, exhaustive historical coverage or unrestricted pagination. Image URLs are optional metadata observations; image files are not downloaded. No API key or login is required.

Export and integrations

Use the Apify dataset to export JSON, CSV or Excel. An API workflow, n8n or Make can start the Actor and read its dataset using their Apify integration or HTTP modules. Use the returned fields for your dashboard or processing step; sentiment analysis and summaries are not included in this Actor.

Frequently asked questions

Can I use this as a Google News API? Yes. Start the Actor through the Apify API and read its dataset. This is an independent scraper, not an official Google API.

Can it monitor brand mentions automatically? Schedule repeated runs on Apify and use the dataset in your workflow. This version does not remember articles between runs; repeated articles can reappear.

Does it return direct article URLs? When requested, successfully verified publisher links are returned in articleUrl. Unverified links remain null and the run reports incomplete requested data.

Does the date filter check article content? No. It uses the publication date supplied by Google News. It does not verify dates inside publisher pages.

Is this Google Search scraping? It collects Google News results. It does not collect Google.com organic search results.

What does it cost? $0.20 per 1,000 news records saved to the dataset, plus $0.0015 per run start. Platform usage is included. Both modes have the same result price. A result fee covers a news record; it does not guarantee that an optional publisher link can be resolved. The startup fee also applies to empty searches and failed runs.

Can I cap the cost? Set Maximum cost per run in Apify Console, or maxTotalChargeUsd through the API. The minimum run budget is $0.0017. A $0.0025 budget covers the startup fee and up to five news records. The Actor limits collection to the available result budget and stops when it is exhausted. Budget-limited or aborted runs may contain partial results. Charges apply only to records saved within the budget.

Can I choose exact start and end dates?

Yes. Select Advanced mode, choose Custom dates and provide dateFrom and dateTo. Both endpoints are inclusive in UTC, up to 3660 days, from 1970 onward and no future dates. Intervals longer than 366 days are automatically split into disjoint windows, newest first. The Actor checks feed publication dates locally. A date range does not guarantee a complete historical archive; enable expandCoverage to subdivide saturated feeds into smaller date windows. This uses at most 16 feeds per keyword and stops at the result or time limit. Even a single day can be saturated; coverage is never guaranteed exhaustive.

Does the selected country restrict every publisher to that country?

No. Country and language select a Google News edition. The source determines matching and publishers, and headlines retain their original language.

How do I report missing or unresolved data?

Open the Issues tab with your run ID, non-sensitive query, edition and expected result. Review RUN_SUMMARY and articleUrlStatus first. A publisher homepage is not a substitute for an unresolved article URL.

Price examples

Delivered news recordsTotal run charge
0$0.0015
10$0.0035
100$0.0215
200$0.0415

These are charges for one run at 128 MB. The price is the same across Apify plans; Free-plan users spend their available Apify credits. Repeated scheduled runs incur a startup fee each time.

Google News to Google Sheets with n8n

Build a brand monitoring sheet with Google News headlines, publishers, publication dates and article links. This workflow uses Google News Scraper and built-in n8n nodes; you do not need a community node or a Google News API key.

Start with Microsoft, United States, past week, up to 10 articles. The Actor charge is at most $0.0035 per run at the current list price, with a $0.005 run spending cap. The workflow runs manually until you choose to add a schedule.

What you need

  • An Apify account with available credits and an API token.
  • An n8n instance with HTTP Request, Code and Google Sheets nodes. Import and local execution were verified with n8n 2.42.6; older versions may require updating node versions or mapping.
  • A Google Sheet you can edit and a Google Sheets OAuth2 credential configured in n8n. Follow n8n’s Google Sheets credential guide.

1. Prepare the sheet

Create a tab named News. Paste these tab-separated column names into cell A1, all on the first row:

id title publisher publishedAt articleUrl googleNewsUrl matchedQueries edition collectedAt articleUrlStatus

Keep the headers exactly as shown. Keep id as text and unique. Avoid blank rows inside the table and concurrent workflows writing to this tab. The Google Sheets credential must have edit access to this document.

Your spreadsheet ID is the part between /d/ and /edit in its URL. For example, in https://docs.google.com/spreadsheets/d/YOUR_ID/edit, use YOUR_ID.

2. Import the workflow

Save the supplied google-news-to-google-sheets.n8n.json file and select Import from File in n8n. On the Actor’s public README, the same workflow is available in the Importable workflow JSON section: copy the JSON, save it as a .json file, and import it. n8n import instructions.

Open Configuration and replace PASTE_YOUR_SPREADSHEET_ID with your document ID. You can edit keywords, country, time period and record limit in this single node. Keep the default configuration for your first test:

{
"queries": ["Microsoft"],
"edition": "en-US",
"period": "week",
"maxItemsPerQuery": 10,
"resolveArticleUrls": false,
"maxTotalChargeUsd": 0.005,
"spreadsheetId": "PASTE_YOUR_SPREADSHEET_ID",
"sheetName": "News"
}

This bundled workflow retains the simple collection configuration; it does not export advanced publisher metadata or custom dates. Choose the Google News edition explicitly: en-US, en-GB, it-IT, de-DE, fr-FR or es-ES. Period accepts day, week or month. The workflow checks your configuration before starting a paid run.

3. Connect credentials

In any of the four HTTP Request nodes, create a Bearer Auth credential. Enter your Apify token in the token field, without adding a Bearer prefix. Select this same credential in Start Actor, Wait for Run, Get Run Summary and Get Dataset Items.

Keep the token in n8n credentials; do not paste it into the workflow JSON, a query string or the Configuration node. Apify API authentication.

In Save News to Google Sheets, select your Google Sheets OAuth2 credential. Verify these settings:

SettingValue
OperationAppend or Update Row
DocumentID from Configuration
SheetNews, or the name from Configuration
MappingMap Automatically
Column to match onid
Cell formatRAW

If the editor asks you to refresh column mappings, refresh them after selecting the document and tab, then keep id as the matching column. RAW stores strings as data, including headlines that start with an equals sign. Google Sheets node operations.

4. Run a first test

Click Execute Workflow. The flow:

Manual run → check configuration → run Actor → verify complete output → map news → append or update rows by article ID.

The default example returns up to 10 records, not a guaranteed 10: Google News may have fewer matching articles. Publication dates and collection timestamps remain ISO strings in the sheet. matchedQueries is flattened into a text field.

With direct links disabled, articleUrl is empty and googleNewsUrl is your usable news link. Enable resolveArticleUrls if you need verified publisher article URLs. This takes longer; the sample workflow keeps a conservative 200-requested-record limit and 120-second run timeout. The Actor itself supports larger inputs with a longer time budget. The workflow rejects incomplete output if any requested links cannot be verified. Article bodies and paywalled content are not included.

The Actor deduplicates overlapping queries within one run. The sheet additionally matches id across runs: existing IDs are updated, new IDs are appended. This does not remove pre-existing duplicate rows or save Actor charges on repeated collection. Metadata and matched queries for an existing row are replaced by the latest run’s values; this is a current monitoring sheet, not an immutable event log.

Costs and scheduling

At the current list price, the Actor charges $0.0015 per start + $0.0002 per saved news record, including Actor platform usage at the prescribed 128 MB. Startup also applies when no articles are returned. n8n hosting and any separate storage/read/transfer charges are outside this estimate; check current pricing before enabling a schedule.

ConfigurationMaximum Actor charge per run30 runs, one per day
1 keyword × 10 records$0.0035$0.105
2 keywords × 10 records$0.0055$0.165
1 keyword × 100 records$0.0215$0.645

Set maxTotalChargeUsd at least as high as the configured maximum: 0.0015 + 0.0002 × keywords × maxItemsPerQuery. For two keywords with 10 articles each, a cap of $0.01 is sufficient. Overlapping queries can reduce the saved count and charge. The default $0.005 cap covers the default single-keyword example.

After one successful manual run, you may replace the Manual Trigger with a Schedule Trigger, choose your timezone and run once daily. Publish/activate only when you are ready for repeated charges. The supplied workflow is inactive and contains no schedule.

Errors and recovery

  • Configuration error: no Actor is started. Fix the document ID, input or spending cap first.
  • Run is RUNNING/READY: the two API calls wait up to 60 seconds each. Open the given run ID in Apify Console. If it is still running, wait for completion and retrieve that run’s outputs; do not retry Start Actor just to download them.
  • FAILED, TIMED-OUT or ABORTED: inspect the run log and RUN_SUMMARY; the workflow stops before writing to Sheets. A start fee and charges for already saved records may still apply.
  • Incomplete/budget-limited output: the workflow stops instead of silently exporting a partial set. Inspect the summary before deliberately retrying with another budget.
  • No results: a complete empty run leaves the sheet unchanged; this is not necessarily an error.
  • Google Sheets permission/header error: fix access or headers. Reuse the successful run’s dataset rather than launching another paid run. If a write was partly completed, reprocessing the same dataset with matching id updates those rows instead of adding another copy, provided the sheet has unique IDs and no concurrent writer.
  • Network error on Start Actor: automatic retries are disabled for the POST. Check whether Apify created a run before launching another one. GET requests retry safely up to three times.

Validation scope

The default input was run against the released Apify Actor on 10 October 2026: 10 records, complete: true. The importable JSON was imported into n8n 2.42.6 and executed with those real output shapes against a local mock API, through the sheet boundary. Additional tests exercise the official Google Sheets node with mocked transport: append, update on a repeat run, and RAW value handling. Tests also reject failed/pending runs, partial output, duplicate IDs and an insufficient spending cap.

A live write to a user-owned Google Sheet has not been tested. Your OAuth credential and sheet must be connected for that final check. No token, credential ID, sheet ID or customer data is included in the template.

More ready-to-run monitoring examples

Use caseExample
Track brands and competitorsMicrosoft and Google news
Follow AI industry headlinesArtificial intelligence news
Try publisher metadata separately from this simple workflowArticle descriptions and images

For search interest over time, see Google Trends Keyword History. For public-channel updates, see Telegram New Posts Monitor. These are separate Actors with their own pricing.

Importable workflow JSON

Copy the JSON below into a .json file and import it in n8n.

{
"name": "Google News to Google Sheets — budget-capped brand monitoring",
"nodes": [
{
"id": "news-1",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
200
],
"parameters": {}
},
{
"id": "news-2",
"name": "Configuration",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
240,
200
],
"parameters": {
"mode": "raw",
"jsonOutput": "{\n \"queries\": [\n \"Microsoft\"\n ],\n \"edition\": \"en-US\",\n \"period\": \"week\",\n \"maxItemsPerQuery\": 10,\n \"resolveArticleUrls\": false,\n \"maxTotalChargeUsd\": 0.005,\n \"spreadsheetId\": \"PASTE_YOUR_SPREADSHEET_ID\",\n \"sheetName\": \"News\"\n}",
"options": {}
},
"notes": "Edit queries and spreadsheetId here. Default: at most 10 records, $0.005 run cap, US edition. No schedule is enabled.",
"notesInFlow": true
},
{
"id": "news-3",
"name": "Validate Configuration",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
480,
200
],
"parameters": {
"jsCode": "const c = $input.first().json;\nif (!c.spreadsheetId || c.spreadsheetId === 'PASTE_YOUR_SPREADSHEET_ID') throw new Error('Set spreadsheetId in Configuration before running.');\nif (!Array.isArray(c.queries) || !c.queries.length || c.queries.length > 20 || c.queries.some(q => typeof q !== 'string' || !q.trim())) throw new Error('Provide 1–20 non-empty queries.');\nif (!Number.isInteger(c.maxItemsPerQuery) || c.maxItemsPerQuery < 1 || c.maxItemsPerQuery > 100) throw new Error('maxItemsPerQuery must be 1–100.');\nif (typeof c.resolveArticleUrls !== 'boolean') throw new Error('resolveArticleUrls must be true or false.');\nif (!['en-US','en-GB','it-IT','de-DE','fr-FR','es-ES'].includes(c.edition) || !['day','week','month'].includes(c.period)) throw new Error('Choose a supported edition and period.');\nif (!Number.isFinite(c.maxTotalChargeUsd) || c.maxTotalChargeUsd < 0.0017) throw new Error('Run cap must be at least $0.0017.');\nconst maxRows = c.queries.length * c.maxItemsPerQuery;\nif (c.resolveArticleUrls && maxRows > 200) throw new Error('Direct links support at most 200 requested records per run.');\nconst estimatedMaximum = 0.0015 + maxRows * 0.0002;\nif (c.maxTotalChargeUsd + 1e-10 < estimatedMaximum) throw new Error('Cap is below the configured maximum ($' + estimatedMaximum.toFixed(4) + '). Reduce records or increase the cap.');\nreturn [{json:c}];"
}
},
{
"id": "news-4",
"name": "Start Actor",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
200
],
"parameters": {
"method": "POST",
"url": "https://api.apify.com/v2/actors/monkey.d.scraping~google-news-scraper-lite/runs",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {
"timeout": 75000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "waitForFinish",
"value": "60"
},
{
"name": "timeout",
"value": "120"
},
{
"name": "memory",
"value": "128"
},
{
"name": "build",
"value": "latest"
},
{
"name": "restartOnError",
"value": "false"
},
{
"name": "maxTotalChargeUsd",
"value": "={{ $json.maxTotalChargeUsd }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({queries:$json.queries, edition:$json.edition, period:$json.period, maxItemsPerQuery:$json.maxItemsPerQuery, resolveArticleUrls:$json.resolveArticleUrls}) }}"
},
"retryOnFail": false,
"maxTries": 3,
"waitBetweenTries": 1000,
"notes": "Select the same Apify Bearer Auth credential on all four HTTP nodes. Never enable automatic retries on Start Actor: a repeated POST can start and bill another run.",
"notesInFlow": false
},
{
"id": "news-5",
"name": "Wait for Run",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
960,
200
],
"parameters": {
"method": "GET",
"url": "=https://api.apify.com/v2/actor-runs/{{ $json.data.id }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {
"timeout": 75000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "waitForFinish",
"value": "60"
}
]
}
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"notes": "Select the same Apify Bearer Auth credential on all four HTTP nodes. Never enable automatic retries on Start Actor: a repeated POST can start and bill another run.",
"notesInFlow": false
},
{
"id": "news-6",
"name": "Validate Run",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1200,
200
],
"parameters": {
"jsCode": "const r = $input.first().json.data;\nif (!r?.id) throw new Error('Missing Apify run ID.');\nif (r.status !== 'SUCCEEDED') throw new Error('Apify run ' + r.id + ' is ' + r.status + '. Inspect it in Console. If still running, resume with Wait for Run using this ID after it finishes; do not restart Start Actor to fetch the same results.');\nif (!r.defaultDatasetId || !r.defaultKeyValueStoreId) throw new Error('Run has no output storage IDs.');\nreturn [{json:r}];"
}
},
{
"id": "news-7",
"name": "Get Run Summary",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1440,
200
],
"parameters": {
"method": "GET",
"url": "=https://api.apify.com/v2/key-value-stores/{{ $json.defaultKeyValueStoreId }}/records/RUN_SUMMARY",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {
"timeout": 75000,
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"notes": "Select the same Apify Bearer Auth credential on all four HTTP nodes. Never enable automatic retries on Start Actor: a repeated POST can start and bill another run.",
"notesInFlow": false
},
{
"id": "news-8",
"name": "Check Complete Output",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
200
],
"parameters": {
"jsCode": "const s = $input.first().json;\nif (s.complete !== true || s.budgetLimited === true || s.queriesFailed > 0 || s.queriesSkipped > 0) throw new Error('Apify output is partial or unverified. Inspect RUN_SUMMARY before exporting. No sheet rows were written.');\nif (!Number.isInteger(s.savedRows) || s.savedRows < 0) throw new Error('Invalid savedRows in RUN_SUMMARY.');\nreturn [{json:{datasetId:$('Validate Run').first().json.defaultDatasetId, expectedRows:s.savedRows}}];"
}
},
{
"id": "news-9",
"name": "Get Dataset Items",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1920,
200
],
"parameters": {
"method": "GET",
"url": "=https://api.apify.com/v2/datasets/{{ $json.datasetId }}/items",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {
"timeout": 75000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "clean",
"value": "true"
},
{
"name": "format",
"value": "json"
},
{
"name": "limit",
"value": "2000"
}
]
}
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"notes": "Select the same Apify Bearer Auth credential on all four HTTP nodes. Never enable automatic retries on Start Actor: a repeated POST can start and bill another run.",
"notesInFlow": false
},
{
"id": "news-10",
"name": "Prepare Sheet Rows",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
200
],
"parameters": {
"jsCode": "const input = $input.all();\nconst rows = input.flatMap(i => Array.isArray(i.json) ? i.json : [i.json]);\nconst expected = $('Check Complete Output').first().json.expectedRows;\nif (rows.length !== expected) throw new Error('Dataset row count mismatch; no rows exported.');\nconst seen = new Set();\nreturn rows.map(r => {\n if (typeof r.id !== 'string' || !r.id || seen.has(r.id)) throw new Error('Missing or duplicate article ID.');\n seen.add(r.id);\n const keys = ['id','title','publisher','publishedAt','articleUrl','googleNewsUrl','edition','collectedAt','articleUrlStatus'];\n const out = Object.fromEntries(keys.map(k => [k, r[k] == null ? '' : String(r[k])]));\n out.matchedQueries = Array.isArray(r.matchedQueries) ? r.matchedQueries.join(' | ') : String(r.query ?? '');\n return {json:out};\n});"
}
},
{
"id": "news-11",
"name": "Save News to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.6,
"position": [
2400,
200
],
"parameters": {
"resource": "sheet",
"operation": "appendOrUpdate",
"documentId": {
"__rl": true,
"value": "={{ $('Configuration').first().json.spreadsheetId }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "={{ $('Configuration').first().json.sheetName }}",
"mode": "name"
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {},
"matchingColumns": [
"id"
],
"schema": [
{
"id": "id",
"displayName": "id",
"required": false,
"defaultMatch": true,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "title",
"displayName": "title",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "publisher",
"displayName": "publisher",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "publishedAt",
"displayName": "publishedAt",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "articleUrl",
"displayName": "articleUrl",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "googleNewsUrl",
"displayName": "googleNewsUrl",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "matchedQueries",
"displayName": "matchedQueries",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "edition",
"displayName": "edition",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "collectedAt",
"displayName": "collectedAt",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "articleUrlStatus",
"displayName": "articleUrlStatus",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {
"cellFormat": "RAW",
"handlingExtraData": "ignoreIt"
}
},
"notes": "Select your Google Sheets OAuth2 credential. Create the News tab with the exact headers from the tutorial. Append or Update matches id; RAW stores headlines as text.",
"notesInFlow": true
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Configuration",
"type": "main",
"index": 0
}
]
]
},
"Configuration": {
"main": [
[
{
"node": "Validate Configuration",
"type": "main",
"index": 0
}
]
]
},
"Validate Configuration": {
"main": [
[
{
"node": "Start Actor",
"type": "main",
"index": 0
}
]
]
},
"Start Actor": {
"main": [
[
{
"node": "Wait for Run",
"type": "main",
"index": 0
}
]
]
},
"Wait for Run": {
"main": [
[
{
"node": "Validate Run",
"type": "main",
"index": 0
}
]
]
},
"Validate Run": {
"main": [
[
{
"node": "Get Run Summary",
"type": "main",
"index": 0
}
]
]
},
"Get Run Summary": {
"main": [
[
{
"node": "Check Complete Output",
"type": "main",
"index": 0
}
]
]
},
"Check Complete Output": {
"main": [
[
{
"node": "Get Dataset Items",
"type": "main",
"index": 0
}
]
]
},
"Get Dataset Items": {
"main": [
[
{
"node": "Prepare Sheet Rows",
"type": "main",
"index": 0
}
]
]
},
"Prepare Sheet Rows": {
"main": [
[
{
"node": "Save News to Google Sheets",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"pinData": {},
"tags": [],
"id": "googleNewsSheetsTemplate"
}

More Actors by Monkey D. Scraping

Combine news research with these complementary tools from the same developer. Each Actor runs separately with its own inputs and pricing.

Recommended ActorWhen to use it
Google Trends Scraper — Keyword History APICompare news coverage with keyword search-interest history by country and period.
Telegram New Posts Monitor & Channel DiscoveryFollow new posts from public Telegram channels using saved task checkpoints, alongside your news-monitoring workflow.

If a dataset write cannot be confirmed

The Actor stops further dataset writes with POST_STORAGE_UNCONFIRMED after a storage, billing acknowledgement or cancellation error. Other workers and the abort handler do not resubmit the uncertain batch. Records from earlier acknowledged batches remain available.

An error can occur after the platform accepted a batch, so a failed run does not prove that it saved no records or incurred no charges. Inspect the existing dataset before starting a separate run and deduplicate by id. A storage failure can prevent the final RUN_SUMMARY from being saved; the Actor does not treat that run as complete.

Why do query counts differ from the number of news rows?

An article found by several searches is saved once. query is the first associated search, not a complete count of matches. Use every value in matchedQueries when grouping articles by search; those per-search counts can add up to more than the number of unique articles. These are matches returned by Google News, not an independent check that the exact phrase appears in the headline or refers to the intended person.

The default News headlines view puts all matching searches and the available Google News link next to the headline. Open Publisher links and metadata for optional direct links, descriptions, images and their status, or All article fields for the complete record.

If resolveArticleUrls is false, articleUrl is null and articleUrlStatus is not_requested by design. Open googleNewsUrl to read the Google News result. publisherHomepage is the publication homepage, not the article. Selecting an output view does not enable URL resolution or enrichment and does not change charges.

Real observed output excerpt

Reduced record from an owner verification run observed on 19 October 2026. Field values are retained from that observation and may have changed since then.

{
"query": "Microsoft",
"matchedQueries": [
"Microsoft"
],
"title": "Lifetime access to Microsoft Word, Excel, PowerPoint, and more is now just $49.97 - PCWorld",
"publishedAt": "2026-10-19T08:05:58+00:00",
"publisher": "PCWorld",
"googleNewsUrl": "https://news.google.com/rss/articles/CBMivwFBVV95cUxPZWpJU29YaW1zcF9YamNhYmk5aHU0elZhSHloQm9kRzZuckhXSlhrUWNRVmlKS3dHRzkxZ0VQY1ZjWTJKTEJycWk2WVNfSV9YOXJia2pBa0pCSE52QVA1MXFpWmIxS1cydFZiMFRYT18wVFBRa3ZvSE02RFlKWThRWVV0STlNVmI5Vzd2VkJwdzJpM2pzUWRaSFAtdnNiOS1rTHdBV2tQQUhVbGN4MlAwNDl5cnozdWFRQlpDY3U4RQ?oc=5",
"articleUrl": null,
"articleUrlResolved": false,
"articleUrlStatus": "not_requested",
"edition": "en-US",
"collectedAt": "2026-10-19T10:51:11.195424+00:00",
"source": "google-news-rss"
}

Other fields are omitted here. The article URL is null because resolution was not requested, not because resolution failed. Use googleNewsUrl as the source link in this mode. The headline is publisher content, not a verified commercial offer. matchedQueries reports searches associated with this saved item; it does not prove complete news coverage.