# Google Shopping Feed vs Website Checker (`egeusta/feed-consistency-checker`) Actor

Compare a public Google Shopping XML, CSV, or TSV feed with live product pages. Find price and stock mismatches, dead or redirected links, duplicate IDs, and missing product data before ads or customers discover them.

- **URL**: https://apify.com/egeusta/feed-consistency-checker.md
- **Developed by:** [Ege Usta](https://apify.com/egeusta) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 feed item checkeds

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

**Catch feed-to-store drift before customers—and ad platforms—do.**

Merchant Feed Consistency Checker reads a public Google Merchant product feed and compares each selected item with the live product page it links to. It detects price drift, availability disagreements, dead links, redirects, missing links, duplicate IDs, and pages whose product data cannot be extracted reliably.

Use it before submitting a feed, after catalog or storefront deployments, and on a schedule to catch quiet inconsistencies that can waste ad spend or trigger Merchant Center disapprovals.

### Quick start

```json
{
  "feedUrl": "https://shop.example/google-merchant-feed.xml",
  "maxItems": 100,
  "sampleEvery": 1,
  "onlyMismatches": true,
  "maxFeedMegabytes": 64
}
```

The feed must be reachable without a login. Supported formats include Google Shopping XML/RSS/Atom, CSV, and TSV; plain and gzip-compressed files are accepted.

### What it checks

For every selected feed item, the Actor compares the feed with public product-page signals:

- Feed price versus live-page price
- Feed availability versus live-page availability
- HTTP errors and dead product links
- Redirected product URLs
- Missing product links
- Duplicate product IDs
- Product data that is absent from the live page

The page extractor prefers structured product data where available and normalizes prices and availability before comparing them.

### Why feed drift is easy to miss

A feed generator and a storefront often update on different schedules. Each system can appear healthy while the values customers see no longer match the values sent to an ad platform. The result can be wasted clicks, disapprovals, or confusing landing pages without any obvious application error.

This Actor turns that silent failure into a deterministic dataset with feed values, page values, the numeric difference, HTTP evidence, and a per-run summary.

### Input

| Field | Description |
|---|---|
| `feedUrl` | Public XML, CSV, or TSV feed URL |
| `maxItems` | Maximum products compared with live pages |
| `sampleEvery` | Check every Nth item across the feed |
| `onlyMismatches` | Omit consistent item rows; omitted rows are not charged |
| `maxFeedMegabytes` | Download limit for unexpectedly large feeds |
| `crawlerIdentity` | Optional custom User-Agent |

For a large catalog, start with `maxItems: 100` or increase `sampleEvery` to sample the entire file rather than checking only its first products.

### Output

The default dataset uses one **Feed consistency results** view. Check `rowType` to distinguish three records.

#### Item comparison

```json
{
  "rowType": "item",
  "ok": true,
  "id": "SKU-1042",
  "title": "Trail Runner",
  "link": "https://shop.example/products/trail-runner",
  "position": 42,
  "mismatches": ["price"],
  "feedPrice": 89.99,
  "pagePrice": 94.99,
  "priceDelta": 5,
  "feedAvailability": "in_stock",
  "pageAvailability": "in_stock",
  "httpStatus": 200
}
```

#### Unreachable page

A free, ungraded row with the feed ID, product URL, position, HTTP status, and network error. A request timeout is not reported as a merchant mismatch.

#### Run summary

A free row with detected feed format, parsed items, checked items, products with problems, price mismatches, availability mismatches, dead links, duplicate IDs, and truncation status.

### Pricing

Pay per event:

- **$0.01 per Actor start** at the default 512 MB memory
- **$0.002 per delivered item comparison** — $2.00 per 1,000
- Unreachable pages are free
- The run summary is free
- Products omitted by `onlyMismatches` are free
- Apify platform usage is included

Examples before user-level discounts:

| Delivered comparisons | Estimated price |
|---:|---:|
| 10 | $0.03 |
| 100 | $0.21 |
| 1,000 | $2.01 |

The Actor honors the maximum total charge configured for a run and stops before continuing unpaid work.

### Sampling large feeds

`sampleEvery` selects products throughout the feed instead of taking only the first page. For example, `sampleEvery: 10` checks roughly 10% of the feed, subject to `maxItems`. This is useful for daily health checks on catalogs with tens of thousands of products.

Use `maxFeedMegabytes` as a safety limit. If the feed exceeds it, the Actor marks `truncated: true` in the summary so the result cannot be mistaken for a full audit.

### Reliability

Requests to one host are rate-limited, body sizes and timeouts are capped, and HTTP 429 receives a backed-off retry. The feed URL and product URLs must be public. The Actor does not log in, bypass paywalls, solve anti-bot challenges, or upload anything to Merchant Center.

A product page that cannot be reached due to a network failure is returned as `unreachable`, free, and compared against nothing. HTTP statuses observed from a reached server remain useful evidence for dead-link checks.

### Limitations

- The Actor compares public feed and page signals; it does not access your Merchant Center account or Diagnostics tab.
- No JavaScript rendering: values that exist only after client-side execution may not be visible in the initial HTML.
- Price comparison uses normalized numeric values. Taxes, shipping, market-specific prices, variants, or logged-in pricing can legitimately differ.
- Availability vocabularies are normalized, but custom text can remain unknown.
- CSV and TSV column names must be recognizable feed fields.
- Results are point-in-time checks and can change when the feed or storefront updates.

### Automation

Schedule the Actor hourly, daily, or after feed-generation deployments. Use Apify webhooks and integrations to send mismatches to a spreadsheet, database, Slack workflow, ticketing system, or downstream Actor.

### Responsible use and support

Check only feeds and public pages you are authorized to audit. Follow applicable website terms, laws, advertising policies, and organizational rules. The output is technical evidence, not a guarantee of Merchant Center approval and not legal or financial advice.

For support, open an Actor issue with the run ID, a sanitized feed sample, and one unexpected dataset row. Never post credentials, private feeds, or customer data.

# Actor input Schema

## `feedUrl` (type: `string`):

Google Merchant XML/RSS/Atom, CSV, or TSV feed. Plain and gzip-compressed feeds are supported.

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

Hard cap on feed items compared with live product pages.

## `sampleEvery` (type: `integer`):

1 checks every item. Use 10 to check an evenly distributed tenth of a large feed.

## `onlyMismatches` (type: `boolean`):

Omit consistent products from the dataset. Omitted products are not charged.

## `maxFeedMegabytes` (type: `integer`):

Stop reading after this many megabytes and mark the run as truncated.

## `crawlerIdentity` (type: `string`):

Optional crawler identity for live product-page requests.

## Actor input object example

```json
{
  "feedUrl": "https://gist.githubusercontent.com/marcosnakamine/acc1be40f6606c397b3c8bbd7f8b689c/raw/example_feed_xml_rss.xml",
  "maxItems": 25,
  "sampleEvery": 1,
  "onlyMismatches": true,
  "maxFeedMegabytes": 64
}
```

# Actor output Schema

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

The default dataset. Use rowType to distinguish item, unreachable, and summary rows.

# 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 = {
    "feedUrl": "https://gist.githubusercontent.com/marcosnakamine/acc1be40f6606c397b3c8bbd7f8b689c/raw/example_feed_xml_rss.xml"
};

// Run the Actor and wait for it to finish
const run = await client.actor("egeusta/feed-consistency-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 = { "feedUrl": "https://gist.githubusercontent.com/marcosnakamine/acc1be40f6606c397b3c8bbd7f8b689c/raw/example_feed_xml_rss.xml" }

# Run the Actor and wait for it to finish
run = client.actor("egeusta/feed-consistency-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 '{
  "feedUrl": "https://gist.githubusercontent.com/marcosnakamine/acc1be40f6606c397b3c8bbd7f8b689c/raw/example_feed_xml_rss.xml"
}' |
apify call egeusta/feed-consistency-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,egeusta/feed-consistency-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/4ucb22W1MYCp8zz6n/builds/THxH4srGT1RWvjHiH/openapi.json
