AutomationFlowsSocial Media › Automated Meta Token Renewal System with Graph API and Data Storage

Automated Meta Token Renewal System with Graph API and Data Storage

ByGeoffroy @jojoq42 on n8n.io

Meta long-lived user tokens typically expire after ~60 days. If a token expires, any workflows that rely on it start failing. Manual renewal is easy to forget and time consuming. This template monitors the token you store in an n8n Data Table and refreshes it automatically…

Cron / scheduled trigger★★★★☆ complexity13 nodesData TableHTTP Request
Social Media Trigger: Cron / scheduled Nodes: 13 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #9604 — we link there as the canonical source.

This workflow follows the Datatable → HTTP Request 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 →

Download .json
{
  "id": "QRfOs6S3QrhslSFD",
  "name": "Facebook & Instagram Renovation Token",
  "tags": [],
  "nodes": [
    {
      "id": "56b6e307-f5e0-405e-9e1e-eb8e2d49b518",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -304,
        -80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "daysInterval": 10,
              "triggerAtHour": 21
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "3a4de69d-c1d8-4e83-b3bb-25e6ff1c3cd3",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        400,
        160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ed641ba7-01ec-4baa-bf2e-5cac217a7709",
      "name": "Get token expiration date",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -32,
        0
      ],
      "parameters": {
        "limit": 1,
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "TcHt9QIGMyCs1qIB",
          "cachedResultUrl": "/projects/XqoBcIeUrbWmIJt8/datatables/TcHt9QIGMyCs1qIB",
          "cachedResultName": "Meta credential"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ebfac905-851e-42db-b4d4-5c2a67987b46",
      "name": "Needs renewal?",
      "type": "n8n-nodes-base.if",
      "position": [
        176,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e62d1e04-38f2-454f-9301-6b6b896a9e5a",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ new Date($json.expires_at) <= new Date(Date.now() + 15*24*60*60*1000) }}",
              "rightValue": "={{ 10 }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1da184df-364e-4c52-844a-f368480ad132",
      "name": "Carry ID & Token",
      "type": "n8n-nodes-base.set",
      "position": [
        400,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1d09ed8a-2288-42db-b355-63e9b0354cbb",
              "name": "record_id",
              "type": "number",
              "value": "={{ $json.id }}"
            },
            {
              "id": "25975e2f-4375-41d4-b9cb-97ac0cec134b",
              "name": "current_token",
              "type": "string",
              "value": "={{ $json.token }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "42726ba6-dbab-4cdc-893e-92c299c0fe96",
      "name": "User Exchange",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        672,
        -16
      ],
      "parameters": {
        "url": "https://graph.facebook.com/v20.0/oauth/access_token",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "form-urlencoded",
        "bodyParameters": {
          "parameters": [
            {
              "name": "grant_type",
              "value": "fb_exchange_token"
            },
            {
              "name": "client_id"
            },
            {
              "name": "client_secret"
            },
            {
              "name": "fb_exchange_token",
              "value": "={{$json.current_token}}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "2e570311-fc11-408c-956a-f66a246aa5e1",
      "name": "Compute new expiry",
      "type": "n8n-nodes-base.set",
      "position": [
        960,
        -16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "6be317cc-adac-45eb-a36d-0440c0fbac1c",
              "name": "token",
              "type": "string",
              "value": "={{ $json.access_token }}"
            },
            {
              "id": "5d6562df-c638-4245-b967-c02e2617fab5",
              "name": "expired_at",
              "type": "string",
              "value": "={{ new Date(Date.now() + ($json.expires_in)*1000).toISOString() }}"
            },
            {
              "id": "3268497e-4040-4486-bde1-b65caf5141df",
              "name": "record_id",
              "type": "string",
              "value": "={{ $node[\"Carry ID & Token\"].json.record_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "97cbffa5-4305-42da-bafe-26a5f06df25a",
      "name": "Update Record",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1168,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "token": "={{$json.token}}",
            "expires_at": "={{$json.expired_at}}"
          },
          "schema": [
            {
              "id": "token",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "token",
              "defaultMatch": false
            },
            {
              "id": "expires_at",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "expires_at",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyValue": "={{$json.record_id}}"
            }
          ]
        },
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "TcHt9QIGMyCs1qIB",
          "cachedResultUrl": "/projects/XqoBcIeUrbWmIJt8/datatables/TcHt9QIGMyCs1qIB",
          "cachedResultName": "Meta credencial"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e477c855-2431-4507-a8bb-8f108ab5a973",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        -240
      ],
      "parameters": {
        "width": 288,
        "height": 480,
        "content": "* Right now the cron runs every 10 days to avoid consuming too much n8n credits. Feel free to change it. If you change it change also the logic in the \"Needs renewal?\" node.\n* For now Facebook gives token with 60 days expiration "
      },
      "typeVersion": 1
    },
    {
      "id": "9e8f62b4-187d-43eb-a40b-baa555c01eb6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -240
      ],
      "parameters": {
        "color": 4,
        "width": 256,
        "height": 480,
        "content": "## Data tables\n* This workflow is using the new Data tables feature\n* Create a DataTable called \"Meta credential\" with the following fields:\n** Token - your Access Token (string)\n** expires_at - expiration date of your token (datetime)"
      },
      "typeVersion": 1
    },
    {
      "id": "6afeba73-f1f4-436d-a3a4-811cc6d841de",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 272,
        "height": 496,
        "content": "## Generate new tokens\n* If tokens has less than 15 days before expiring it generates a new one \n* In this node you need to update the following fields: \n** client_id: this is your AppID you got when creating your credential \n** client_secret: this is your AppSecret"
      },
      "typeVersion": 1
    },
    {
      "id": "fef64b9c-a077-4278-9187-db0743ca7692",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 448,
        "height": 496,
        "content": "## Setting new expiration date and updating data table \n* It format the date from unix to datetime \n* It updates the row in the Data table"
      },
      "typeVersion": 1
    },
    {
      "id": "2e41d7ee-aae9-4083-bdd0-4252fc764dd9",
      "name": "When clicking \"Execute workflow\"",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -304,
        80
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "7be243a3-0f7d-4039-990a-613e2a856002",
  "connections": {
    "User Exchange": {
      "main": [
        [
          {
            "node": "Compute new expiry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Needs renewal?": {
      "main": [
        [
          {
            "node": "Carry ID & Token",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Carry ID & Token": {
      "main": [
        [
          {
            "node": "User Exchange",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get token expiration date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compute new expiry": {
      "main": [
        [
          {
            "node": "Update Record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get token expiration date": {
      "main": [
        [
          {
            "node": "Needs renewal?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \"Execute workflow\"": {
      "main": [
        [
          {
            "node": "Get token expiration date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

Meta long-lived user tokens typically expire after ~60 days. If a token expires, any workflows that rely on it start failing. Manual renewal is easy to forget and time consuming. This template monitors the token you store in an n8n Data Table and refreshes it automatically…

Source: https://n8n.io/workflows/9604/ — 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

📺 Full walkthrough video: https://youtu.be/Me4d4BILvHk

Gmail, Data Table, HTTP Request
Social Media

Automatically upload your Instagram videos to YouTube with configurable time gaps between each upload, using n8n Tables for deduplication. Fetches recent Instagram posts via the Meta Graph API and fil

HTTP Request, Data Table, YouTube
Social Media

This workflow automatically discovers trending topics, generates engaging social media content using AI, and publishes posts to X (Twitter) and Facebook via Buffer.

Data Table, Google Gemini, Mcp Client +2
Social Media

This n8n workflow provides automated monitoring of YouTube channels and sends real-time notifications to RocketChat when new videos are published. It supports all YouTube URL formats, uses dual-source

HTTP Request, XML, Rocketchat
Social Media

📘 Multi-Photo Facebook Post (Windows Directory) – How to Use ✅ Requirements To run this automation, make sure you have the following:

Read Write File, Execute Command, Facebook Graph Api +1