n8n Umami Analytics to AI and Baserow Workflow

Overview

Type: AI Research, RAG, and Data Analysis Workflow
Node Types: manualTrigger, scheduleTrigger, httpRequest, stickyNote, code, baserow, main
Estimated Time: 7 min
Complexity: ⭐⭐⭐ Complex

📊 Summarize Umami Data with AI (via Openrouter) and Save to Baserow

This n8n Umami Analytics to AI and Baserow workflow automates the process of extracting valuable insights from your Umami analytics data. It fetches key website statistics, leverages Artificial Intelligence (Openrouter) to summarize overall performance and compare page-specific views week-over-week, and then neatly organizes all the actionable information into a Baserow database. This is ideal for SEO experts, content strategists, and website owners looking to streamline their analytics reporting, identify content optimization opportunities, and track performance trends efficiently.

🔧 Workflow Steps:

  1. When clicking ‘Test workflow’ / Schedule Trigger: Initiates the workflow either manually for testing or automatically on a predefined schedule (e.g., weekly on Thursday).
  2. Get view stats from Umami: Retrieves comprehensive website statistics, including pageviews, visitors, visits, bounces, and total time, for the last seven days from your Umami analytics instance.
  3. Parse Umami data: Processes the raw Umami summary data and transforms it into a URL-encoded string, making it ready for ingestion by the AI model.
  4. Send data to A.I.: Sends the prepared summary statistics to Openrouter AI, which then analyzes the data and provides a concise table summary in markdown format.
  5. Get page data from Umami: Fetches detailed page-specific view data for the current week directly from your Umami analytics.
  6. Parse Umami data1: Converts the current week’s page view data into a URL-encoded string, preparing it for AI comparison.
  7. Get page view data from Umami: Retrieves page-specific view data for the previous week (from 14 to 7 days ago) from your Umami analytics.
  8. Parse Umami: Transforms the previous week’s page view data into a URL-encoded string.
  9. Send data to A.I.1: Transmits both the current and previous week’s page data to Openrouter AI. The AI then compares the data, presents it in a markdown table, and offers five actionable improvement suggestions for your content or SEO strategy.
  10. Save data to Baserow: Stores all the AI-generated summaries, comparisons, and improvement suggestions into a designated Baserow table for organized record-keeping and easy access.

📌 Use Cases:

  • Automating the generation of weekly or monthly SEO performance reports.
  • Quickly identifying top-performing and underperforming content based on page views.
  • Leveraging AI to gain deeper insights and actionable recommendations for content optimization.
  • Consolidating website analytics data from Umami into a structured database like Baserow for historical tracking and custom analysis.
  • Streamlining the process of identifying trends and making data-driven decisions for your website.

🧰 Required Credentials:

  • Umami API: Requires HTTP Header Authentication to access your Umami analytics data.
  • Openrouter API: Needs HTTP Header Authentication. Set ‘Authorization’ as the username and ‘Bearer {Your API Key}’ as the password.
  • Baserow API: For connecting to your Baserow database and saving the processed data.

⚙️ Notes & Enhancements:

  • Remember to update the Umami URLs and website IDs in the ‘Get view stats from Umami’, ‘Get page data from Umami’, and ‘Get page view data from Umami’ nodes to match your specific Umami instance and website.
  • Before running the workflow, ensure you have a table set up in Baserow with the following columns: ‘Date’ (date type), ‘Summary’ (long text), ‘Top pages’ (long text), and ‘Blog name’ (long text).
  • The AI prompts are customizable; you can modify them in the ‘Send data to A.I.’ and ‘Send data to A.I.1’ nodes to tailor the AI’s analysis and output to your specific needs.
  • Explore other metrics and dimensions available in the Umami API documentation to enrich your analysis.

Workflow Editor Screenshot

Workflow Screenshot

Workflow JSON Code

{
"id": "eZT6SZ4Kvmq5TzyQ",
"meta": {
"instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a",
"templateCredsSetupCompleted": true
},
"name": "Umami analytics template",
"tags": [],
"nodes": [
{
"id": "8a54ac1c-a072-42e6-a3ba-8cde33475eb5",
"name": "When clicking ‘Test workflow’",
"type": "n8n-nodes-base.manualTrigger",
"position": [
460,
220
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e81c9be0-f59d-467e-9bda-eeb2d66ed31e",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
460,
380
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
4
]
}
]
}
},
"typeVersion": 1.2
},
{
"id": "01b04872-9aea-4834-8df5-f6c91914133d",
"name": "Get view stats from Umami",
"type": "n8n-nodes-base.httpRequest",
"position": [
760,
260
],
"parameters": {
"url": "=https://umami.mydomain.com/api/websites/86d4095c-a2a8-4fc8-9521-103e858e2b41/event-data/stats?startAt={{ DateTime.now().minus({ days: 7 }).toMillis() }}&endAt={{ DateTime.now().toMillis() }}&unit=hour&timezone=Asia%2FHong_Kong",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "FKsKXvQUlaX5qt9n",
"name": "Header Auth account 3"
}
},
"typeVersion": 4.2
},
{
"id": "38d342e3-10ad-4260-8f44-5a3233ec3166",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
660,
-260
],
"parameters": {
"width": 504.88636363636317,
"content": "## Send data from Umami to A.I. and then save to Baserow\n\nYou can find out more about the stats available in the [Umami API](https://umami.is/docs/api/website-stats-api)\n\nRead the [case study here](https://rumjahn.com/how-to-analyze-umami-data-using-n8n-and-a-i-to-improve-seo-and-uncover-hidden-insights-for-better-content-optimization/).\n\n"
},
"typeVersion": 1
},
{
"id": "18c997fe-61b1-464a-8bb5-fcdc017dd1f6",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
660,
-60
],
"parameters": {
"color": 4,
"width": 393.16558441558414,
"height": 504.17207792207796,
"content": "## Get summary stats from Umami\n\nIt will get: Pageviews, Visitors, Visits, Bounces, Total Time\n\nYou need to change the URL to your website. https://{your website}/api/websites/{website ID}/\n\nYou can find your ID by going to your Umami account -> Settings -> Edit (next to domain)"
},
"typeVersion": 1
},
{
"id": "bfdc04a2-57fa-4a8a-b412-39047cebb370",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1080,
-60
],
"parameters": {
"color": 5,
"width": 216.5746753246753,
"height": 502.37012987012963,
"content": "## Send data to A.I.\n\nTo use Openrouter, you need to register for an account.\nThen add header authorization credentials.\nUsername: Authroization\nPassword: Bearer {Your API Key}\n*It's Bearer space {API key}."
},
"typeVersion": 1
},
{
"id": "fc373fd7-52fc-4729-8022-021c09d0c89c",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1320,
-60
],
"parameters": {
"color": 6,
"width": 746.3474025974022,
"height": 505.9740259740257,
"content": "## Get page specific stats for this week and last\n\nCalls Umami to get this week and last week's data. It will get the views for each page visited on your website for comparison."
},
"typeVersion": 1
},
{
"id": "82bd35b6-8b49-4d77-8be2-033a8bff3f41",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2120,
-60
],
"parameters": {
"color": 5,
"width": 216.5746753246753,
"height": 502.37012987012963,
"content": "## Send data to A.I.\n\nTo use Openrouter, you need to register for an account.\nThen add header authorization credentials.\nUsername: Authroization\nPassword: Bearer {Your API Key}\n*It's Bearer space {API key}."
},
"typeVersion": 1
},
{
"id": "503c4ca3-36da-41a8-9029-f844a34daa59",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2380,
-60
],
"parameters": {
"color": 4,
"width": 393.16558441558414,
"height": 504.17207792207796,
"content": "## Save analysis to baserow\n\nYou need to create a table in advance to save. \n- Date (date)\n- Summary (Long text)\n- Top pages (Long text)\n- Blog name (Long text)"
},
"typeVersion": 1
},
{
"id": "f64cdfbd-712f-461c-b025-25f37e2bded8",
"name": "Parse Umami data",
"type": "n8n-nodes-base.code",
"position": [
940,
260
],
"parameters": {
"jsCode": "function transformToUrlString(items) {\n // In n8n, we need to check if items is an array and get the json property\n const data = items[0].json;\n \n if (!data) {\n console.log('No valid data found');\n return encodeURIComponent(JSON.stringify([]));\n }\n \n try {\n // Create a simplified object with the metrics\n const simplified = {\n pageviews: {\n value: parseInt(data.pageviews.value) || 0,\n prev: parseInt(data.pageviews.prev) || 0\n },\n visitors: {\n value: parseInt(data.visitors.value) || 0,\n prev: parseInt(data.visitors.prev) || 0\n },\n visits: {\n value: parseInt(data.visits.value) || 0,\n prev: parseInt(data.visits.prev) || 0\n },\n bounces: {\n value: parseInt(data.bounces.value) || 0,\n prev: parseInt(data.bounces.prev) || 0\n },\n totaltime: {\n value: parseInt(data.totaltime.value) || 0,\n prev: parseInt(data.totaltime.prev) || 0\n }\n };\n \n return encodeURIComponent(JSON.stringify(simplified));\n } catch (error) {\n console.log('Error processing data:', error);\n throw new Error('Invalid data structure');\n }\n}\n\n// Get the input data\nconst items = $input.all();\n\n// Process the data\nconst result = transformToUrlString(items);\n\n// Return the result\nreturn { json: { urlString: result } };"
},
"typeVersion": 2
},
{
"id": "470715b6-0878-48b8-b6c6-40de27fbc966",
"name": "Send data to A.I.",
"type": "n8n-nodes-base.httpRequest",
"position": [
1140,
260
],
"parameters": {
"url": "https://openrouter.ai/api/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"meta-llama/llama-3.1-70b-instruct:free\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"You are an SEO expert. Here is data from Umami analytics of Pennibnotes.com. Where X is URL and Y is number of visitors. Give me a table summary of this data in markdown format:{{ $('Parse Umami data').item.json.urlString }}.\"\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "WY7UkF14ksPKq3S8",
"name": "Header Auth account 2"
}
},
"typeVersion": 4.2
},
{
"id": "ea4bb37f-96d9-41b8-bf46-fb09865a6e0f",
"name": "Get page data from Umami",
"type": "n8n-nodes-base.httpRequest",
"position": [
1380,
260
],
"parameters": {
"url": "=https://umami.rumjahn.synology.me/api/websites/f375d28c-1949-4597-8871-f1b942e3aa24/metrics?startAt={{Date.now() - (7 * 24 * 60 * 60 * 1000)}}&endAt={{Date.now()}}&type=url&tz=America/Los_Angeles",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "FKsKXvQUlaX5qt9n",
"name": "Header Auth account 3"
}
},
"typeVersion": 4
},
{
"id": "d982606b-49c8-4d5b-ba79-bd0fdd2600b6",
"name": "Parse Umami data1",
"type": "n8n-nodes-base.code",
"position": [
1560,
260
],
"parameters": {
"jsCode": "// Get input data\nconst data = $input.all();\n\n// Create URL-encoded string from the data\nconst encodedData = encodeURIComponent(JSON.stringify(data));\n\n// Return the encoded data\nreturn {\n json: {\n thisWeek: encodedData\n }\n};"
},
"typeVersion": 2
},
{
"id": "f3734045-1318-4234-a3ac-61b766124609",
"name": "Get page view data from Umami",
"type": "n8n-nodes-base.httpRequest",
"position": [
1760,
260
],
"parameters": {
"url": "=https://umami.rumjahn.synology.me/api/websites/f375d28c-1949-4597-8871-f1b942e3aa24/metrics?startAt={{Date.now() - (14 * 24 * 60 * 60 * 1000)}}&endAt={{Date.now() - (7 * 24 * 60 * 60 * 1000)}}&type=url&tz=America/Los_Angeles",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "FKsKXvQUlaX5qt9n",
"name": "Header Auth account 3"
}
},
"typeVersion": 4
},
{
"id": "a0153ab0-3eaf-4f97-a2dc-ab63d45a9187",
"name": "Parse Umami",
"type": "n8n-nodes-base.code",
"position": [
1920,
260
],
"parameters": {
"jsCode": "// Get input data\nconst data = $input.all();\n\n// Create URL-encoded string from the data\nconst encodedData = encodeURIComponent(JSON.stringify(data));\n\n// Return the encoded data\nreturn {\n json: {\n lastweek: encodedData\n }\n};"
},
"typeVersion": 2
},
{
"id": "c2d3d396-09fa-4800-b56d-40ed7592cd3c",
"name": "Send data to A.I.1",
"type": "n8n-nodes-base.httpRequest",
"position": [
2180,
260
],
"parameters": {
"url": "https://openrouter.ai/api/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"meta-llama/llama-3.1-70b-instruct:free\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": \"You are an SEO expert. Here is data from Umami analytics of Pennibnotes.com. Where X is URL and Y is number of visitors. Compare the data from this week to last week. Present the data in a table using markdown and offer 5 improvement suggestions. This week:{{ $('Parse Umami data1').first().json.thisWeek }} Lastweek:{{ $json.lastweek }}\"\n }\n ]\n}\n\n",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "WY7UkF14ksPKq3S8",
"name": "Header Auth account 2"
}
},
"typeVersion": 4.2
},
{
"id": "ce58a556-c05a-4395-88b0-3edecbad80e5",
"name": "Save data to Baserow",
"type": "n8n-nodes-base.baserow",
"position": [
2520,
260
],
"parameters": {
"tableId": 607,
"fieldsUi": {
"fieldValues": [
{
"fieldId": 5870,
"fieldValue": "={{ $json.choices[0].message.content }}"
},
{
"fieldId": 5869,
"fieldValue": "={{ $('Send data to A.I.').first().json.choices[0].message.content }}"
},
{
"fieldId": 5868,
"fieldValue": "={{ DateTime.now().toFormat('yyyy-MM-dd') }}"
},
{
"fieldId": 5871,
"fieldValue": "Name of your blog"
}
]
},
"operation": "create",
"databaseId": 121
},
"credentials": {
"baserowApi": {
"id": "8w0zXhycIfCAgja3",
"name": "Baserow account"
}
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "e28e067d-9245-4879-9321-4d21925f951e",
"connections": {
"Parse Umami": {
"main": [
[
{
"node": "Send data to A.I.1",
"type": "main",
"index": 0
}
]
]
},
"Parse Umami data": {
"main": [
[
{
"node": "Send data to A.I.",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get view stats from Umami",
"type": "main",
"index": 0
}
]
]
},
"Parse Umami data1": {
"main": [
[
{
"node": "Get page view data from Umami",
"type": "main",
"index": 0
}
]
]
},
"Send data to A.I.": {
"main": [
[
{
"node": "Get page data from Umami",
"type": "main",
"index": 0
}
]
]
},
"Send data to A.I.1": {
"main": [
[
{
"node": "Save data to Baserow",
"type": "main",
"index": 0
}
]
]
},
"Get page data from Umami": {
"main": [
[
{
"node": "Parse Umami data1",
"type": "main",
"index": 0
}
]
]
},
"Get view stats from Umami": {
"main": [
[
{
"node": "Parse Umami data",
"type": "main",
"index": 0
}
]
]
},
"Get page view data from Umami": {
"main": [
[
{
"node": "Parse Umami",
"type": "main",
"index": 0
}
]
]
},
"When clicking ‘Test workflow’": {
"main": [
[
{
"node": "Get view stats from Umami",
"type": "main",
"index": 0
}
]
]
}
}
}