{
  "id": "OO4izN00xPfIPGaB",
  "meta": {
    "instanceId": "b3c467df4053d13fe31cc98f3c66fa1d16300ba750506bfd019a0913cec71ea3",
    "templateCredsSetupCompleted": true
  },
  "name": "Ahrefs Keyword Research Workflow",
  "tags": [],
  "nodes": [
    {
      "id": "4e420798-7523-4d47-af27-10f85d09f01d",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -300,
        -60
      ],
      "webhookId": "f40acbbc-ac03-43d1-9341-6c9e8c674293",
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "0f71c28e-a11b-4aed-a342-e15d2714ab47",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -160,
        140
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-1.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "zT4YaNflEp2E6S3m",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9b24fc9d-ac8d-4a9b-a7a5-00d1665f47af",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        980,
        160
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-1.5-flash"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "zT4YaNflEp2E6S3m",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d0cbe978-040d-4663-895e-85844e203773",
      "name": "Keyword Data Response Formatter",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        980,
        -60
      ],
      "parameters": {
        "text": "Provide reponse according to the system message. ",
        "options": {
          "systemMessage": "=system_message:n  description: |n    Your role is to format and output the keyword data into a clean, readable text format. The input data consists of two main parts: **Main Keyword Data** and **Related Keywords Data**. Your task is to process and output this data in a way that is easy to read for the user. Each keyword and its associated details should be displayed clearly.nn  Data:n    - **Main Keyword Datau2728**:n        - **Keyword**: "{{ $json.data[0].keyword }}"n        - **Average Monthly Searches**: "{{ $json.data[0].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[0].competition_index }}"n          - **Competition Value**: "{{ $json.data[0].competition_value }}"n          - **High CPC**: "{{ $json.data[0].high_cpc }}"n          - **Low CPC**: "{{ $json.data[0].low_cpc }}"nn    - **Related Keywordsud83euddf0**:n              n    n        - **1. Keyword**: "{{ $json.data[1].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[1].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[1].competition_index }}"n          - **Competition Value**: "{{ $json.data[1].competition_value }}"n          - **High CPC**: "{{ $json.data[1].high_cpc }}"n          - **Low CPC**: "{{ $json.data[1].low_cpc }}"n        n        - **2. Keyword**: "{{ $json.data[2].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[2].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[2].competition_index }}"n          - **Competition Value**: "{{ $json.data[2].competition_value }}"n          - **High CPC**: "{{ $json.data[2].high_cpc }}"n          - **Low CPC**: "{{ $json.data[2].low_cpc }}"n        n        - **3. Keyword**: "{{ $json.data[3].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[3].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[3].competition_index }}"n          - **Competition Value**: "{{ $json.data[3].competition_value }}"n          - **High CPC**: "{{ $json.data[3].high_cpc }}"n          - **Low CPC**: "{{ $json.data[3].low_cpc }}"n        n        - **4. Keyword**: "{{ $json.data[4].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[4].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[4].competition_index }}"n          - **Competition Value**: "{{ $json.data[4].competition_value }}"n          - **High CPC**: "{{ $json.data[4].high_cpc }}"n          - **Low CPC**: "{{ $json.data[4].low_cpc }}"n        n        - **5. Keyword**: "{{ $json.data[5].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[5].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[5].competition_index }}"n          - **Competition Value**: "{{ $json.data[5].competition_value }}"n          - **High CPC**: "{{ $json.data[5].high_cpc }}"n          - **Low CPC**: "{{ $json.data[5].low_cpc }}"n        n        - **6. Keyword**: "{{ $json.data[6].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[6].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[6].competition_index }}"n          - **Competition Value**: "{{ $json.data[6].competition_value }}"n          - **High CPC**: "{{ $json.data[6].high_cpc }}"n          - **Low CPC**: "{{ $json.data[6].low_cpc }}"n        n        - **7. Keyword**: "{{ $json.data[7].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[7].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[7].competition_index }}"n          - **Competition Value**: "{{ $json.data[7].competition_value }}"n          - **High CPC**: "{{ $json.data[7].high_cpc }}"n          - **Low CPC**: "{{ $json.data[7].low_cpc }}"n        n        - **8. Keyword**: "{{ $json.data[8].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[8].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[8].competition_index }}"n          - **Competition Value**: "{{ $json.data[8].competition_value }}"n          - **High CPC**: "{{ $json.data[8].high_cpc }}"n          - **Low CPC**: "{{ $json.data[8].low_cpc }}"n        n        - **9. Keyword**: "{{ $json.data[9].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[9].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[9].competition_index }}"n          - **Competition Value**: "{{ $json.data[9].competition_value }}"n          - **High CPC**: "{{ $json.data[9].high_cpc }}"n          - **Low CPC**: "{{ $json.data[9].low_cpc }}"nn        - **10. Keyword**: "{{ $json.data[10].keyword }}"n          - **Average Monthly Searches**: "{{ $json.data[10].avg_monthly_searches }}"n          - **Competition Index**: "{{ $json.data[10].competition_index }}"n          - **Competition Value**: "{{ $json.data[10].competition_value }}"n          - **High CPC**: "{{ $json.data[10].high_cpc }}"n          - **Low CPC**: "{{ $json.data[10].low_cpc }}"n"
        },
        "promptType": "define"
      },
      "typeVersion": 1.8
    },
    {
      "id": "9cb26cde-dbff-4118-a141-ebd1fd7df1b1",
      "name": "Keyword Query Extraction & Cleaning Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -80,
        -60
      ],
      "parameters": {
        "options": {
          "systemMessage": "You are a helpful assistant. You job is to check the user message and pick out the SEO keyword they have provided and output it. Make sure you output just one SEO keyword. No commentary. Do not rephrase, just correct grammar if it has been misspelt."
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "6a59bf1f-68a3-433c-9cf7-47cadc1a77eb",
      "name": "Extract Main Keyword & 10 related Keyword data",
      "type": "n8n-nodes-base.code",
      "position": [
        540,
        -60
      ],
      "parameters": {
        "jsCode": "// Get the main keyword data (Global Keyword Data)nconst mainKeywordData = $input.first().json['Global Keyword Data']?.[0] || {};nn// Get the related keywords arraynconst relatedKeywords = $input.first().json['Related Keyword Data (Global)'] || [];nn// Create an output array that includes the main keyword data firstnconst output = [n  {n    keyword: mainKeywordData.keyword || 'N/A',n    avg_monthly_searches: mainKeywordData.avg_monthly_searches || 'N/A',n    competition_index: mainKeywordData.competition_index || 'N/A',n    competition_value: mainKeywordData.competition_value || 'N/A',n    high_cpc: mainKeywordData['High CPC'] || 'N/A',n    low_cpc: mainKeywordData['Low CPC'] || 'N/A'n  },n  // Map up to 10 related keywords with selected fieldsn  ...relatedKeywords.slice(0, 10).map(item => ({n    keyword: item.keyword,n    avg_monthly_searches: item.avg_monthly_searches,n    competition_index: item.competition_index,n    competition_value: item.competition_value,n    high_cpc: item['High CPC'],n    low_cpc: item['Low CPC']n  }))n];nnreturn output;n"
      },
      "typeVersion": 2
    },
    {
      "id": "a2b1b9ff-a425-4c99-bd36-a4bb0e0cd84e",
      "name": "Aggregate Keyword Data",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        800,
        -60
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "36d4c962-71f2-473a-841c-053c6c36bcda",
      "name": "Ahrefs Keyword API Request",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        280,
        -60
      ],
      "parameters": {
        "url": "https://ahrefs-keyword-tool.p.rapidapi.com/global-volume",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "keyword",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-rapidapi-host",
              "value": "ahrefs-keyword-tool.p.rapidapi.com"
            },
            {
              "name": "x-rapidapi-key",
              "value": ""your_rapid_api_key_here""
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "47898c8e-37e7-4abc-beb2-64fc546a7c03",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -260
      ],
      "parameters": {
        "color": 6,
        "width": 260,
        "content": "## Keyword Query ExtractionnThis ai agent is important so that you always make sure for all queries you send, only the keyword phrase will be passed over to the API request node, and if you misspell any word, it will be corrected."
      },
      "typeVersion": 1
    },
    {
      "id": "c83f2813-d57c-48d6-8c66-6a057ca9cfc9",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        -260
      ],
      "parameters": {
        "color": 4,
        "content": "## The API RequestnYou can tweak this to either get "answer the public kwywords" or "keyword overviews", just visit the api   [docs page](https://rapidapi.com/environmentn1t21r5/api/ahrefs-keyword-tool/playground/apiendpoint_d2790246-c8ef-437f-b928-c0eb6f6ffff4)"
      },
      "typeVersion": 1
    },
    {
      "id": "98ad64ea-d023-49c0-ab05-21bd87c322b9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        600,
        -260
      ],
      "parameters": {
        "content": "## Extract Keyword DatanThe data from the API query will be so so big and I have written this javascript function to extract the most important bits. You can modify it if you want to also get monthly data, or just download the response as pdf and probably pass it for analysis."
      },
      "typeVersion": 1
    },
    {
      "id": "1f1d15f3-36f7-4bad-be63-ce74c70580f1",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        -260
      ],
      "parameters": {
        "width": 260,
        "content": "## Trigger NodenThis is just a sample trigger node to get started. You can use a telegram, whatsapp, webhook node etc, to get the keyword queried. "
      },
      "typeVersion": 1
    },
    {
      "id": "a5e0b305-ebc7-44e2-ada2-8d5cf60a1fe2",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        980,
        -260
      ],
      "parameters": {
        "content": "## Respose FormatternThe ai agent node to format responses will give you more room to decide how you want your summaries to be sent back to you. You can modify the system message to get your desired outcome. Otherwise, good luck building on top of this. I will give a detailed docs guide on the main n8n workflow page"
      },
      "typeVersion": 1
    },
    {
      "id": "00ce5fc5-aff8-4cde-871e-ffea5aa5ffb3",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        40,
        140
      ],
      "parameters": {},
      "typeVersion": 1.3
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "e2857a0c-4473-4d3d-9c63-6b02337bccf0",
  "connections": {
    "Simple Memory": {
      "ai_memory": [
        []
      ]
    },
    "Aggregate Keyword Data": {
      "main": [
        [
          {
            "node": "Keyword Data Response Formatter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Keyword Query Extraction & Cleaning Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Keyword Data Response Formatter",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Ahrefs Keyword API Request": {
      "main": [
        [
          {
            "node": "Extract Main Keyword & 10 related Keyword data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Keyword Query Extraction & Cleaning Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keyword Query Extraction & Cleaning Agent": {
      "main": [
        [
          {
            "node": "Ahrefs Keyword API Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Main Keyword & 10 related Keyword data": {
      "main": [
        [
          {
            "node": "Aggregate Keyword Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}