# Similarweb Monthly Traffic Changes & Channel Comparison (`ntriqpro/similarweb-traffic-change-insights`) Actor

Similarweb data you already scraped, compared across two different data months: per domain and month, visits change, channel and country share shifts, new and lost referrers and keywords, ranks, competitor share, data conflicts. AI and summaries on paid plans. 3 domains × 12 months: $1.89 on BRONZE.

- **URL**: https://apify.com/ntriqpro/similarweb-traffic-change-insights.md
- **Developed by:** [daehwan kim](https://apify.com/ntriqpro) (community)
- **Categories:** SEO tools, Business, AI
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.40 / 1,000 domain × month compareds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

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

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

## How to integrate an Actor?

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

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

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

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

# README

## Similarweb Monthly Traffic Changes & Channel Comparison

You already scrape Similarweb. This Actor takes those results and turns them into **one row per domain and month**: how visits moved against the month before, which traffic channels moved with them, which countries, referring sites and search keywords came and went, how ranks and your share of a competitor group changed, and **what in the data does not add up**.

**What it needs: two different data months of the same domain** — the month the numbers are *of* (`snapshotDate`, `engagementMonth`), not the day you scraped. Two scrapes of the same data month are merged into one row (`duplicate-snapshot` conflict), not compared. One scrape whose rows carry a monthly-visits list (`estimatedMonthlyVisits`, `monthlyVisits`) also works: those months get visits-only rows.

It reads your data; it does not scrape. It shows **what moved together** in your data — **not proof of what caused them**: it will not tell you *why* traffic moved, only what moved with it.

| | Free plan (preview) | Paid Apify plan |
|---|---|---|
| Domain × month rows | the first 5 (domains in input order, newest month first): the **verdict** (`up`, `down`, `steady`, `baseline`, `unknown`) and **one sign without numbers** (the channel that moved most with the total) | every month (`maxPeriodsPerDomain`, default 12; `maxPeriods` a run, default 2,000), **in full** |
| Visits, channel, country, referral, keyword, rank and competitor-group numbers, measurement conflicts | locked — each locked field says how many a paid run gives for that row (`{ "locked": true, "count": 2, "paidGets": "…" }`) | all of them |
| AI explanation of each change (checked against the row's numbers) | locked — no model is called | on (`aiExplanations`), up to `aiMaxPeriods` a run |
| Domain and group summary rows | — | one per domain and one per group (`summaries`) |
| The last row | `free-plan-preview`: how many rows were found, how many are locked, what a paid run would add, its price estimate in the three ways to run it, and what this free run cost — all counted on your input | — |
| Price | FREE tier: a free run uses your plan's credit — **at most $0.105** for a normal run ($0.005 run start + 5 × $0.02) | tier discount below |

The whole paid output is shown on fixed, made-up data below (*Output*) and in the preview row's `example` field.

Paid-plan discounts on every event (Apify store tiers):

| Tier | Discount |
|---|---|
| FREE | 0% |
| BRONZE | 20% |
| SILVER | 35% |
| GOLD, PLATINUM, DIAMOND | 48% |

**Three ways to run it** — the same 3 competitor domains × 12 months (36 rows, 33 with a comparison, 3 domain summaries and 1 group summary), BRONZE:

| Run | Switches | Price |
|---|---|---|
| Rules only | `aiExplanations: false` and `summaries: false` | **$0.58** |
| Rules + summaries | `aiExplanations: false` | **$0.836** |
| Everything (default) | both on | **$1.892** |

Not in these prices: your Apify plan, and the runs of the scrapers that made your data. Inputs of more than 1,000 source rows add a `rows-read` event per further 1,000 rows (see *Pricing*). The free preview row gives these three prices for your own input.

### What it is for

- **"What moved with last month's drop?"** — the row says visits went down 20% and that the estimated search visits fell by 25,200 while direct stayed flat: search moved with the drop. It does not say why.
- **Competitor watch** — run the same scraper every month on your site and three rivals; get each one's rank and share of the group, and which channel each one gained or lost share of.
- **A sanity check before a report** — channel shares that add up to 95%, a missing month, two snapshots of the same month that disagree, a monthly-visits list that restates a number, two months taken from two different scrapers: each is flagged on the row as a `conflicts` entry.
- **New referrers and keywords** — what entered and left the top lists since the month before.

### Input

Give any of these (they can be mixed):

- `datasetIds` — datasets in your Apify account from a Similarweb scraper. The fields of these scrapers are recognised by themselves: tri_angle/similarweb-scraper, tri_angle/fast-similarweb-scraper, curious_coder/similarweb-scraper, pro100chok/similarweb-scraper (percent values too), radeance/similarweb-scraper, vortex_data/similarweb-scraper and memo23/similarweb-scraper.
- `csvUrls` / `jsonUrls` — public file addresses. An Apify CSV export works as is (its `trafficSources/directVisitsShare` and `topCountries/0/visitsShare` columns are folded back, and dotted headers such as `engagements.visits` are read as the fields they name), and so does your own monthly export with `domain`, `month`, `visits` and channel columns.
- `snapshots` — snapshots pasted as JSON in a scraper's shape.

What gives a comparison and what does not:

| Your input | What you get |
|---|---|
| The same domain in two **different data months** (e.g. a scrape in August and one in September) | a compared row for the later month (`up`/`down`/`steady`), a `baseline` row for the first |
| Two scrapes of the **same data month** (e.g. two days of the same week) | **one** row for that month (`duplicate-snapshot` conflict when their numbers differ), charged once — no comparison |
| One scrape with a monthly-visits list | one row per listed month, visits only (channels only where the snapshot has them) |
| One month of one domain | a `baseline` row (charged: the month was placed and checked, there is nothing to compare it with) |

Options: `domains` (keep only these), `groups` (competitor groups `[{ "name": "...", "domains": [...] }]`; with none given, all domains of the run form one group), `compareTo` (`previous` or `year-ago`), `minVisitsChangePct` (default 10), `minShareChange` (default 10 points), `maxPeriodsPerDomain`, `maxPeriods`, `aiExplanations`, `aiMaxPeriods`, `summaries`, `maxItemsPerSource`.

### Output

Every row has `recordType`.

#### `period` — one domain and one month

The made-up example below (`example-shop.com`, 2026-09 against 2026-08, in a group with `example-rival.com`) is exactly what the rules give for the example input; the `ai` part is a real answer of the model about this row that passed our checks.

- `verdict`: **down** — visits 120000 → 96000 (**-20%**).
- `channels`: search share **45% → 30% (-15 points)**, direct **40% → 50% (+10 points)**; with the estimated visits per channel (visits × share).
- `movedWith`: **search -25200 visits (105% of the total change)** — search moved with the drop; referral and mail rose a little.
- `countriesEntered`: FR · `countriesLeft`: DE.
- `referrals.new`: **coupons-example.org** · `referrals.gone`: deals-example.net · `keywords.new`: example sale.
- `groups[0]`: share of the group's visits **37.5% → 29.4%**; share of the group's search visits 35.1% → 18.5%; of its display visits 37.5% → 55.6% (`tookFrom` example-rival.com).
- `conflicts`: none here. Possible codes: `channel-shares-not-100`, `country-shares-over-100`, `period-gap`, `duplicate-snapshot`, `visits-disagree`, `visits-restated`, and `sources-differ` — the two months were read from two different scrapers' shapes, whose estimates often differ a lot (in the store examples, one scraper puts apify.com at 285,658 monthly visits and another at 1,911,397).
- `ai` (paid; the model's checked answer, `claude-haiku-5-5`):
  > "Visits fell 20% from August to September, with search traffic dropping while direct share rose."
  > change: search, down — "Search visits estimate fell from 54000 to 28800 and search share dropped 15 points, alongside a fall in the competitor group's search share." — facts: `search visits (estimate) 54000 → 28800 (-25200)`, `search share of visits 45% → 30% (-15 points)`, `share of the group's search visits 35.1% → 18.5% (-16.5 points)`

On a free plan the same row reads `verdict: "down"`, `evidence: { "kind": "moved-with-total", "channel": "search", "direction": "down" }`, and every other field above is `{ "locked": true, "count": …, "paidGets": "…" }`.

Other fields: `periodKey`, `domain`, `period`, `periodStart`, `periodEnd`, `comparedTo`, `comparedToBasis`, `visits` (`current`, `previous`, `change`, `changePct`, `source`), `channelsCompared`, `channelShifts`, `countries`, `countryShifts`, `keywords`, `ranks` (`global`, `country`, `category`: `current`, `previous`, `change` — negative is a better place), `note`, `sources`, `plan`, `locked`, `billedEvents`, `disclaimer`.

#### `domain-summary` and `group-summary` (paid)

- Domain: visits first to last month, best and worst month, channel shares first to last, the three biggest monthly moves and the channels that moved with them, countries in and out, conflicts by code, the AI headlines.
- Group: the ranking by visits for every month, rank changes first to last, and **per channel, who took share of the group's visits from that channel and who lost it** (`channelShareTakers`).

#### Notices and the run report

`noticeCode` rows explain what was skipped or stopped (not charged): `source-unreadable`, `source-no-snapshots`, `source-parse-error` (CSV rows with more cells than the header are left out: `skippedRows` and the first line; at a row that is not valid CSV — a quote never closed, or text right after a closing quote — reading of that file stops: the rows before it are read, from its line on (`notReadFromLine`, `restNotRead: true`) nothing is read or charged, and that part is said to be not read, not invalid), `rows-skipped`, `duplicate-input`, `input-limit`, `reading-stopped`, `charge-limit-reached`, `ai-off`, `ai-stopped-charge-limit`, `free-plan-preview` and others. A `run-started-marker` row (not charged) is written right before the run-start fee is asked for, so that a restarted run never asks for that fee twice; a `rows-read-marker` row (not charged) does the same right before each charge of `rows-read` events. A `limits` row and the `RUN-SUMMARY` key-value record hold the run's numbers (`reading`: rows read and `rows-read` events).

### The AI layer (paid plans)

For every month with a comparison and visits on both sides, the model (Anthropic `claude-haiku-5-5`) gets the row's numbers as numbered facts and writes what moved and what moved with it. Our code checks every answer before it is delivered or charged:

1. every change cites facts that were sent, and at least one cited fact of the change's own factor moved the way the change says;
2. every number it writes is in the data;
3. it states no cause ("because", "due to", "caused", "led to", "drove", "thanks to"…) — the data shows what moved together, not why;
4. no e-mail or web address.

An answer that fails is thrown away and **not charged**; the row keeps its rule comparison. Measured on 24 month rows (11 from the scrapers' public store examples, 13 built for Korean and English sites) before release: 23 answers passed the checks. **When AI is on, the row's numbers, domain names and keywords are sent to Anthropic's API (USA).** Free runs never call the model.

### Pricing

Pay per event; the list price (FREE tier) and the BRONZE price:

| Event | What one is | FREE | BRONZE |
|---|---|---|---|
| `run-started` | once per run that has something to read, before reading — it pays for the first 1,000 source rows | $0.005 | $0.004 |
| `rows-read` | paid plans: each further 1,000 source rows read (or part of them) — dataset rows, file rows, `snapshots` entries, also rows that are not snapshots | $0.002 | $0.0016 |
| `period-compared` | one domain×month row — also a baseline, steady or conflicting one | $0.02 | $0.016 |
| `change-explained` | one AI explanation that passed the checks (paid plans) | $0.04 | $0.032 |
| `domain-summary` | one domain or group summary row (paid plans) | $0.08 | $0.064 |

Example: 3 domains × 12 months = 36 rows (36 source rows: no `rows-read`), 33 with a comparison, 3 domain summaries and 1 group summary → BRONZE $0.004 + 36 × $0.016 + 33 × $0.032 + 4 × $0.064 = **$1.892**; rules only $0.58; rules + summaries $0.836. A dataset of 5,000 rows adds 4 × $0.0016 = $0.0064.

Your run's maximum charge is respected. The run asks before it reads: when the maximum charge no longer pays for the next 1,000 rows next to the rows of what it has read, it stops reading (`reading-stopped`) and compares what it read. It stops at the limit (SUCCEEDED) with a `charge-limit-reached` row, and when only the AI explanations no longer fit it stops those and goes on with the rule rows. A free run reads up to 5,000 source rows without `rows-read`; past that its counts are lower bounds. Platform usage is not passed on. Two runs started at the same time on the same input each deliver and charge their own rows.

Results are delivered first and charged after, and a row is never charged twice. A restarted run does not pay again for rows it already paid to read; if the platform's charge count does not yet show an earlier reading charge, that charge is not made again, it counts against your maximum charge, and reading stops where the count ends (run the same input again as a new run to read the rest). It first checks the platform's own charge count against the rows it already delivered; if some of them are not shown as charged, it does not charge them again and stops there. If a charge call fails, nothing more is delivered until the platform's own count shows it went through; if it does not show it, that charge is not made again and the run stops.

### Limits and accuracy

- Similarweb numbers are third-party estimates; this Actor lines them up and flags where they disagree, it does not correct them. Visits by channel are visits × share (estimates).
- A domain's share of a group is counted over the members with data in both months.
- At most 50 datasets and files, 100,000 snapshots and 20,000 domain×month rows a run; at most 500 `domains`, 50 `groups` and 50 domains in a group. What an input limit leaves out is said in an `input-limit` row, in `limits.input` (`snapshotsLeftOut`, `domainsLeftOut`, `groupsLeftOut`, `groupMembersLeftOut`) and in the status message.

### Responsibility

Unofficial tool, not affiliated with, endorsed by or sponsored by Similarweb or any scraper whose output it reads. It analyses only the data you supply and sends no messages. You are responsible for having the right to use this data and for complying with the law and the terms of the services it comes from. Every result row carries this notice in `disclaimer`.

# Actor input Schema

## `datasetIds` (type: `array`):

IDs of datasets in your Apify account with Similarweb results — runs of the same scraper in two or more different data months, or one run whose rows carry monthly visits. They are read with this run's own token; the run-start fee covers the first 1,000 rows read, each further 1,000 rows is one rows-read event on paid plans. The fields of tri_angle/similarweb-scraper, tri_angle/fast-similarweb-scraper, curious_coder/similarweb-scraper, pro100chok/similarweb-scraper (percent values too), radeance/similarweb-scraper, vortex_data/similarweb-scraper and memo23/similarweb-scraper are found by themselves: domain (name, domain, siteName, SiteName, url), month (snapshotDate, engagementMonth, the last month of the monthly visits), visits (totalVisits, visits, monthlyVisits, engagements.visits), monthly visits (estimatedMonthlyVisits, monthlyVisits, monthlyVisitsHistory), channel shares (trafficSources.\*, directTraffic…, trafficDirect…), countries (topCountries, topCountryShares, countryShare), referring sites (topReferrals), keywords (topKeywords) and ranks.

## `csvUrls` (type: `array`):

Public http(s) addresses of CSV files with one snapshot per row and a header row — an Apify CSV export (its trafficSources/directVisitsShare and topCountries/0/visitsShare columns are folded back), or your own monthly export with domain, month, visits and channel columns. Up to 20 MB a file; addresses inside private networks are refused.

## `jsonUrls` (type: `array`):

Public http(s) addresses of JSON (an array, or an object with items/data/results/snapshots) or JSONL files, one snapshot per entry, in the shape of any of the scrapers above.

## `snapshots` (type: `array`):

Snapshots pasted here as JSON objects in a scraper's shape, for example { "name": "example.com", "snapshotDate": "2026-09-01", "totalVisits": 96000, "trafficSources": { "directVisitsShare": 0.5, "searchVisitsShare": 0.3 } }. The prefill is made-up snapshots of two made-up domains.

## `domains` (type: `array`):

Domains to keep (https://, www. and paths are ignored). Empty: every domain in the sources.

## `groups` (type: `array`):

Groups of competing domains, for example \[{ "name": "Shoe shops", "domains": \["a.com", "b.com", "c.com"] }]. Each month row of a member gets its rank and share of the group's visits, and per channel its share of the group's visits from that channel — with the members it took share from (paid plans). Paid plans also get one summary row per group: who took share of which channel, first month to last.

## `groupAllDomains` (type: `boolean`):

When no groups are given and the sources hold 2 or more domains, they form one group, "All domains".

## `compareTo` (type: `string`):

previous: the month just before (when it has no data, the latest earlier month that has — the row flags a period-gap conflict). year-ago: the same month a year before.

## `minVisitsChangePct` (type: `integer`):

A month whose visits moved by at least this many percent against the month it is compared with is up or down; less is steady.

## `minShareChange` (type: `integer`):

A channel or country whose share of visits moved by at least this many points is listed in channelShifts / countryShifts (and counted in the free preview).

## `maxPeriodsPerDomain` (type: `integer`):

The newest this many months of each domain become rows (an older month still serves as the comparison of the oldest row).

## `maxPeriods` (type: `integer`):

At most this many domain×month rows are delivered and charged in one run, in source order. A free run compares the first 5.

## `aiExplanations` (type: `boolean`):

For every month with a comparison and visits on both sides: what moved and what moved together with it, each change citing the row's own numbers and checked by code (the facts it cites must exist and move the way it says, every number must be in the data, and it may not state a cause); an answer that fails the checks is thrown away and not charged. $0.032 each on BRONZE. When on, the row's numbers, domain names and keywords are sent to Anthropic's API (USA). Turn this and summaries off to run with the rules only.

## `aiMaxPeriods` (type: `integer`):

At most this many months get an AI explanation in one run.

## `summaries` (type: `boolean`):

One row per domain with two or more month rows (visits first to last, best and worst month, channel shares first to last, the biggest moves, countries in and out, conflicts, AI headlines) and one per competitor group (ranking by month, who took share of which channel). $0.064 each on BRONZE. With aiExplanations off and this on: rules + summaries.

## `maxItemsPerSource` (type: `integer`):

At most this many rows are read from one dataset or file. Rows read count toward rows-read on paid plans (each 1,000 past the first 1,000 of the run), also rows that are not snapshots.

## Actor input object example

```json
{
  "snapshots": [
    {
      "name": "example-shop.com",
      "snapshotDate": "2026-08-01T00:00:00+00:00",
      "totalVisits": 120000,
      "trafficSources": {
        "directVisitsShare": 0.4,
        "searchVisitsShare": 0.45,
        "socialNetworksVisitsShare": 0.05,
        "referralVisitsShare": 0.06,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.02
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.4
        },
        {
          "countryAlpha2Code": "GB",
          "visitsShare": 0.1
        },
        {
          "countryAlpha2Code": "DE",
          "visitsShare": 0.08
        }
      ],
      "topReferrals": [
        {
          "domain": "news-example.com",
          "visitsShare": 0.2
        },
        {
          "domain": "deals-example.net",
          "visitsShare": 0.1
        }
      ],
      "topKeywords": [
        {
          "name": "example shop"
        },
        {
          "name": "example shoes"
        }
      ]
    },
    {
      "name": "example-shop.com",
      "snapshotDate": "2026-09-01T00:00:00+00:00",
      "totalVisits": 96000,
      "trafficSources": {
        "directVisitsShare": 0.5,
        "searchVisitsShare": 0.3,
        "socialNetworksVisitsShare": 0.06,
        "referralVisitsShare": 0.08,
        "mailVisitsShare": 0.03,
        "adsVisitsShare": 0.03
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.38
        },
        {
          "countryAlpha2Code": "GB",
          "visitsShare": 0.12
        },
        {
          "countryAlpha2Code": "FR",
          "visitsShare": 0.07
        }
      ],
      "topReferrals": [
        {
          "domain": "news-example.com",
          "visitsShare": 0.25
        },
        {
          "domain": "coupons-example.org",
          "visitsShare": 0.12
        }
      ],
      "topKeywords": [
        {
          "name": "example shop"
        },
        {
          "name": "example sale"
        }
      ]
    },
    {
      "name": "example-rival.com",
      "snapshotDate": "2026-08-01T00:00:00+00:00",
      "totalVisits": 200000,
      "trafficSources": {
        "directVisitsShare": 0.35,
        "searchVisitsShare": 0.5,
        "socialNetworksVisitsShare": 0.05,
        "referralVisitsShare": 0.06,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.02
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.5
        }
      ],
      "topReferrals": [],
      "topKeywords": []
    },
    {
      "name": "example-rival.com",
      "snapshotDate": "2026-09-01T00:00:00+00:00",
      "totalVisits": 230000,
      "trafficSources": {
        "directVisitsShare": 0.33,
        "searchVisitsShare": 0.55,
        "socialNetworksVisitsShare": 0.04,
        "referralVisitsShare": 0.05,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.01
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.52
        }
      ],
      "topReferrals": [],
      "topKeywords": []
    }
  ],
  "groupAllDomains": true,
  "compareTo": "previous",
  "minVisitsChangePct": 10,
  "minShareChange": 10,
  "maxPeriodsPerDomain": 12,
  "maxPeriods": 2000,
  "aiExplanations": true,
  "aiMaxPeriods": 200,
  "summaries": true,
  "maxItemsPerSource": 20000
}
```

# Actor output Schema

## `dataset` (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 = {
    "snapshots": [
        {
            "name": "example-shop.com",
            "snapshotDate": "2026-08-01T00:00:00+00:00",
            "totalVisits": 120000,
            "trafficSources": {
                "directVisitsShare": 0.4,
                "searchVisitsShare": 0.45,
                "socialNetworksVisitsShare": 0.05,
                "referralVisitsShare": 0.06,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.02
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.4
                },
                {
                    "countryAlpha2Code": "GB",
                    "visitsShare": 0.1
                },
                {
                    "countryAlpha2Code": "DE",
                    "visitsShare": 0.08
                }
            ],
            "topReferrals": [
                {
                    "domain": "news-example.com",
                    "visitsShare": 0.2
                },
                {
                    "domain": "deals-example.net",
                    "visitsShare": 0.1
                }
            ],
            "topKeywords": [
                {
                    "name": "example shop"
                },
                {
                    "name": "example shoes"
                }
            ]
        },
        {
            "name": "example-shop.com",
            "snapshotDate": "2026-09-01T00:00:00+00:00",
            "totalVisits": 96000,
            "trafficSources": {
                "directVisitsShare": 0.5,
                "searchVisitsShare": 0.3,
                "socialNetworksVisitsShare": 0.06,
                "referralVisitsShare": 0.08,
                "mailVisitsShare": 0.03,
                "adsVisitsShare": 0.03
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.38
                },
                {
                    "countryAlpha2Code": "GB",
                    "visitsShare": 0.12
                },
                {
                    "countryAlpha2Code": "FR",
                    "visitsShare": 0.07
                }
            ],
            "topReferrals": [
                {
                    "domain": "news-example.com",
                    "visitsShare": 0.25
                },
                {
                    "domain": "coupons-example.org",
                    "visitsShare": 0.12
                }
            ],
            "topKeywords": [
                {
                    "name": "example shop"
                },
                {
                    "name": "example sale"
                }
            ]
        },
        {
            "name": "example-rival.com",
            "snapshotDate": "2026-08-01T00:00:00+00:00",
            "totalVisits": 200000,
            "trafficSources": {
                "directVisitsShare": 0.35,
                "searchVisitsShare": 0.5,
                "socialNetworksVisitsShare": 0.05,
                "referralVisitsShare": 0.06,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.02
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.5
                }
            ],
            "topReferrals": [],
            "topKeywords": []
        },
        {
            "name": "example-rival.com",
            "snapshotDate": "2026-09-01T00:00:00+00:00",
            "totalVisits": 230000,
            "trafficSources": {
                "directVisitsShare": 0.33,
                "searchVisitsShare": 0.55,
                "socialNetworksVisitsShare": 0.04,
                "referralVisitsShare": 0.05,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.01
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.52
                }
            ],
            "topReferrals": [],
            "topKeywords": []
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ntriqpro/similarweb-traffic-change-insights").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 = { "snapshots": [
        {
            "name": "example-shop.com",
            "snapshotDate": "2026-08-01T00:00:00+00:00",
            "totalVisits": 120000,
            "trafficSources": {
                "directVisitsShare": 0.4,
                "searchVisitsShare": 0.45,
                "socialNetworksVisitsShare": 0.05,
                "referralVisitsShare": 0.06,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.02,
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.4,
                },
                {
                    "countryAlpha2Code": "GB",
                    "visitsShare": 0.1,
                },
                {
                    "countryAlpha2Code": "DE",
                    "visitsShare": 0.08,
                },
            ],
            "topReferrals": [
                {
                    "domain": "news-example.com",
                    "visitsShare": 0.2,
                },
                {
                    "domain": "deals-example.net",
                    "visitsShare": 0.1,
                },
            ],
            "topKeywords": [
                { "name": "example shop" },
                { "name": "example shoes" },
            ],
        },
        {
            "name": "example-shop.com",
            "snapshotDate": "2026-09-01T00:00:00+00:00",
            "totalVisits": 96000,
            "trafficSources": {
                "directVisitsShare": 0.5,
                "searchVisitsShare": 0.3,
                "socialNetworksVisitsShare": 0.06,
                "referralVisitsShare": 0.08,
                "mailVisitsShare": 0.03,
                "adsVisitsShare": 0.03,
            },
            "topCountries": [
                {
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.38,
                },
                {
                    "countryAlpha2Code": "GB",
                    "visitsShare": 0.12,
                },
                {
                    "countryAlpha2Code": "FR",
                    "visitsShare": 0.07,
                },
            ],
            "topReferrals": [
                {
                    "domain": "news-example.com",
                    "visitsShare": 0.25,
                },
                {
                    "domain": "coupons-example.org",
                    "visitsShare": 0.12,
                },
            ],
            "topKeywords": [
                { "name": "example shop" },
                { "name": "example sale" },
            ],
        },
        {
            "name": "example-rival.com",
            "snapshotDate": "2026-08-01T00:00:00+00:00",
            "totalVisits": 200000,
            "trafficSources": {
                "directVisitsShare": 0.35,
                "searchVisitsShare": 0.5,
                "socialNetworksVisitsShare": 0.05,
                "referralVisitsShare": 0.06,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.02,
            },
            "topCountries": [{
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.5,
                }],
            "topReferrals": [],
            "topKeywords": [],
        },
        {
            "name": "example-rival.com",
            "snapshotDate": "2026-09-01T00:00:00+00:00",
            "totalVisits": 230000,
            "trafficSources": {
                "directVisitsShare": 0.33,
                "searchVisitsShare": 0.55,
                "socialNetworksVisitsShare": 0.04,
                "referralVisitsShare": 0.05,
                "mailVisitsShare": 0.02,
                "adsVisitsShare": 0.01,
            },
            "topCountries": [{
                    "countryAlpha2Code": "US",
                    "visitsShare": 0.52,
                }],
            "topReferrals": [],
            "topKeywords": [],
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ntriqpro/similarweb-traffic-change-insights").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 '{
  "snapshots": [
    {
      "name": "example-shop.com",
      "snapshotDate": "2026-08-01T00:00:00+00:00",
      "totalVisits": 120000,
      "trafficSources": {
        "directVisitsShare": 0.4,
        "searchVisitsShare": 0.45,
        "socialNetworksVisitsShare": 0.05,
        "referralVisitsShare": 0.06,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.02
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.4
        },
        {
          "countryAlpha2Code": "GB",
          "visitsShare": 0.1
        },
        {
          "countryAlpha2Code": "DE",
          "visitsShare": 0.08
        }
      ],
      "topReferrals": [
        {
          "domain": "news-example.com",
          "visitsShare": 0.2
        },
        {
          "domain": "deals-example.net",
          "visitsShare": 0.1
        }
      ],
      "topKeywords": [
        {
          "name": "example shop"
        },
        {
          "name": "example shoes"
        }
      ]
    },
    {
      "name": "example-shop.com",
      "snapshotDate": "2026-09-01T00:00:00+00:00",
      "totalVisits": 96000,
      "trafficSources": {
        "directVisitsShare": 0.5,
        "searchVisitsShare": 0.3,
        "socialNetworksVisitsShare": 0.06,
        "referralVisitsShare": 0.08,
        "mailVisitsShare": 0.03,
        "adsVisitsShare": 0.03
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.38
        },
        {
          "countryAlpha2Code": "GB",
          "visitsShare": 0.12
        },
        {
          "countryAlpha2Code": "FR",
          "visitsShare": 0.07
        }
      ],
      "topReferrals": [
        {
          "domain": "news-example.com",
          "visitsShare": 0.25
        },
        {
          "domain": "coupons-example.org",
          "visitsShare": 0.12
        }
      ],
      "topKeywords": [
        {
          "name": "example shop"
        },
        {
          "name": "example sale"
        }
      ]
    },
    {
      "name": "example-rival.com",
      "snapshotDate": "2026-08-01T00:00:00+00:00",
      "totalVisits": 200000,
      "trafficSources": {
        "directVisitsShare": 0.35,
        "searchVisitsShare": 0.5,
        "socialNetworksVisitsShare": 0.05,
        "referralVisitsShare": 0.06,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.02
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.5
        }
      ],
      "topReferrals": [],
      "topKeywords": []
    },
    {
      "name": "example-rival.com",
      "snapshotDate": "2026-09-01T00:00:00+00:00",
      "totalVisits": 230000,
      "trafficSources": {
        "directVisitsShare": 0.33,
        "searchVisitsShare": 0.55,
        "socialNetworksVisitsShare": 0.04,
        "referralVisitsShare": 0.05,
        "mailVisitsShare": 0.02,
        "adsVisitsShare": 0.01
      },
      "topCountries": [
        {
          "countryAlpha2Code": "US",
          "visitsShare": 0.52
        }
      ],
      "topReferrals": [],
      "topKeywords": []
    }
  ]
}' |
apify call ntriqpro/similarweb-traffic-change-insights --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ntriqpro/similarweb-traffic-change-insights"
        }
    }
}
```

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/UChaBqPkyi5hkwLT9/builds/gvfzxQPW9Kl1VBWc4/openapi.json
