This workflow follows the HTTP Request → Postgres recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Multi-Platform Price Monitor & Dynamic Pricing",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"id": "cron-trigger",
"name": "Scheduled Price Check",
"type": "n8n-nodes-base.cron",
"position": [
240,
300
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $vars.SHOPIFY_STORE_URL }}/admin/api/2023-10/products.json",
"authentication": "headerAuth",
"headerAuth": {
"name": "X-Shopify-Access-Token",
"value": "={{ $vars.SHOPIFY_ACCESS_TOKEN }}"
},
"options": {
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "50"
},
{
"name": "fields",
"value": "id,title,variants,vendor,product_type,tags"
}
]
}
}
},
"id": "shopify-products",
"name": "Get Shopify Products",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "product-data",
"name": "product_id",
"value": "={{ $json.id }}",
"type": "string"
},
{
"id": "product-title",
"name": "title",
"value": "={{ $json.title }}",
"type": "string"
},
{
"id": "current-price",
"name": "current_price",
"value": "={{ $json.variants[0].price }}",
"type": "number"
},
{
"id": "sku",
"name": "sku",
"value": "={{ $json.variants[0].sku }}",
"type": "string"
},
{
"id": "inventory",
"name": "inventory_quantity",
"value": "={{ $json.variants[0].inventory_quantity }}",
"type": "number"
}
]
},
"options": {}
},
"id": "extract-product-data",
"name": "Extract Product Data",
"type": "n8n-nodes-base.set",
"position": [
680,
300
]
},
{
"parameters": {
"url": "https://api.amazon.com/products/search",
"authentication": "headerAuth",
"headerAuth": {
"name": "Authorization",
"value": "Bearer {{ $vars.AMAZON_ACCESS_TOKEN }}"
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "query",
"value": "={{ $json.title }}"
},
{
"name": "category",
"value": "all"
}
]
}
},
"id": "amazon-price-check",
"name": "Check Amazon Prices",
"type": "n8n-nodes-base.httpRequest",
"position": [
900,
200
]
},
{
"parameters": {
"url": "https://api.ebay.com/buy/browse/v1/item_summary/search",
"authentication": "headerAuth",
"headerAuth": {
"name": "Authorization",
"value": "Bearer {{ $vars.EBAY_ACCESS_TOKEN }}"
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "={{ $json.title }}"
},
{
"name": "limit",
"value": "10"
}
]
}
},
"id": "ebay-price-check",
"name": "Check eBay Prices",
"type": "n8n-nodes-base.httpRequest",
"position": [
900,
400
]
},
{
"parameters": {
"jsCode": "// Price analysis and optimization logic\nconst productData = $input.first().json;\nconst amazonPrices = $('Check Amazon Prices').first().json.products || [];\nconst ebayPrices = $('Check eBay Prices').first().json.itemSummaries || [];\n\n// Extract competitor prices\nconst competitorPrices = [\n ...amazonPrices.map(p => parseFloat(p.price?.value || 0)),\n ...ebayPrices.map(p => parseFloat(p.price?.value || 0))\n].filter(price => price > 0);\n\n// Calculate market statistics\nconst marketStats = {\n min: Math.min(...competitorPrices),\n max: Math.max(...competitorPrices),\n avg: competitorPrices.reduce((a, b) => a + b, 0) / competitorPrices.length,\n median: competitorPrices.sort()[Math.floor(competitorPrices.length / 2)]\n};\n\n// Current product price\nconst currentPrice = parseFloat(productData.current_price);\nconst inventoryLevel = productData.inventory_quantity;\n\n// Dynamic pricing rules\nlet recommendedPrice = currentPrice;\nlet priceAction = 'no_change';\nlet reason = 'Price is optimal';\n\n// Rule 1: Competitive pricing\nif (marketStats.min > 0 && currentPrice > marketStats.avg * 1.15) {\n recommendedPrice = Math.max(marketStats.avg * 1.05, currentPrice * 0.9);\n priceAction = 'decrease';\n reason = 'Price too high compared to market average';\n}\n\n// Rule 2: Inventory-based pricing\nif (inventoryLevel < 10) {\n recommendedPrice = Math.max(recommendedPrice, currentPrice * 1.1);\n priceAction = 'increase';\n reason = 'Low inventory - premium pricing';\n} else if (inventoryLevel > 100) {\n recommendedPrice = Math.min(recommendedPrice, currentPrice * 0.95);\n priceAction = 'decrease';\n reason = 'High inventory - clearance pricing';\n}\n\n// Rule 3: Margin protection (assume 30% cost ratio)\nconst minPrice = currentPrice * 0.7 / 0.7; // Maintain minimum margin\nrecommendedPrice = Math.max(recommendedPrice, minPrice);\n\n// Price change threshold (minimum 2% change)\nconst priceChangePercent = Math.abs(recommendedPrice - currentPrice) / currentPrice;\nif (priceChangePercent < 0.02) {\n recommendedPrice = currentPrice;\n priceAction = 'no_change';\n reason = 'Price change too small to implement';\n}\n\nreturn {\n json: {\n product_id: productData.product_id,\n title: productData.title,\n sku: productData.sku,\n current_price: currentPrice,\n recommended_price: Math.round(recommendedPrice * 100) / 100,\n price_action: priceAction,\n reason: reason,\n inventory_level: inventoryLevel,\n market_stats: marketStats,\n competitor_count: competitorPrices.length,\n price_change_percent: Math.round(priceChangePercent * 10000) / 100,\n analysis_timestamp: new Date().toISOString()\n }\n};"
},
"id": "price-analysis",
"name": "Price Analysis Engine",
"type": "n8n-nodes-base.code",
"position": [
1120,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "price-change-needed",
"leftValue": "={{ $json.price_action }}",
"rightValue": "no_change",
"operator": {
"type": "string",
"operation": "notEqual"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "price-update-check",
"name": "Should Update Price?",
"type": "n8n-nodes-base.if",
"position": [
1340,
300
]
},
{
"parameters": {
"method": "PUT",
"url": "={{ $vars.SHOPIFY_STORE_URL }}/admin/api/2023-10/variants/{{ $json.variant_id }}.json",
"authentication": "headerAuth",
"headerAuth": {
"name": "X-Shopify-Access-Token",
"value": "={{ $vars.SHOPIFY_ACCESS_TOKEN }}"
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "variant.price",
"value": "={{ $json.recommended_price }}"
}
]
}
},
"id": "update-shopify-price",
"name": "Update Shopify Price",
"type": "n8n-nodes-base.httpRequest",
"position": [
1560,
200
]
},
{
"parameters": {
"operation": "create",
"table": "price_history",
"columns": {
"mappingMode": "defineBelow",
"value": {
"product_id": "={{ $json.product_id }}",
"sku": "={{ $json.sku }}",
"old_price": "={{ $json.current_price }}",
"new_price": "={{ $json.recommended_price }}",
"price_action": "={{ $json.price_action }}",
"reason": "={{ $json.reason }}",
"competitor_count": "={{ $json.competitor_count }}",
"market_avg": "={{ $json.market_stats.avg }}",
"inventory_level": "={{ $json.inventory_level }}",
"timestamp": "={{ $json.analysis_timestamp }}"
}
},
"options": {}
},
"id": "log-price-change",
"name": "Log Price Change",
"type": "n8n-nodes-base.postgres",
"position": [
1560,
400
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "={{ $vars.SLACK_WEBHOOK_URL }}",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "\ud83d\udcb0 Price Update: {{ $json.title }}\n\ud83d\udcca {{ $json.current_price }} \u2192 {{ $json.recommended_price }} ({{ $json.price_change_percent }}%)\n\ud83d\udcc8 Action: {{ $json.price_action }}\n\ud83d\udca1 Reason: {{ $json.reason }}\n\ud83d\udce6 Inventory: {{ $json.inventory_level }} units\n\ud83c\udfc6 Competitors: {{ $json.competitor_count }} tracked"
}
]
}
},
"id": "slack-notification",
"name": "Send Price Alert",
"type": "n8n-nodes-base.httpRequest",
"position": [
1780,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "monitoring-summary",
"name": "summary",
"value": "Price monitoring completed for {{ $json.title }}",
"type": "string"
},
{
"id": "no-change-reason",
"name": "reason",
"value": "{{ $json.reason }}",
"type": "string"
}
]
}
},
"id": "no-change-log",
"name": "Log No Change",
"type": "n8n-nodes-base.set",
"position": [
1560,
600
]
},
{
"parameters": {
"jsCode": "// Error handling and retry logic\nconst error = $input.first().json;\n\nreturn {\n json: {\n error_type: error.name || 'Unknown Error',\n error_message: error.message || 'An error occurred',\n product_id: $('Extract Product Data').first()?.json?.product_id || 'unknown',\n timestamp: new Date().toISOString(),\n retry_count: $executionData.workflowData?.retryCount || 0\n }\n};"
},
"id": "error-handler",
"name": "Error Handler",
"type": "n8n-nodes-base.code",
"position": [
1340,
700
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"url": "={{ $vars.SLACK_WEBHOOK_URL }}",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "\ud83d\udea8 Price Monitor Error!\n\u274c Type: {{ $json.error_type }}\n\ud83d\udcdd Message: {{ $json.error_message }}\n\ud83c\udd94 Product: {{ $json.product_id }}\n\ud83d\udd04 Retry: {{ $json.retry_count }}/3"
}
]
}
},
"id": "error-notification",
"name": "Send Error Alert",
"type": "n8n-nodes-base.httpRequest",
"position": [
1560,
700
]
}
],
"connections": {
"Scheduled Price Check": {
"main": [
[
{
"node": "Get Shopify Products",
"type": "main",
"index": 0
}
]
]
},
"Get Shopify Products": {
"main": [
[
{
"node": "Extract Product Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Product Data": {
"main": [
[
{
"node": "Check Amazon Prices",
"type": "main",
"index": 0
},
{
"node": "Check eBay Prices",
"type": "main",
"index": 0
}
]
]
},
"Check Amazon Prices": {
"main": [
[
{
"node": "Price Analysis Engine",
"type": "main",
"index": 0
}
]
]
},
"Check eBay Prices": {
"main": [
[
{
"node": "Price Analysis Engine",
"type": "main",
"index": 0
}
]
]
},
"Price Analysis Engine": {
"main": [
[
{
"node": "Should Update Price?",
"type": "main",
"index": 0
}
]
]
},
"Should Update Price?": {
"main": [
[
{
"node": "Update Shopify Price",
"type": "main",
"index": 0
},
{
"node": "Log Price Change",
"type": "main",
"index": 0
}
],
[
{
"node": "Log No Change",
"type": "main",
"index": 0
}
]
]
},
"Update Shopify Price": {
"main": [
[
{
"node": "Send Price Alert",
"type": "main",
"index": 0
}
]
]
},
"Log Price Change": {
"main": [
[
{
"node": "Send Price Alert",
"type": "main",
"index": 0
}
]
]
},
"Error Handler": {
"main": [
[
{
"node": "Send Error Alert",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "error-handler"
},
"versionId": "1.0.0",
"meta": {
"templateCredsSetupCompleted": false
},
"id": "price-monitor",
"tags": [
{
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"id": "e-commerce",
"name": "E-commerce"
},
{
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"id": "pricing",
"name": "Pricing"
},
{
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"id": "automation",
"name": "Automation"
}
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
postgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Keep your online store's prices competitive across platforms by automatically monitoring competitors on Amazon and eBay, then dynamically adjusting your Shopify listings to stay ahead without constant manual effort. This saves time for e-commerce owners juggling multiple marketplaces, ensuring you never undersell or overprice. The key step involves a scheduled price check that fetches your Shopify products, pulls competitor data via HTTP requests, analyses the figures in a custom code node, and updates prices only if needed.
Use this workflow for small to medium e-commerce operations selling on Shopify with direct rivals on Amazon and eBay, especially when prices fluctuate daily. Avoid it for high-volume stores needing real-time monitoring, as the cron trigger runs on a fixed schedule rather than instantly. Common variations include adding more competitor sites like Etsy or integrating with a different database instead of Postgres for storing historical price data.
About this workflow
Multi-Platform Price Monitor & Dynamic Pricing. Uses httpRequest, postgres. Scheduled trigger; 13 nodes.
Source: https://github.com/MustafaKemal0146/Yapay-Zeka-Otomasyon-1/blob/46e56683900ff2af1a0007b7141a1f8cb0a32541/automations/e-commerce/price-monitor/workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.
공유회_알림톡_크론. Uses postgres, httpRequest, n8n-nodes-solapi. Scheduled trigger; 39 nodes.
QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.
QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.
QuepasaAutomatic. Uses postgres, postgresTrigger, httpRequest. Scheduled trigger; 39 nodes.