AutomationFlowsSocial Media › Dashboard API

Dashboard API

03 - Dashboard API. Uses postgres. Webhook trigger; 4 nodes.

Webhook trigger★★★★☆ complexity4 nodesPostgres
Social Media Trigger: Webhook Nodes: 4 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "name": "03 - Dashboard API",
  "settings": {
    "executionOrder": "v1"
  },
  "nodes": [
    {
      "parameters": {
        "httpMethod": "GET",
        "path": "dashboard-stats",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-in",
      "name": "GET /dashboard-stats",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -220,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT id, topic, post_text, linkedin_urn, posted_at, status, likes, comments, shares, impressions\nFROM latest_post_stats\nLIMIT 200;",
        "options": {}
      },
      "id": "query-stats",
      "name": "Query latest_post_stats",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        0,
        0
      ],
      "alwaysOutputData": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "notes": "alwaysOutputData is REQUIRED. n8n skips nodes that receive zero items, so on an empty database the response node would never run and the webhook would hang until timeout."
    },
    {
      "parameters": {
        "jsCode": "// alwaysOutputData can hand us a single empty item when there are no rows yet -\n// filter it out so an empty database returns clean zeros instead of a phantom post.\nconst rows = $input.all()\n  .map((item) => item.json)\n  .filter((r) => r && r.id != null);\n\nconst totals = rows.reduce((acc, r) => {\n  acc.totalPosts += 1;\n  acc.totalLikes += r.likes || 0;\n  acc.totalComments += r.comments || 0;\n  return acc;\n}, { totalPosts: 0, totalLikes: 0, totalComments: 0 });\n\nconst byTopic = {};\nfor (const r of rows) {\n  const key = r.topic || 'uncategorised';\n  if (!byTopic[key]) byTopic[key] = { topic: key, posts: 0, likes: 0, comments: 0 };\n  byTopic[key].posts += 1;\n  byTopic[key].likes += r.likes || 0;\n  byTopic[key].comments += r.comments || 0;\n}\n\nreturn [{\n  json: {\n    totals,\n    byTopic: Object.values(byTopic).sort((a, b) => (b.likes + b.comments) - (a.likes + a.comments)),\n    posts: rows,\n    generatedAt: new Date().toISOString()\n  }\n}];"
      },
      "id": "shape-response",
      "name": "Shape Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              },
              {
                "name": "Cache-Control",
                "value": "no-store"
              }
            ]
          }
        }
      },
      "id": "respond",
      "name": "Respond JSON",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        440,
        0
      ],
      "notes": "Access-Control-Allow-Origin is * so the static dashboard can call this from GitHub Pages. Narrow it to your Pages domain if you would rather not leave it open."
    }
  ],
  "connections": {
    "GET /dashboard-stats": {
      "main": [
        [
          {
            "node": "Query latest_post_stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query latest_post_stats": {
      "main": [
        [
          {
            "node": "Shape Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shape Response": {
      "main": [
        [
          {
            "node": "Respond JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

03 - Dashboard API. Uses postgres. Webhook trigger; 4 nodes.

Source: https://github.com/kapoordeepanshu/linkedin-autopilot-n8n/blob/main/n8n-workflows/03-dashboard-api.json — original creator credit. Request a take-down →

More Social Media workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Social Media

generación_publicaciones (workflow 3) webhook all platforms decrypt publicar git. Uses dataTable, linkedIn, httpRequest. Webhook trigger; 50 nodes.

Data Table, LinkedIn, HTTP Request
Social Media

Automatically discovers trending topics in your niche and generates ready-to-use content ideas with AI. Twitter/X trending topics and hashtags Reddit hot posts from niche subreddits Google Trends dail

HTTP Request, Email Send, Slack +1
Social Media

This workflow captures buying-signal leads via a webhook (or optionally polls a HubSpot list), generates a personalized LinkedIn intro and follow-up sequence with Twain, and posts the ready-to-send dr

HTTP Request, Slack
Social Media

Automatically generates engaging marketing posts using OpenAI and publishes them across LinkedIn, Twitter (X), and Facebook. Creates platform-optimized content with hashtags, emojis, and proper format

HTTP Request, Postgres
Social Media

Twitter Stream Monitor. Uses googleDrive, googleSheets. Webhook trigger; 19 nodes.

Google Drive, Google Sheets