ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Workflows
  3. Competitor Pricing Dashboard Feed
Workflow

Competitor Pricing Dashboard Feed

Daily feed of competitor pricing pages via SERP. Extract pricing tiers, update dashboard database. Python implementation using Scavio search API.

Start FreeAPI Docs

Overview

Searches Google daily for competitor pricing pages, extracts pricing tier information from SERP snippets, and writes structured pricing data to a dashboard-ready database table.

Trigger

Daily cron at 6 AM

Schedule

Daily at 6 AM (cron: 0 6 * * *)

Workflow Steps

1

Load competitor list

Read competitor names and domains from a competitors table. These are the companies to track pricing for.

2

Search for pricing pages

For each competitor, POST to Scavio search API with query '[competitor name] pricing 2026 site:[competitor domain]'. Extract top result URL and snippet.

3

Parse pricing from snippet

Use regex and keyword matching to extract price mentions from the snippet: dollar amounts, 'per month', 'per year', 'free', 'enterprise'. Structure as tier objects.

4

Store structured pricing data

Insert competitor_name, date, raw_snippet, parsed_tiers (JSON), source_url into competitor_pricing table.

5

Flag pricing changes

Compare today's parsed_tiers against yesterday's for each competitor. If tiers differ, flag as changed and store diff.

6

Update dashboard

The competitor_pricing table is queried by the dashboard directly. Optionally send a daily summary of any pricing changes detected.

Python Implementation

Python
import sqlite3
import requests
import re
import json
from datetime import date, timedelta
import time

DB_PATH = "competitor_pricing.db"
SCRAVIO_KEY = "YOUR_API_KEY"

def init_db():
    conn = sqlite3.connect(DB_PATH)
    conn.executescript("""
        CREATE TABLE IF NOT EXISTS competitors (name TEXT, domain TEXT);
        CREATE TABLE IF NOT EXISTS competitor_pricing (
            competitor TEXT, date TEXT, raw_snippet TEXT,
            parsed_tiers TEXT, source_url TEXT, changed INTEGER DEFAULT 0,
            PRIMARY KEY (competitor, date)
        );
    """)
    conn.commit()
    return conn

def search_pricing(name: str, domain: str) -> dict | None:
    resp = requests.post(
        "https://api.scavio.dev/api/v1/search",
        headers={"x-api-key": SCRAVIO_KEY},
        json={"query": f"{name} pricing 2026 site:{domain}", "platform": "google", "num": 3}
    )
    resp.raise_for_status()
    results = resp.json().get("results", [])
    if not results:
        return None
    r = results[0]
    return {"snippet": r.get("snippet", ""), "url": r.get("url", "")}

def parse_pricing_tiers(snippet: str) -> list:
    tiers = []
    # Find price mentions: $X/mo, $X/month, $X/year, $X per month
    price_pattern = r'\$([\d,]+)(?:\.\d+)?(?:/mo|/month|/year|\s+per\s+month|\s+per\s+year)?'
    prices = re.findall(price_pattern, snippet, re.IGNORECASE)
    if "free" in snippet.lower():
        tiers.append({"tier": "free", "price": 0})
    for i, price in enumerate(prices):
        price_val = float(price.replace(',', ''))
        tiers.append({"tier": f"tier_{i+1}", "price": price_val})
    if "enterprise" in snippet.lower() or "contact" in snippet.lower():
        tiers.append({"tier": "enterprise", "price": None})
    return tiers

def run():
    conn = init_db()
    today = date.today().isoformat()
    yesterday = (date.today() - timedelta(days=1)).isoformat()
    competitors = conn.execute("SELECT name, domain FROM competitors").fetchall()
    changes = []
    for name, domain in competitors:
        result = search_pricing(name, domain)
        if not result:
            time.sleep(0.5)
            continue
        tiers = parse_pricing_tiers(result["snippet"])
        tiers_json = json.dumps(tiers)
        prev = conn.execute(
            "SELECT parsed_tiers FROM competitor_pricing WHERE competitor=? AND date=?",
            (name, yesterday)
        ).fetchone()
        changed = 0
        if prev and prev[0] != tiers_json:
            changed = 1
            changes.append(f"{name}: pricing tiers changed")
        conn.execute(
            "INSERT OR REPLACE INTO competitor_pricing VALUES (?,?,?,?,?,?)",
            (name, today, result["snippet"], tiers_json, result["url"], changed)
        )
        conn.commit()
        time.sleep(0.5)
    if changes:
        print("Pricing changes detected:", changes)

if __name__ == "__main__":
    run()

JavaScript Implementation

JavaScript
const Database = require('better-sqlite3');
const fetch = require('node-fetch');

const DB_PATH = 'competitor_pricing.db';
const SCRAVIO_KEY = 'YOUR_API_KEY';

const db = new Database(DB_PATH);
db.exec(`
  CREATE TABLE IF NOT EXISTS competitors (name TEXT, domain TEXT);
  CREATE TABLE IF NOT EXISTS competitor_pricing (competitor TEXT, date TEXT, raw_snippet TEXT, parsed_tiers TEXT, source_url TEXT, changed INTEGER DEFAULT 0, PRIMARY KEY (competitor, date));
`);

async function searchPricing(name, domain) {
  const res = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: { 'x-api-key': SCRAVIO_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: `${name} pricing 2026 site:${domain}`, platform: 'google', num: 3 })
  });
  const results = (await res.json()).results || [];
  if (!results.length) return null;
  return { snippet: results[0].snippet || '', url: results[0].url || '' };
}

function parseTiers(snippet) {
  const tiers = [];
  if (/free/i.test(snippet)) tiers.push({ tier: 'free', price: 0 });
  const prices = [...snippet.matchAll(/\$([\d,]+)(?:\.\d+)?/g)].map(m => parseFloat(m[1].replace(/,/g,'')));
  prices.forEach((p, i) => tiers.push({ tier: `tier_${i+1}`, price: p }));
  if (/enterprise|contact/i.test(snippet)) tiers.push({ tier: 'enterprise', price: null });
  return tiers;
}

async function run() {
  const today = new Date().toISOString().slice(0,10);
  const yesterday = new Date(Date.now()-86400000).toISOString().slice(0,10);
  const competitors = db.prepare('SELECT name, domain FROM competitors').all();
  for (const { name, domain } of competitors) {
    const result = await searchPricing(name, domain);
    if (!result) { await new Promise(r=>setTimeout(r,500)); continue; }
    const tiers = JSON.stringify(parseTiers(result.snippet));
    const prev = db.prepare('SELECT parsed_tiers FROM competitor_pricing WHERE competitor=? AND date=?').get(name, yesterday);
    const changed = prev && prev.parsed_tiers !== tiers ? 1 : 0;
    if (changed) console.log(`${name}: pricing changed`);
    db.prepare('INSERT OR REPLACE INTO competitor_pricing VALUES (?,?,?,?,?,?)').run(name, today, result.snippet, tiers, result.url, changed);
    await new Promise(r=>setTimeout(r,500));
  }
}

run().catch(console.error);

Platforms Used

Google

Web search with knowledge graph, PAA, and AI overviews

Frequently Asked Questions

Searches Google daily for competitor pricing pages, extracts pricing tier information from SERP snippets, and writes structured pricing data to a dashboard-ready database table.

This workflow uses a daily cron at 6 am. Daily at 6 AM (cron: 0 6 * * *).

This workflow uses the following Scavio platforms: google. Each platform is called via the same unified API endpoint.

Yes. Scavio's free tier includes 50 credits on signup with no credit card required. That is enough to test and validate this workflow before scaling it.

Competitor Pricing Dashboard Feed

Daily feed of competitor pricing pages via SERP. Extract pricing tiers, update dashboard database. Python implementation using Scavio search API.

Get Your API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy