This workflow corresponds to n8n.io template #17482 — we link there as the canonical source.
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 →
{
"id": "IoPwQybp6rbdWwVV",
"name": "Publish Facebook Reels from a Video URL",
"tags": [],
"nodes": [
{
"id": "0d23c905-fb94-4b9e-ae40-507eb484793e",
"name": "Receive Reel Request",
"type": "n8n-nodes-base.webhook",
"position": [
0,
0
],
"parameters": {
"path": "facebook-reel-publish",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "43c18308-b84c-45f1-8218-23b131b03238",
"name": "Set Facebook Page ID",
"type": "n8n-nodes-base.set",
"position": [
224,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "page-id-1",
"name": "page_id",
"type": "string",
"value": "YOUR_FACEBOOK_PAGE_ID"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f978ac0a-c43c-4ea8-b44d-6b43acff4729",
"name": "Start Upload Session",
"type": "n8n-nodes-base.httpRequest",
"position": [
448,
0
],
"parameters": {
"url": "=https://graph.facebook.com/v25.0/{{ $('Set Facebook Page ID').first().json.page_id }}/video_reels",
"method": "POST",
"options": {},
"jsonBody": "={ \"upload_phase\": \"start\" }",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "645c5f70-83b1-408f-979e-db17ba41f534",
"name": "Upload Video from URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
672,
0
],
"parameters": {
"url": "=https://rupload.facebook.com/video-upload/v25.0/{{ $json.video_id }}",
"method": "POST",
"options": {
"timeout": 120000
},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "file_url",
"value": "={{ $('Receive Reel Request').first().json.body.video_url }}"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "3d5bcd9b-8459-428f-b764-db69556c3916",
"name": "Wait for Processing",
"type": "n8n-nodes-base.wait",
"position": [
880,
0
],
"parameters": {
"amount": 8
},
"typeVersion": 1.1
},
{
"id": "1186f848-8e2c-4fee-9c1c-dc7333951228",
"name": "Finish Upload (Draft, Schedule or Publish)",
"type": "n8n-nodes-base.httpRequest",
"position": [
1104,
0
],
"parameters": {
"url": "=https://graph.facebook.com/v25.0/{{ $('Set Facebook Page ID').first().json.page_id }}/video_reels",
"method": "POST",
"options": {
"timeout": 60000
},
"jsonBody": "={{ JSON.stringify(Object.assign({\n upload_phase: 'finish',\n video_id: $('Start Upload Session').first().json.video_id,\n video_state: $('Receive Reel Request').first().json.body.video_state || 'DRAFT',\n description: $('Receive Reel Request').first().json.body.caption || ''\n}, $('Receive Reel Request').first().json.body.scheduled_publish_time ? { scheduled_publish_time: $('Receive Reel Request').first().json.body.scheduled_publish_time } : {})) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "20ce9581-1755-436c-8402-322d6244ebee",
"name": "Build Reel Link",
"type": "n8n-nodes-base.code",
"position": [
1328,
0
],
"parameters": {
"jsCode": "\n// Build the response: the Reel link for the caller.\n// Errors from the finish call pass through as an error field.\nconst first = $input.first().json;\nconst vid = $('Start Upload Session').first().json.video_id;\nreturn [{ json: { video_id: vid, url: 'https://www.facebook.com/reel/' + vid, finish: first } }];\n"
},
"typeVersion": 2
},
{
"id": "f04999f8-9d13-4359-a14b-9f58703e828e",
"name": "Respond with Reel Link",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1552,
0
],
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "61676334-5f0a-442a-81a0-6812e169d2d0",
"name": "Note -760x-280",
"type": "n8n-nodes-base.stickyNote",
"position": [
-560,
-384
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Publish Facebook Reels from a video URL\n\n**How it works**\n- A webhook receives a JSON request with `video_url`, `caption` and an optional `video_state` (`DRAFT`, `SCHEDULED` or `PUBLISHED`, default `DRAFT`) plus `scheduled_publish_time` (unix timestamp, only for `SCHEDULED`).\n- The workflow runs Facebook's official three-phase Reel upload: it starts an upload session, lets Facebook pull the video directly from your URL (no file handling in n8n), then finishes the upload with your caption and publishing mode.\n- It responds with the new Reel's video id and link.\n\n**Setup steps**\n1. In Meta's developer portal, create an app connected to your Facebook Page and get a **Page access token** with `pages_show_list`, `pages_read_engagement` and `pages_manage_posts`. Page tokens of this type do not expire.\n2. Create an **HTTP Header Auth** credential: name `Authorization`, value `Bearer <your Page access token>`, and attach it to the three Facebook nodes.\n3. Enter your **Facebook Page ID** in the \"Set Facebook Page ID\" node.\n4. Send a POST request to the webhook, e.g. `{\"video_url\": \"https://example.com/my-reel.mp4\", \"caption\": \"Hello!\", \"video_state\": \"DRAFT\"}`.\n\nThe video must be publicly reachable, vertical (9:16) and max 90 seconds. Drafts appear in Meta Business Suite for review before publishing.\n\n**Why HTTP Request instead of the Facebook Graph API node?** The Reels upload phase requires the `rupload.facebook.com` host and a custom `file_url` header. The native node supports neither, so this template uses HTTP Request throughout: one credential covers all three calls."
},
"typeVersion": 1
},
{
"id": "287f5719-f954-4957-ad0c-6e7661e90c29",
"name": "Note -40x-140",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-144
],
"parameters": {
"color": 7,
"width": 500,
"height": 360,
"content": "## 1. Receive request\nThe webhook takes `video_url`, `caption` and the publishing mode from your app or another workflow. Your Page ID is set once here."
},
"typeVersion": 1
},
{
"id": "e605e795-3ff4-42e8-a982-fee3e4b96ef2",
"name": "Note 480x-140",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
-144
],
"parameters": {
"color": 7,
"width": 840,
"height": 360,
"content": "## 2. Three-phase upload\nStart an upload session, let Facebook pull the video from your URL, then finish with caption and `DRAFT` / `SCHEDULED` / `PUBLISHED`."
},
"typeVersion": 1
},
{
"id": "23dbaf6f-3500-4eb1-895d-a1a2e047ead4",
"name": "Note 1340x-140",
"type": "n8n-nodes-base.stickyNote",
"position": [
1344,
-144
],
"parameters": {
"color": 7,
"width": 420,
"height": 360,
"content": "## 3. Respond\nReturns the video id and the Reel link to the caller."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "794c2631-e8e6-46ac-8975-19636f3464ba",
"nodeGroups": [],
"connections": {
"Build Reel Link": {
"main": [
[
{
"node": "Respond with Reel Link",
"type": "main",
"index": 0
}
]
]
},
"Wait for Processing": {
"main": [
[
{
"node": "Finish Upload (Draft, Schedule or Publish)",
"type": "main",
"index": 0
}
]
]
},
"Receive Reel Request": {
"main": [
[
{
"node": "Set Facebook Page ID",
"type": "main",
"index": 0
}
]
]
},
"Set Facebook Page ID": {
"main": [
[
{
"node": "Start Upload Session",
"type": "main",
"index": 0
}
]
]
},
"Start Upload Session": {
"main": [
[
{
"node": "Upload Video from URL",
"type": "main",
"index": 0
}
]
]
},
"Upload Video from URL": {
"main": [
[
{
"node": "Wait for Processing",
"type": "main",
"index": 0
}
]
]
},
"Finish Upload (Draft, Schedule or Publish)": {
"main": [
[
{
"node": "Build Reel Link",
"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.
httpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow exposes a webhook that takes a public video URL and caption, uploads the video to a Facebook Page as a Reel via the Facebook Graph API’s three-phase upload, and responds with the created Reel’s video ID and link. Receives a POST webhook request containing , , and…
Source: https://n8n.io/workflows/17482/ — 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.
generación_publicaciones (workflow 3) webhook all platforms decrypt publicar git. Uses dataTable, linkedIn, httpRequest. Webhook trigger; 50 nodes.
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
Automate your entire Instagram carousel publishing pipeline from a single webhook call. This workflow receives a product collection payload, loops through each slide image, uploads every asset via Upl
Twitter MCP - Complete Workflow. Uses start, httpRequest. Webhook trigger; 18 nodes.
This workflow leverages n8n to automate LinkedIn content creation from start to finish. Upload an image and quote through a web form, and get a professionally designed post with AI-generated captions,