# SaaS Pricing Monitor: Track Competitor Plans (`offerastudio/saas-pricing-monitor`) Actor

Track competitors' SaaS pricing pages: plans, prices, billing periods, limits and features, from plan cards and schema.org offers. Get a plan-level diff on change (price old to new with %, plans added or removed, features) and a plain summary. Optional browser mode for JavaScript pages.

- **URL**: https://apify.com/offerastudio/saas-pricing-monitor.md
- **Developed by:** [Offera Studio](https://apify.com/offerastudio) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 page 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?

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

### What does SaaS Pricing Monitor do?

**SaaS Pricing Monitor** watches your competitors' (or vendors') **pricing pages** and tells you **what changed, plan by plan**. On every run it reads the **plans** from each page (name, price, currency, billing period, per-user unit, limits and feature list) and compares them with the plans it saw last time:

- 💲 **price changes**, old → new with the percentage: *"Pro went from $29/mo to $35/mo (+20.7%)"*
- ➕➖ **plans added or removed**
- 🔁 **billing period changes** (monthly ↔ yearly)
- ✅ **features added to or removed from** a plan's list
- 🧾 a **plain-language summary** and the **structured plans** in every row

Give it pricing page URLs, or just **domains**: the Actor looks for the pricing page itself (a pricing link on the home page, then `/pricing`, `/plans` ...). Schedule it daily or weekly and connect alerts by email, Slack or webhook.

**No API key, no proxy and no login.** By default the Actor reads the page's HTML (fast and cheap). For pages that build their plans with JavaScript there is an optional **Render JavaScript** mode (a real headless browser) at the **same price per page**.

### Who is it for?

- **Product and pricing teams**: know the day a competitor raises a price, adds a tier or moves a feature between plans.
- **Sales and marketing**: keep battle cards and comparison pages current.
- **Founders and analysts**: build a price history of a market without checking pages by hand.
- **Procurement**: watch the list prices of the SaaS tools you buy.

### How to use it

1. Click **Start** with the default input: three pricing pages that render without JavaScript. The first run saves a **baseline** (a row with the plans found).
2. From the second run on, you get a row **only when something changed** (the default input also asks for unchanged rows so that a first try and Apify's daily test show something; turn **Also return unchanged pages** off for monitoring).
3. Replace the pages with your competitors' pricing URLs or domains. Set a **Currency hint** if the pages show `$` for Canadian or Australian dollars. Give the monitor a **name**: its snapshots live in the named key-value store `pricing-monitor-<name>`.
4. If a page comes back as `no-plans-found`, try **Render JavaScript**.
5. Add a **schedule** and an **integration** (Slack, email, webhook, Zapier, Make, n8n) to the task.

### How the extraction works (and how far to trust it)

**The extraction is heuristic.** There is no standard for pricing pages, so the Actor uses rules for the common layouts:

1. **Plan cards.** It looks for the price on the page, then for the lowest level where two or more sibling blocks each have a price and a name. From each block it reads the **name** (heading), the **price** (first price that is not struck through and not in a feature list), the **billing period** and **unit** (`/mo`, `per user per month`, `billed annually`), a **description**, the **feature list** (list items) and the **limits** (features that state a quantity, such as "10 GB storage"). Plans without a price slot ("Free", "Contact sales") are recognised too.
2. **schema.org (JSON-LD)** offers, when no cards are found. They usually carry prices but no feature lists.

Each row has a **`confidence`** (`high`, `medium` or `low`) and `extractionNotes`. It measures how clean the page's structure was, **not whether the numbers are right**: always compare a **new baseline with the page** once. Typical limits:

- the page shows **one billing state** (monthly or yearly, whatever it opens in). The Actor does not click toggles: you get the prices as the page shows them when it opens, and `billingNote` says "billed annually" where the page says so;
- **comparison tables, sliders, per-seat calculators, usage-based tiers and "from" prices** are read as what the first price says;
- prices **in images**, behind a login or a region switch are not read;
- a page redesign can change what is recognised: the Actor then starts a **new baseline** instead of reporting every plan as removed, and a page where no plans are found keeps the old plans and gives a free `no-plans-found` row.

#### Real pages tried (static mode, 1–2 October 2026)

| Page | What the Actor read |
| --- | --- |
| basecamp.com/pricing | Free, Freelancer $25/mo, Studio $59/mo, Pro $99/mo, Unlimited $299/mo, with feature lists (high) |
| ghost.org/pricing | Starter $18/mo, Publisher $29/mo, Business $199/mo, Custom (billed yearly noted) (high) |
| fastmail.com/pricing | Individual $6, Duo $10, Family $14 and Basic $4, Standard $6, Professional $10 per user (high; the page also shows longer-term prices as extra price options) |
| linear.app/pricing | Free, Basic $10/user, Business $16/user, Enterprise custom (high) |
| zapier.com/pricing | Free, Professional $19.99, Team $69, Enterprise custom (high) |
| trello.com/pricing | Free, Standard $5/user, Premium $10/user, Enterprise $17.50/user, "billed annually" noted (high, no feature lists) |
| loom.com/pricing | Starter free, Business $18/user, Business + AI $24/user, Enterprise custom (high) |
| zoho.com/crm/pricing | Free, Standard ₹800, Professional ₹1,400, Enterprise ₹2,400 per user (currency ₹ read correctly) |
| notion.com/pricing | Free and Plus $10/member only: the other plans are not in the HTML (medium) |
| railway.com/pricing | Hobby $5, Pro $20, Enterprise custom: the page's free trial tier is missing |
| sentry.io/pricing | Developer, Team $26, Business $80, Enterprise (the enterprise card is read as "free": wrong, though `confidence` says high) |
| posthog.com/pricing, digitalocean.com/pricing | read products or add-ons, not plans: wrong for this purpose |
| buttondown.com/pricing | one plan with a slider: low confidence, not useful |
| netlify.com/pricing | only schema.org data (one "Free" offer): low |
| figma.com/pricing, mailchimp.com/pricing, vercel.com/pricing, todoist.com/pricing, fly.io, twilio.com | no plans found in the HTML (these need **Render JavaScript** or are not card layouts) |
| github.com/pricing, canva.com/pricing, pipedrive.com | refused automated access (HTTP 403): free `blocked` rows |

Of **28 pages** tried, **12 were read well** (basecamp, ghost, fastmail, linear, zapier, trello, loom, zoho, slack, miro, freshworks, dropbox), **7 partly or wrongly**, **6 gave no plans** in static mode and **3 refused access**. So expect about **half of the pages to work well**, a quarter to be partly or wrongly read in ways you only see by reading the baseline, and a quarter to need Render JavaScript, an exact URL or to be out of reach.

### Input example

```json
{
    "startUrls": [
        { "url": "https://competitor-a.com/pricing" },
        { "url": "https://competitor-b.com" },
        { "url": "https://competitor-c.com/plans" }
    ],
    "currencyHint": "USD",
    "renderJavaScript": false,
    "includeUnchanged": false,
    "monitorName": "rivals"
}
```

### Output example

**Baseline**: real output of the default input on 2 October 2026 (first run):

| Page | Plans |
| --- | --- |
| https://basecamp.com/pricing | Free · Freelancer $25/mo · Studio $59/mo · Pro $99/mo · Unlimited $299/mo |
| https://www.fastmail.com/pricing/ | Individual $6/mo · Duo $10/mo · Family $14/mo · Basic $4/mo/user · Standard $6/mo/user · Professional $10/mo/user |
| https://ghost.org/pricing/ | Starter $18/mo · Publisher $29/mo · Business $199/mo · Custom |

**A change row.** Live pricing pages change rarely, so to show a real change the saved version of Basecamp's plans was edited on the test machine (Pro at $89, no Studio plan, two features fewer on Unlimited) before the next run; the row is what the Actor produced from the live page:

```json
{
    "url": "https://basecamp.com/pricing",
    "domain": "basecamp.com",
    "status": "changed",
    "summary": "Studio added at $59/mo; Pro went from $89/mo to $99/mo (+11.2%); Unlimited gained 2 features.",
    "plansCount": 5,
    "plans": [
        { "name": "Pro", "price": 99, "priceType": "paid", "currency": "USD", "billingPeriod": "month", "perUnit": null, "priceText": "$99", "limits": ["Up to 25 active projects", "…"], "features": ["Up to 25 active projects", "Unlimited users", "…"], "source": "cards" }
    ],
    "extractionMethod": "cards",
    "confidence": "high",
    "plansAdded": [{ "name": "Studio", "priceText": "$59/mo" }],
    "plansRemoved": [],
    "priceChanges": [
        { "plan": "Pro", "oldPrice": 89, "newPrice": 99, "oldCurrency": "USD", "newCurrency": "USD", "oldPeriod": "month", "newPeriod": "month", "percentChange": 11.2, "oldText": "$89/mo", "newText": "$99/mo", "option": "main" }
    ],
    "billingPeriodChanges": [],
    "featureChanges": [{ "plan": "Unlimited", "added": ["Annual billing + extra payment options …", "Extended 45-day free trial …"], "removed": [] }],
    "summaryItems": ["Studio added at $59/mo", "Pro went from $89/mo to $99/mo (+11.2%)", "Unlimited gained 2 features"],
    "renderedWithBrowser": false,
    "error": null
}
```

**Fields worth knowing:**

- `status`: `baseline` (first check, saved), `changed`, `unchanged` (only on request) or `error` (a free info row).
- `plans[].prices`: all price options found in a plan (for example monthly and yearly); the first one is the main price that is compared. Other options are compared by billing period.
- `priceChanges[].percentChange` is empty when the currency or the billing period differs, or the old price was 0.
- Rows with an `error` code are free: `no-plans-found`, `no-pricing-page-found`, `robots-disallowed`, `http-error`, `blocked`, `timeout`, `invalid-url`.

### How much does it cost?

This Actor uses **pay per event**:

| Event | Price |
| --- | --- |
| Page checked (fetched and plans read, including baselines), **with or without Render JavaScript** | **$0.003** |
| Pages that fail to load, pages where no plans are recognised, domains without a pricing page, pages robots.txt does not allow, info rows | **free** |

- 50 competitor pages checked daily cost **$0.15 a day** (about $4.50 a month).
- Browser mode needs more memory (4 GB by default) and time, but the price per page is the same.
- Set **Maximum cost per run** in the run options and the Actor stops when it is reached.

### Limitations

- **Heuristic extraction** (see above): check each new baseline, and use `confidence` and `extractionNotes` as hints, not guarantees.
- **robots.txt is respected** (also when looking for the pricing page); the Actor sends an identifiable User-Agent and waits at least 1.5 s between requests to the same site. Sites that block automated visits answer a free `blocked` row; the Actor does not use proxies or work around blocks.
- **No clicking**: billing toggles, currency or region selectors, and "show more" buttons are not used, also in browser mode.
- **Taxes and promotions**: the Actor reads list prices as shown; struck-through old prices are ignored, coupon banners are not interpreted.
- **Language**: names and features are returned as written; billing periods are recognised in English, German, French, Spanish and a few more languages.
- **Up to 300 pages or domains per run**, up to 12 plans per page and 60 features per plan.
- Version history starts at your first run.

### Data and your responsibility

- The Actor reads **public pricing pages**. It returns prices, plan names and short feature lines for monitoring; check the site's terms before you republish them.
- No personal data is processed. Not affiliated with any company whose pages you monitor.

### FAQ

#### Why did a page return `no-plans-found`?

Its plans are built by JavaScript, are in images, or use a layout the rules do not know. Turn on **Render JavaScript**, or give the exact pricing URL if you gave a domain.

#### Can it find the pricing page from a domain?

Yes, when the home page links to it or it sits at a usual path (`/pricing`, `/plans` ...) and shows plans without JavaScript. The page found is remembered for 30 days.

#### Does the browser mode cost more?

No, the price per page is the same. It needs more memory (4 GB by default), so runs take longer.

#### Why is my plan's price missing a period?

The page shows the price and "/mo" in places the rules do not link together, or the price has no period (a one-time price, usage-based pricing). `billingPeriod` is then empty.

#### How do I track yearly prices?

If the page shows both, the plan's `prices` list has both and changes are reported for each period. If it only shows the default state, you get only that.

### More tools from the same developer

All pay-per-result, no proxy or login needed, built and maintained by the same developer:

**Website audits**

- [Website Accessibility Checker: WCAG 2.2 & EAA](https://apify.com/offerastudio/website-accessibility-audit): accessibility issues with fixes, SEO basics and security headers.
- [Cookie & Tracker Audit: GDPR Consent Checker](https://apify.com/offerastudio/cookie-tracker-audit): cookies and tracking tags that load before consent.
- [AI Crawler Access Checker: robots.txt & llms.txt](https://apify.com/offerastudio/ai-crawler-access-audit): which AI crawlers a site allows, plus llms.txt.
- [Structured Data Validator: Schema & Rich Results](https://apify.com/offerastudio/structured-data-validator): JSON-LD and Microdata checked against Google's rich result rules.
- [Website Change Monitor: Diffs, Prices & Alerts](https://apify.com/offerastudio/website-change-monitor): get a row only when a page changes, with a clean diff.
- [Policy Change Monitor: Privacy & Terms Tracker](https://apify.com/offerastudio/policy-change-monitor): privacy policy and terms changes, classified clause by clause.
- [Sitemap Change Monitor: New & Removed URLs](https://apify.com/offerastudio/sitemap-change-monitor): new, removed and changed URLs from a site's sitemaps.
- [Site SEO Crawler: Broken Links & On-Page Audit](https://apify.com/offerastudio/site-seo-crawler-audit): site-wide crawl for broken links, redirects and on-page SEO issues.
- [Website Tech Stack Detector: Bulk Lead Filters](https://apify.com/offerastudio/website-tech-stack-detector): technologies used by websites, with filters for lead lists.
- [Domain Availability & Expiry Checker (RDAP)](https://apify.com/offerastudio/domain-whois-availability): domain availability, registrar and expiry dates from RDAP.
- [Status Page SLA Monitor: Uptime & Incidents](https://apify.com/offerastudio/status-page-sla-monitor): SaaS vendor uptime, incidents and a monthly SLA table from public status pages.

**Company data and compliance**

- [Company Contact Finder: Emails, Phones & Socials](https://apify.com/offerastudio/company-contact-finder): contact details published on company websites.
- [UK New Companies Feed: Companies House Daily](https://apify.com/offerastudio/uk-new-companies-feed): newly incorporated UK companies with sector filters.
- [EU VAT Number Validator: Bulk VIES Checker](https://apify.com/offerastudio/eu-vat-number-validator): bulk VAT checks with name, address and consultation number.
- [LEI Corporate Tree: GLEIF Parents & Subsidiaries](https://apify.com/offerastudio/gleif-lei-corporate-tree): LEI lookup with parents, subsidiaries and a KYC summary.
- [UK Company Distress Watch: Insolvency Alerts](https://apify.com/offerastudio/uk-company-distress-watch): administrations, liquidations and winding-up petitions from The Gazette.
- [IBAN Validator: Bulk Check & Bank Lookup](https://apify.com/offerastudio/iban-bank-validator): IBAN format and checksum, plus bank name and BIC where open data exists.
- [Sanctions Screening: OFAC, EU, UN & UK Lists](https://apify.com/offerastudio/sanctions-screening): names screened against official sanctions lists, with match scores.
- [OSHA & EPA Violation Monitor: Fines by Company](https://apify.com/offerastudio/osha-epa-violation-monitor): US OSHA and EPA enforcement cases and penalties by company.
- [Email List Precheck: Syntax, MX & Disposable Check](https://apify.com/offerastudio/email-list-precheck): cheap email list hygiene before a real verification.
- [UK Company Officer Changes: Director & PSC Alerts](https://apify.com/offerastudio/uk-company-officer-changes): director, owner, address and status changes for a watchlist of UK companies.
- [FDA Warning Letters Monitor: By Company & Subject](https://apify.com/offerastudio/fda-warning-letters-monitor): FDA warning letters by company and subject, with cited regulations.
- [Supplier Risk Report: Sanctions, VAT & Insolvency](https://apify.com/offerastudio/supplier-risk-report): one risk row per supplier from eight official registers, with changes since last run.
- [Brand Impersonation Domain Monitor: Look-alikes](https://apify.com/offerastudio/brand-impersonation-domain-monitor): look-alike domains and certificates that imitate your brand, with a risk score.

**Media and AI**

- [Audio & Video Transcriber: Podcasts, SRT, Speakers](https://apify.com/offerastudio/audio-video-transcriber): audio, video, podcasts and social links to text, SRT and VTT.
- [Podcast Mention Alerts: Brand Mentions by Second](https://apify.com/offerastudio/podcast-mention-alerts): where your brand is said in new podcast episodes, with the exact second.
- [News Brand Mentions Monitor: New Articles Only](https://apify.com/offerastudio/news-brand-mentions-monitor): new news articles about your brand, people or topics.
- [YouTube Channel Monitor: New Videos & Growth](https://apify.com/offerastudio/youtube-channel-monitor): new videos and view growth of the channels you watch.

**Market signals**

- [US WARN Layoff Notices: 12 States Daily Feed](https://apify.com/offerastudio/us-warn-layoff-notices): layoff and plant closure notices from official state sources.
- [US Product Recalls Monitor: FDA & CPSC Feed](https://apify.com/offerastudio/us-product-recalls-monitor): FDA and CPSC recalls in one feed, with severity.
- [EU Tenders Feed: TED Public Procurement Alerts](https://apify.com/offerastudio/eu-tender-feed): EU public tenders from TED with CPV, country and value filters.
- [Liquor License Openings: New Bars & Stores (US)](https://apify.com/offerastudio/liquor-license-openings): new US liquor licences from official state open data.
- [Clinical Trials Change Monitor: Status & Updates](https://apify.com/offerastudio/clinicaltrials-change-monitor): status, enrollment and results changes on ClinicalTrials.gov studies.
- [Career Site Jobs Monitor: ATS Jobs & New Roles](https://apify.com/offerastudio/career-site-jobs-monitor): open roles from company career sites, with new and closed roles since the last run.
- [App Reviews Monitor: App Store & Google Play](https://apify.com/offerastudio/app-store-reviews-monitor): app reviews from both stores, only new ones in monitor mode.
- [US Federal Contracts Feed: SAM.gov & USAspending](https://apify.com/offerastudio/us-federal-contracts-feed): SAM.gov contract opportunities with the buyer's award history.
- [Grants.gov Opportunities: US Federal Grants Feed](https://apify.com/offerastudio/grants-gov-opportunities): US federal grant opportunities by keyword, eligibility and agency.
- [Federal Register Monitor: US Rules & Notices Feed](https://apify.com/offerastudio/federal-register-monitor): new US rules, proposed rules and notices by agency or topic.
- [B2B Sales Trigger Feed: Hiring + Tech Leads](https://apify.com/offerastudio/b2b-sales-trigger-feed): companies hiring for a role and using (or not using) a technology, with contacts.
- [Local Business Leads: OpenStreetMap, No Website](https://apify.com/offerastudio/local-business-leads-osm): local businesses by city and category, including those with no website.
- [Solana Token Pair Monitor: New & Trending Pairs](https://apify.com/offerastudio/solana-token-pair-monitor): new and trending Solana pairs with liquidity, volume and safety flags.

### Feedback

Found a pricing page that is read wrongly? Open an issue on the **Issues** tab with the URL.

# Changelog

This Actor's version history is a separate document: https://apify.com/offerastudio/saas-pricing-monitor/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Up to 300 entries. A pricing page URL (acme.com/pricing) is checked as it is. A bare domain or home page (acme.com) makes the Actor look for its pricing page (a pricing link on the home page, then /pricing, /plans ...). Each page is fetched once per run and compared with the plans saved by the previous run.

## `currencyHint` (type: `string`):

Three-letter currency code (USD, CAD, AUD, EUR, GBP ...) used when a page shows an ambiguous symbol such as $ or kr without saying which currency. A currency stated on the page (schema.org data, "US$", "EUR") wins. Empty = $ means USD.

## `renderJavaScript` (type: `boolean`):

Off (default): the page's HTML is read, fast and cheap. On: each page is opened in a real headless browser (Playwright + Chromium) without clicking anything, so plans that are built by JavaScript are found too. Slower and uses more memory (4 GB by default), same price per page. Billing toggles (monthly/yearly) are not clicked: you get the prices the page shows when it opens.

## `includeUnchanged` (type: `boolean`):

Also add a row (with the plans) for pages that did not change. Off by default, so the dataset (and your alerts) only get rows when something changed. It is switched on in the example input only so Apify's daily test and a first try show a row for every page; turn it off for monitoring.

## `monitorName` (type: `string`):

Name of this monitor. Its snapshots live in the named key-value store "pricing-monitor-<name>"; use the same name to continue the same monitor when you change the list. Empty = a name made from the list of pages.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://basecamp.com/pricing"
    },
    {
      "url": "https://www.fastmail.com/pricing/"
    },
    {
      "url": "https://ghost.org/pricing/"
    }
  ],
  "renderJavaScript": false,
  "includeUnchanged": true
}
```

# Actor output Schema

## `changes` (type: `string`):

No description

## `plans` (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 = {
    "startUrls": [
        {
            "url": "https://basecamp.com/pricing"
        },
        {
            "url": "https://www.fastmail.com/pricing/"
        },
        {
            "url": "https://ghost.org/pricing/"
        }
    ],
    "includeUnchanged": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("offerastudio/saas-pricing-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [
        { "url": "https://basecamp.com/pricing" },
        { "url": "https://www.fastmail.com/pricing/" },
        { "url": "https://ghost.org/pricing/" },
    ],
    "includeUnchanged": True,
}

# Run the Actor and wait for it to finish
run = client.actor("offerastudio/saas-pricing-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://basecamp.com/pricing"
    },
    {
      "url": "https://www.fastmail.com/pricing/"
    },
    {
      "url": "https://ghost.org/pricing/"
    }
  ],
  "includeUnchanged": true
}' |
apify call offerastudio/saas-pricing-monitor --silent --output-dataset

```

## MCP server setup

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

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RFzAGGzjdSCOUEHyZ/builds/xaS49dD4AjYKcR7Sw/openapi.json
