# Commerce Stack Evidence Checker (`sailing/commerce-stack-evidence-checker`) Actor

Check up to 100 public website homepages for Shopify, WooCommerce, GA4, GTM and six more commerce tools. Get page evidence, JSON/CSV results and changes from previous checks. HTML only; no JavaScript rendering.

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

## Pricing

from $5.00 / 1,000 completed homepage checks

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

## Commerce Stack Evidence Checker

**Check Shopify, WooCommerce, analytics, pixels, chat, and review tools—with evidence for each match.**

Review up to 100 public website homepages per run. Built for ecommerce agencies and website service providers checking a client-supplied website list. Get JSON and CSV results, then compare a later check with your saved baseline to spot changes in observed signals.

### What it checks

Shopify, WooCommerce, Google Analytics 4 (GA4), Google Tag Manager (GTM), Meta Pixel, Klaviyo, Gorgias, Intercom, Judge.me, and Yotpo.

The Actor examines the homepage's HTTP response for recognized scripts, assets, metadata, and integration configuration. It returns a timestamp, final URL, check status, and supporting evidence for each detected technology. It checks the initial HTML; it does not execute JavaScript or confirm that an integration is working.

Use it to prepare website audit reports, review a list before a client call, or compare scheduled snapshots. A result is a starting point for an evidence-based review, not a complete inventory of everything a website uses.

### Quick start

1. Enter your public website URLs in **Public website URLs**.
2. Optionally add an earlier JSON output to **Previous results**.
3. Set your maximum run charge, then start the Actor.
4. Open **JSON results**, **CSV evidence**, and **Completion and billing summary** in the run output.

```json
{
  "urls": ["https://www.allbirds.com/"],
  "previousResults": []
}
```

This example checks a real public homepage. Its content and detected signals can change between runs.

Supply 1–100 URLs. Paths, query strings, and fragments are discarded; the Actor checks the homepage once per unique hostname. For example, two product URLs on `store.example.com` become one homepage check. `example.com` and `www.example.com` remain separate hostnames. An invalid or explicitly non-public input rejects the input before any homepage checks begin. Private network destinations and redirects to them are blocked.

### Understand the results

| Field and value | Meaning |
| --- | --- |
| Overall `status: completed` | The homepage response was retrieved and parsed within the check limits. It can contain zero detected technologies. |
| Overall `status: unknown` | The check could not be completed. The `error` field explains why. |
| Technology `status: found` | The response contains a recognized signal for that technology. Inspect its evidence. |
| Technology `status: not_observed` | No supported signal was found in this response. This does not establish that the technology is absent. |
| Technology `status: unknown` | The check could not determine whether the technology is present. |

JSON contains one result per checked hostname and ten technology entries per result. Each evidence item includes its type, a sanitized description of the matched signal, and the page URL. Account and tracking IDs are redacted; full HTML is not included in the delivered results.

For example, a saved Allbirds homepage response contained the Shopify configuration summarized by this evidence entry:

```json
{
  "name": "Shopify",
  "status": "found",
  "evidence": [
    {
      "kind": "inline_signature",
      "value": "Shopify.shop = '[store-redacted].myshopify.com'",
      "source_url": "https://www.allbirds.com/"
    }
  ]
}
```

This is an excerpt from a local check on September 13, 2026, not a claim about the site's current state. A full result also includes `input_url`, `final_url`, `checked_at`, `http_status`, `source_sha256`, `result_id`, and `changes`.

CSV contains one row per website–technology pair, so one completed homepage produces ten CSV rows. You pay per completed homepage, not per technology or CSV row.

### Compare repeat checks

Save the **JSON results** array and supply it as `previousResults` on a later run. The comparison reports `newly_observed`, `no_longer_observed`, or `unknown` changes. **No longer observed does not mean uninstalled.** A blocked or incomplete check cannot establish removal.

Keep your last completed baseline when a website temporarily returns `unknown`. An independent new run is a new check and can incur new charges.

### Pricing and spending limits

| Event | Price |
| --- | --- |
| Completed homepage check (`domain-check`) | **$0.005 each — $5 per 1,000** |
| Actor startup (`apify-actor-start`) | **$0.00005 per startup event** |

Platform usage is included in this Actor's event price. A normal run with 100 completed unique homepage checks and one startup event costs **$0.50005** in event fees. The Actor's Pricing tab is authoritative.

An `unknown`, incomplete, or unprocessed homepage has no completed-check charge. A successfully parsed homepage with no detected technologies is still a completed, chargeable check. The startup event can apply even when no homepage check completes.

Set a maximum run charge in Apify, or use `maxTotalChargeUsd` through the API. For example, `$0.55` covers 100 completed checks and one startup at these prices. This is a per-run limit, not a monthly spending limit. The Actor stops further work when its charge budget is exhausted; partial output can include completed rows that were not charged. `billable: true` means eligible for charging, not proof that a charge succeeded.

### API and n8n

Use the Actor's API tab or the [Apify run API](https://docs.apify.com/api/v2/actors-runs-post). The Actor ID is `MUyHYSDDeQjXdbfBA`.

```text
POST https://api.apify.com/v2/actors/MUyHYSDDeQjXdbfBA/runs?memory=256&timeout=900&maxTotalChargeUsd=0.55&restartOnError=false
Authorization: Bearer YOUR_APIFY_TOKEN
Content-Type: application/json
```

Send the input JSON above as the request body. Save the returned run ID, then poll `GET /v2/actor-runs/{runId}`. When the run succeeds, use its `defaultKeyValueStoreId` to download these [key-value store records](https://docs.apify.com/api/v2/key-value-store-record-get):

| Record | Contents |
| --- | --- |
| `OUTPUT` | Canonical JSON results array |
| `OUTPUT.csv` | CSV evidence rows |
| `SUMMARY` | Completed, unknown, and unprocessed counts, stop reason, and billing phases |

The record URL is `https://api.apify.com/v2/key-value-stores/{storeId}/records/{record}`. Send the same authorization header. Keep tokens in your credential store, outside URLs and workflow exports.

For n8n, use **Schedule Trigger → HTTP Request to start once → Wait and poll the run → HTTP Request to read OUTPUT**. Save the previous completed results in your own workflow or storage and pass them to the next run. Check `SUMMARY` as well as the platform's run status: a finished process can have partial results.

If a start request times out, check the existing run list before starting again. If a run is interrupted, inspect its saved output and individual `RESULT-*` records before retrying. Uncertain charging outcomes stop processing and are not automatically charged again. The dataset is a convenient view, but append retries can duplicate rows and interruption can leave it incomplete; use `OUTPUT` for integrations.

### Scope and limitations

- **Static evidence, not execution:** a script reference or configuration can remain after a service is disabled, or occur in a branch that never runs. A match does not prove an active subscription, successful tracking, or a working integration.
- **Homepage only:** product-page integrations, server-side tracking, and tools loaded only after navigation may be missed.
- **No browser rendering:** consent-triggered tags, dynamically injected scripts, custom proxies, obfuscated code, and unrecognized vendor changes can be missed. GA4 and GTM are separate checks; one does not imply the other.
- **Explicit access failures:** robots restrictions, access blocks, timeouts, unsupported response formats or compression, and size or parsing limits return `unknown`. The Actor does not log in or bypass these restrictions.

For a support request, include the run ID, affected public URL, and the signal you expected versus the result you received. Include a short relevant page-code excerpt if available; do not share API tokens or private account details.

# Actor input Schema

## `urls` (type: `array`):

1–100 public websites. Paths and queries are discarded; one homepage per hostname is checked.

## `previousResults` (type: `array`):

Previous OUTPUT JSON array for the same websites. Unknowns never count as removal.

## Actor input object example

```json
{
  "urls": [
    "https://www.allbirds.com/"
  ],
  "previousResults": []
}
```

# Actor output Schema

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

No description

## `csv` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {
    "urls": [
        "https://www.allbirds.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sailing/commerce-stack-evidence-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 = { "urls": ["https://www.allbirds.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("sailing/commerce-stack-evidence-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 '{
  "urls": [
    "https://www.allbirds.com/"
  ]
}' |
apify call sailing/commerce-stack-evidence-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sailing/commerce-stack-evidence-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/MUyHYSDDeQjXdbfBA/builds/BXwyends7qrhKC5zd/openapi.json
