Alchemy RecipeAdvancedautomation

Competitive pricing analysis and dynamic pricing recommendation

Published

Pricing strategy is one of the most consequential decisions in e-commerce, yet most companies make it manually. A product manager reviews competitor prices once a week, makes notes in a spreadsheet, then passes them to the pricing team who debate for hours before updating SKUs in the system. By the time those changes go live, the market has already shifted. Your competitors have moved on..........

The friction here isn't technical; it's structural. You have the data sources (competitor websites, your own sales metrics, inventory levels), the decision logic (price elasticity models, margin targets), and the systems that need updating (your product database, your point-of-sale). What's missing is the connective tissue that moves information from point A to point B without someone manually copying and pasting between tabs.

This is where automation becomes genuinely valuable. By wiring together Accio AI (which scrapes competitor pricing at scale), Finster AI (which runs pricing algorithms against your business rules), and Terrakotta AI (which updates your product catalogue), you can create a workflow that refreshes your pricing in minutes rather than days. This post shows you exactly how to build that workflow using either Zapier, n8n, Make, or Claude Code.

The Automated Workflow

Which Orchestration Tool to Use

For this particular workflow, n8n is the strongest choice, though each tool has merit. Here's why: Accio AI returns large datasets (hundreds of competitor price points), and you need to transform and filter that data before sending it to Finster AI for analysis. Zapier's data transformation capabilities are lighter; Make works well here too, but n8n's native looping and conditional logic give you finer control over how batches are processed. If you're already invested in Zapier, it's certainly possible, and Claude Code is excellent if you want to write custom Python logic.

For this walkthrough, I'll use n8n as the primary example with notes on adapting to other platforms.

Step 1: Trigger and Competitor Data Collection

Set up a cron trigger in n8n to run daily at 06:00 UTC. This calls Accio AI's pricing scrape endpoint.


GET /v2/scrape/batch
Headers:
  Authorization: Bearer YOUR_ACCIO_API_KEY
  Content-Type: application/json

Body:
{
  "urls": [
    "https://competitor-a.com/products",
    "https://competitor-b.com/products",
    "https://competitor-c.com/products"
  ],
  "extract_fields": ["title", "sku", "price", "currency", "availability"],
  "callback_url": "https://your-n8n-instance.com/webhook/accio-complete"
}

Accio AI will scrape asynchronously and POST results back to your webhook. In n8n, set up a Webhook node to receive this callback. The response looks like this:

{
  "batch_id": "batch_62847293",
  "timestamp": "2024-01-15T06:42:17Z",
  "results": [
    {
      "source": "competitor-a.com",
      "products": [
        {
          "title": "Widget Pro",
          "sku": "WID-PRO-001",
          "price": 49.99,
          "currency": "GBP",
          "availability": "in_stock"
        }
      ]
    }
  ]
}

Step 2: Data Normalisation and Preparation

Before sending data to Finster AI, you need to normalise competitor products against your own product catalogue. This is where most workflows break down; the SKU from competitor A doesn't match your internal SKU, and you can't just assume "Widget Pro" at competitor-a.com is the same as your "Pro Widget" SKU-12345.

In n8n, add a Function node that maps competitor products to your internal SKUs using a reference table. You'll maintain this table in a JSON file or database; for this example, I'll show a simple lookup:

const competitorProducts = $input.all()[0].json.results;
const skuMapping = {
  "competitor-a.com": {
    "Widget Pro": "SKU-12345",
    "Widget Basic": "SKU-12344"
  },
  "competitor-b.com": {
    "Pro Widget": "SKU-12345",
    "Basic Widget": "SKU-12344"
  }
};

const normalisedData = [];

competitorProducts.forEach(source => {
  source.products.forEach(product => {
    const internalSKU = skuMapping[source.source]?.[product.title];
    if (internalSKU) {
      normalisedData.push({
        internal_sku: internalSKU,
        competitor: source.source,
        competitor_title: product.title,
        competitor_price: product.price,
        currency: product.currency,
        availability: product.availability,
        scraped_at: new Date().toISOString()
      });
    }
  });
});

return normalisedData;

This function outputs a clean array of competitor prices matched to your SKUs. Important: maintain this mapping file separately and update it monthly as you add new competitors or products.

Step 3: Fetch Your Current Pricing and Business Rules

Before Finster AI can recommend new prices, it needs two inputs: your current product data and your business constraints. Add an HTTP request node that pulls your product catalogue:


GET /api/v1/products
Headers:
  Authorization: Bearer YOUR_DB_API_KEY

Params:
  fields=sku,current_price,cost,margin_target,price_floor,price_ceiling,category
  status=active

This returns something like:

{
  "products": [
    {
      "sku": "SKU-12345",
      "name": "Pro Widget",
      "current_price": 45.00,
      "cost": 18.00,
      "margin_target": 0.50,
      "price_floor": 35.00,
      "price_ceiling": 75.00,
      "category": "widgets",
      "last_updated": "2024-01-14T10:30:00Z"
    }
  ]
}

Store this in n8n's context for the next step.

Step 4: Call Finster AI's Pricing Algorithm

Now combine the normalised competitor data with your product data and send it to Finster AI for analysis. Finster AI runs your pricing algorithm and returns recommended prices based on competitor positioning, demand elasticity, and your margin constraints. For more on this, see Competitor pricing analysis and dynamic pricing recommend....


POST /v1/pricing/recommend
Headers:
  Authorization: Bearer YOUR_FINSTER_API_KEY
  Content-Type: application/json

Body:
{
  "products": [
    {
      "sku": "SKU-12345",
      "name": "Pro Widget",
      "current_price": 45.00,
      "cost": 18.00,
      "margin_target": 0.50,
      "price_floor": 35.00,
      "price_ceiling": 75.00,
      "category": "widgets",
      "competitors": [
        {
          "source": "competitor-a.com",
          "price": 49.99,
          "availability": "in_stock"
        },
        {
          "source": "competitor-b.com",
          "price": 48.50,
          "availability": "in_stock"
        }
      ]
    }
  ],
  "algorithm": "dynamic_elasticity",
  "confidence_threshold": 0.75
}

Finster AI returns:

{
  "recommendations": [
    {
      "sku": "SKU-12345",
      "current_price": 45.00,
      "recommended_price": 47.99,
      "competitor_avg": 49.25,
      "price_change_pct": 6.64,
      "confidence": 0.89,
      "reasoning": "Competitor average 49.25; recommendation positions 2.87% below to gain market share whilst maintaining margin target.",
      "projected_margin": 0.488
    }
  ],
  "processing_time_ms": 342
}

In n8n, add an HTTP Request node configured as above. Set the method to POST and map the normalised competitor data plus your product catalogue as the request body.

Step 5: Filter Recommendations and Quality Checks

Not every recommendation should be applied automatically. Use a Filter node to apply quality thresholds:

  • Only apply recommendations with confidence >= 0.75
  • Only apply if the recommended price change is between -15% and +25% (prevents wild swings)
  • Skip categories with very low inventory
  • Skip products where the price floor or ceiling would be violated

In n8n, add a Filter node with this expression:


{{ 
  $json.confidence >= 0.75 && 
  Math.abs($json.price_change_pct) <= 25 &&
  ($json.price_change_pct >= -15) &&
  $json.recommended_price >= $json.price_floor &&
  $json.recommended_price <= $json.price_ceiling
}}

This ensures only safe, sensible recommendations move to the next step. Log rejected recommendations to a separate channel for manual review.

Step 6: Update Product Database via Terrakotta AI

Terrakotta AI handles bulk product updates. Format the filtered recommendations as batch update instructions and send them to Terrakotta's bulk update endpoint:


POST /v1/products/batch-update
Headers:
  Authorization: Bearer YOUR_TERRAKOTTA_API_KEY
  Content-Type: application/json

Body:
{
  "batch_id": "pricing-update-2024-01-15",
  "updates": [
    {
      "sku": "SKU-12345",
      "fields": {
        "price": 47.99,
        "price_source": "automated_finster_recommendation",
        "price_updated_at": "2024-01-15T06:45:00Z",
        "price_change_reason": "competitive_positioning"
      }
    }
  ],
  "publish": true
}

Terrakotta returns a batch status:

{
  "batch_id": "pricing-update-2024-01-15",
  "status": "processing",
  "total_updates": 47,
  "estimated_completion": "2024-01-15T06:47:30Z"
}

In n8n, use another HTTP Request node. Set a wait loop that polls Terrakotta's batch status endpoint every 10 seconds until the batch completes, then proceed.

Step 7: Logging and Notification

Log all pricing changes to a database or spreadsheet for audit purposes, and send a summary to your pricing team via Slack or email.


POST /api/v1/audit-log
Body:
{
  "event_type": "automated_pricing_update",
  "batch_id": "pricing-update-2024-01-15",
  "products_updated": 47,
  "timestamp": "2024-01-15T06:47:30Z",
  "recommendations_applied": [
    {
      "sku": "SKU-12345",
      "old_price": 45.00,
      "new_price": 47.99,
      "change_pct": 6.64
    }
  ]
}

And send a Slack message:


POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Body:
{
  "text": "Pricing update complete",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Automated Pricing Update*\nBatch ID: pricing-update-2024-01-15\nProducts updated: 47\nAvg price change: +3.2%"
      }
    }
  ]
}

This entire workflow, from trigger to completion, should run in 5 to 10 minutes depending on the number of SKUs and competitor sources.

The Manual Alternative

If you prefer to keep human eyes on every pricing decision before it goes live, modify step 5 to send recommendations to an approval queue instead of automatically updating.

Replace the direct Terrakotta AI call with a Slack message that includes the recommendations in a formatted table. Add an approval button that either approves the batch or rejects it with comments. Store rejections in a database so you can identify patterns (e.g., "Your team consistently rejects price increases above 8%"; this feedback can then inform Finster AI's algorithm tuning).

This hybrid approach trades automation for control. It's slower, but it gives your pricing team explicit oversight of what's changing and why. For most companies, this is a sensible middle ground until you've built enough confidence in the algorithm.

Pro Tips

1. Manage API Rate Limits Proactively

Accio AI's scraping endpoint has a default rate limit of 100 concurrent requests. If you're scraping more than 50 competitor URLs, split the batch into chunks. In n8n, use a Loop node to process URLs in batches of 20, with a 2-second delay between batches.

const urls = $input.all()[0].json.urls;
const batchSize = 20;
const batches = [];

for (let i = 0; i < urls.length; i += batchSize) {
  batches.push(urls.slice(i, i + batchSize));
}

return { batches, total: batches.length };

Then iterate through batches rather than sending all URLs at once.

2. Cache Competitor Data to Reduce Costs

Scraping is expensive. Accio AI charges per successful scrape. If a competitor's website hasn't changed, you're paying to re-scrape the same data. Implement a caching layer: before calling Accio, check if you've already scraped that URL within the last 24 hours. If yes, use the cached data. If no, scrape fresh.

Store cached results in a Redis instance or in your database with a TTL (time-to-live). This typically cuts scraping costs by 40 to 50%.

3. Monitor for Outliers and Anomalies

A competitor's price drop from £50 to £10 overnight might be a data extraction error, not a real price change. Add a validation step that flags price changes beyond a certain threshold (e.g., more than 30% from the previous day's price). Log these outliers and exclude them from the recommendation calculation until they're manually verified.

const previousPrices = $input.all()[0].json.previous_competitor_prices;
const currentPrices = $input.all()[1].json.current_competitor_prices;
const outliers = [];

currentPrices.forEach(current => {
  const previous = previousPrices.find(p => p.sku === current.sku);
  if (previous) {
    const pctChange = Math.abs((current.price - previous.price) / previous.price);
    if (pctChange > 0.30) {
      outliers.push({
        sku: current.sku,
        previous: previous.price,
        current: current.price,
        change_pct: (pctChange * 100).toFixed(2)
      });
    }
  }
});

return outliers;

4. A/B Test Recommendations Before Full Rollout

Don't apply all recommended prices to all products simultaneously. Start by applying recommendations to 10% of your SKUs, measure the impact on conversion rate and revenue over one week, then expand. This approach reduces risk and gives you empirical evidence of whether the algorithm is working.

Use a consistent hash of the SKU to determine which products fall into the test group, so the same SKUs are always in the test.

5. Cost Optimisation: Use Event-Driven Triggers

Running the full workflow daily is safe but expensive. Instead, trigger it only when something changes: when a competitor's price changes, when your inventory drops below a threshold, when demand spikes. Use Accio AI's webhook feature to notify you of price changes in real-time, rather than scraping on a fixed schedule. This cuts API calls by 60 to 70% while keeping your pricing fresher.

Cost Breakdown

ToolPlan NeededMonthly CostNotes
Accio AIProfessional£450Includes 10,000 scrapes/month; overage at £0.045 per scrape. Assumes 2,000 scrapes/month for daily + event-driven updates.
Finster AIBusiness£299Unlimited pricing recommendations. Includes up to 100,000 SKUs.
Terrakotta AIGrowth£199Includes 50,000 product updates/month; overage at £0.004 per update. Budget for 1,500 updates/month.
n8n (self-hosted)Cloud Pro£40Alternative: self-host for free but requires DevOps support.
Total£988Plus infrastructure costs if self-hosting.

The typical payback is 2 to 3 weeks if automation enables even one profitable price optimisation per month.

More Recipes