โ† Back to blog๐Ÿ› ๏ธBuilding

The Competitor Monitoring Tool I Built With Ahrefs Firehose and Claude

by Kamila Olexa

Part 2 of a 4-part series on building marketing tools with Firehose.

"How can I keep my articles always up to date with the most recent info?" With competitor focused content becoming more popular these days, it's a question you should ask yourself as well.

You publish a detailed comparison post. "Competitor Y vs Competitor Z vs You." It ranks. It drives signups. 2 weeks later, Competitor Y quietly changes their pricing. Your post now has wrong numbers. You don't notice. Your readers do. The world is in ruins.

Well don't fret! The second competitor monitoring tool I built solves this. And you can build it too.

It watches competitor pricing pages, detects when something changes, figures out which of your blog posts mention said competitor, rewrites just the pricing sections, and asks you to approve the update in Slack before pushing it live. Automated competitor pricing analysis, end to end.

The pipeline

Competitor /pricing page changes
    โ†“  Firehose detects the change
Claude extracts structured pricing (tiers, prices, features)
    โ†“
Script scans your Webflow blog posts for mentions of that competitor
    โ†“
Claude rewrites just the pricing sections
    โ†“
Posts a summary to Slack with proposed changes
    โ†“
You react with โœ… to approve
    โ†“
Updated posts pushed to Webflow and published

Six steps and four services you need: Firehose, Claude, Slack, Webflow.

Step 1: Watching competitor pricing pages

Firehose won't monitor the whole web for mentions of your competitor, but specific URLs. You guessed it, it's your competitors' pricing pages.

Firehose rules for monitoring competitor pricing pages

The config file lists each competitor:

competitors: [
  {
    name: "Competitor 1",
    nameVariations: ["Competitor 1", "Competitor 1 app"],
    domain: "competitor1.com",
    pricingUrls: ["https://www.competitor.com/pricing"],
    hints: "Teams and Individual plans with annual/monthly billing.",
  },
  {
    name: "Competitor 2",
    nameVariations: ["Competitor 2", "Competitor 2 ai"],
    domain: "competitor2.ai",
    pricingUrls: ["https://competitor2.ai/pricing"],
    hints: "Free, Starter, Business, Enterprise tiers.",
  },
]

The nameVariations field is how the script knows which blog posts mention this competitor. You need to map how you refer to your competitors in your content, e.g. "Competitor 1" might appear as "Competitor 1" or "Competitor 1 app".

๐Ÿ’ก The hints field
The hints field gives Claude context about what to expect on the pricing page: tier names, billing structure. It's optional, but it makes extraction more reliable because Claude knows what to look for. I filled it in manually to be sure of the structure.

The setup script converts these into Firehose rules. Each pricing URL becomes a rule using the url field:

url:"https://www.competitor1.com/pricing"

Since we're watching for any change to these specific pages, we disable the quality filter (which normally limits results to pages published in the last 7 days. Pricing pages aren't "published," they're updated):

{ "value": "url:\"https://www.competitor1.com/pricing\"", "tag": "competitor-pricing", "quality": false }

Step 2: Extracting competitor pricing data with Claude

When Firehose catches a change, the script gets the full page content as markdown (Firehose includes this in every match). That markdown goes to Claude with a prompt like:

Here's a pricing page. Extract every plan tier with: tier name, price, billing cycle (monthly/annual), and a short feature summary. Return structured JSON.

Claude comes back with:

{
  "competitor": "competitor 1",
  "tiers": [
    { "name": "Pro AI", "price": "$19/seat/mo", "billing": "annual", "features": "..." },
    { "name": "Business AI", "price": "$29/seat/mo", "billing": "annual", "features": "..." }
  ]
}
๐Ÿ”‘ Claude API setup
If you haven't used the Claude API before: sign up at console.anthropic.com, generate a key (starts with sk-ant-), and add it to your .env file. Pricing is per-token. For this use case, you're looking at a few cents per run. We're sending one pricing page and getting back a small JSON blob.

The hints field from your config gets included in the prompt, so Claude knows the expected tier structure and is less likely to hallucinate or misparse tables.

Step 3: Finding your blog posts that mention the competitor

Now the script needs to answer: which of our blog posts talk about this competitor?

In this case I am using Webflow, but you can adjust this part to your situation.

It pulls all posts from your Webflow CMS collection using the Webflow API, then scans the content fields for the competitor's name variations. If your post's body contains "competitor 1" or "competitor 1 app," it's a match.

The config tells the script which Webflow fields to scan:

webflow: {
  siteId: "your-site-id",
  blogCollectionId: "your-blog-collection-id",
  fieldsToScan: ["blog-content", "key-takeaways", "conclusions", "blog-summary"],
}
๐Ÿ” Finding your Webflow IDs
If you're not sure what your site ID or collection ID is, the tool includes helper scripts:

npm run webflow:sites lists your sites with IDs
npm run webflow:collections lists CMS collections
npm run webflow:fields lists all fields on your blog collection

For the Webflow API token: go to your site's Settings โ†’ Apps & Integrations โ†’ Generate API Token. Make sure it has both read and write permissions (read to scan posts, write to update them later).

Step 4: Claude rewrites only the pricing sections

Claude doesn't rewrite your whole post. It gets the full post content plus the new structured pricing, and its job is to find and replace only the parts that reference that competitor's pricing.

If your post says "competitor 1's Pro plan starts at $15/month" and the new pricing is $19/month, Claude updates that sentence. The rest of your post (your analysis, your opinions, your CTAs) stays untouched.

The output is the updated HTML for each affected field, ready to push to Webflow.

Step 5: Slack approval

The script doesn't publish without your permission. It sends a Slack message that looks like this:

๐Ÿ’ฐ Competitor Pricing Changes Detected
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Motion โ€” pricing page updated
  โ€ข Pro AI: $19/seat/mo (annual)
  โ€ข Business AI: $29/seat/mo (annual)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2 blog post update(s) ready:

๐Ÿ“ "Best Project Management Tools 2025"
  Field: blog-content ยท Competitor: Motion
  Changes: Updated Pro AI price from $15/mo to $19/mo

๐Ÿ“ "Motion vs Reclaim: Full Comparison"
  Field: blog-content ยท Competitor: Motion
  Changes: Updated both tier prices, added new Enterprise tier
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
React with โœ… to approve and publish.

You read the summary. If it looks right, react with โœ…. The bot picks up the reaction, pushes the changes to Webflow, publishes the updated posts, and confirms in a thread reply.

Slack approval flow for competitor pricing updates

โš ๏ธ Slack app vs webhook
This tool uses a Slack Bot Token (xoxb-...) rather than the simpler Incoming Webhook from Part 1. That's because it needs to both post messages and read your reactions. You create a Slack app at api.slack.com/apps, add the chat:write and reactions:read scopes, install it to your workspace, and invite the bot to your channel. A bit more setup than a webhook, but still under 10 minutes.

Step 6: Push to Webflow

Once approved, the script calls the Webflow CMS API to update each affected item's fields and publishes the changes. Your blog posts now have correct pricing. Your readers see accurate numbers. You didn't manually edit anything.

Full setup checklist for this competitor tracking tool

Five things in your .env:

  • FIREHOSE_TAP_TOKEN โ†’ Your Firehose tap token (fh_...) โ†’ firehose.com dashboard
  • ANTHROPIC_API_KEY โ†’ Claude API key (sk-ant-...) โ†’ console.anthropic.com
  • WEBFLOW_API_TOKEN โ†’ Webflow CMS token โ†’ Site Settings โ†’ Apps & Integrations
  • SLACK_BOT_TOKEN โ†’ Slack bot token (xoxb-...) โ†’ api.slack.com/apps โ†’ OAuth
  • SLACK_CHANNEL_ID โ†’ Channel to post in โ†’ Right-click channel in Slack โ†’ Copy link โ†’ ID is at the end

Then:

  1. Edit pricing.config.js with your competitors and Webflow IDs
  2. npm run setup creates the Firehose rules
  3. npm run test dry-run to see what would change
  4. npm run slack:bot run the full flow locally
  5. Push to GitHub and add your secrets for daily scheduling

Next up

Part 3 bundles two tools to help you with "What should we create next?" The Content Gap Radar finds topics competitors are covering that you aren't. The Trend Radar spots breaking stories in your niche before they peak. Both push ready-to-use briefs to Notion.

PS: Part 1 covered the pattern + brand monitoring

Kamila Olexa

Written by

Kamila Olexa

Growth Marketing Lead

Kamila writes about SEO, content strategy, and growth marketing. Consulting and leading organic & paid growth at multiple startups from 0 to 100k monthly visitors and counting.