This workflow corresponds to n8n.io template #17746 — we link there as the canonical source.
This workflow follows the HTTP Request → LinkedIn 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 →
{
"id": "NToMW6sFTYKqdLrT",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI Post \u2192 Canvora Visual \u2192 LinkedIn",
"tags": [],
"nodes": [
{
"id": "1d159558-7769-4012-aa11-4ed3ab6f85bb",
"name": "Every Tue & Thu 9am",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
29472,
11280
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 2,4"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "1513afaa-c561-4a80-8b27-61b0dcf26605",
"name": "Set Post Parameters",
"type": "n8n-nodes-base.set",
"position": [
29696,
11280
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "p1",
"name": "topic",
"type": "string",
"value": "practical automation wins for small teams"
},
{
"id": "p2",
"name": "brandId",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.4
},
{
"id": "4cccb730-d73e-4105-a8c4-3136bffe4719",
"name": "Write LinkedIn Post",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
29904,
11280
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {},
"messages": {
"values": [
{
"content": "=You are a LinkedIn ghostwriter. Write ONE specific, non-generic LinkedIn post (120-180 words, a concrete angle, a short hook line, no hashtags spam) about: {{ $('Set Post Parameters').item.json.topic }}. Return ONLY the post text."
}
]
}
},
"typeVersion": 1.8
},
{
"id": "224bc9c2-e423-4a15-bc5f-1b7b28962db5",
"name": "Extract Post Text",
"type": "n8n-nodes-base.code",
"position": [
30176,
11280
],
"parameters": {
"jsCode": "const t = $json.message?.content ?? $json.text ?? $json.content ?? '';\nreturn [{ json: { postText: String(t).trim() } }];"
},
"typeVersion": 2
},
{
"id": "d6f80700-20b8-4e77-a7c4-c0990f14527e",
"name": "Post Concept to Canvora",
"type": "n8n-nodes-base.httpRequest",
"position": [
30464,
11280
],
"parameters": {
"url": "https://api.canvora.ai/api/generations",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify(Object.assign({\n inputType: 'idea',\n inputContent: $('Extract Post Text').item.json.postText,\n title: 'LinkedIn visual',\n outputFormats: ['linkedin_post']\n}, $('Set Post Parameters').item.json.brandId ? { brandId: $('Set Post Parameters').item.json.brandId } : {})) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "73c3e0d8-0d17-499d-90b7-0327293ccd89",
"name": "Wait 30s",
"type": "n8n-nodes-base.wait",
"position": [
30816,
11280
],
"parameters": {
"amount": 30
},
"typeVersion": 1.1
},
{
"id": "ddd94b3f-9583-40b1-8ef6-b95af8ad38bc",
"name": "Fetch Generation Status",
"type": "n8n-nodes-base.httpRequest",
"position": [
31024,
11280
],
"parameters": {
"url": "=https://api.canvora.ai/api/generations/{{ $('Post Concept to Canvora').item.json.generation.id }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "7d0161d4-cd9a-4943-9099-9500e015dcfe",
"name": "If Generation Done",
"type": "n8n-nodes-base.if",
"position": [
31232,
11280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t31",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ ['completed','failed','partial','cancelled'].includes($json.generation.status) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "fa629c69-90a7-4463-a4b6-841fbea413f2",
"name": "If Timed Out",
"type": "n8n-nodes-base.if",
"position": [
31232,
11488
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t32",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $runIndex >= 20 }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "e4b6c8ea-d035-4a44-b7fe-d110d4c6d2a6",
"name": "If Generation Succeeded",
"type": "n8n-nodes-base.if",
"position": [
31584,
11280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "t33",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ ['completed','partial'].includes($json.generation.status) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "cebb7708-5fa2-4e88-832e-fb9af60af051",
"name": "Pick Visual URL",
"type": "n8n-nodes-base.code",
"position": [
31792,
11280
],
"parameters": {
"jsCode": "const g = $input.first().json.generation;\nconst fileUrl = (g.outputs && g.outputs[0] && g.outputs[0].fileUrl) || '';\nreturn [{ json: { fileUrl, postText: $('Extract Post Text').item.json.postText } }];"
},
"typeVersion": 2
},
{
"id": "b31c08d8-2a3f-4a88-a33e-b0396628eecb",
"name": "Download Visual",
"type": "n8n-nodes-base.httpRequest",
"position": [
32000,
11280
],
"parameters": {
"url": "={{ $json.fileUrl }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "2a354319-edf8-421d-9be4-84a06a74e331",
"name": "Publish to LinkedIn",
"type": "n8n-nodes-base.linkedIn",
"position": [
32208,
11280
],
"parameters": {
"text": "={{ $('Pick Visual URL').item.json.postText }}",
"additionalFields": {},
"shareMediaCategory": "IMAGE"
},
"typeVersion": 1
},
{
"id": "dfcc930a-986e-4e79-a631-1b2f9989c100",
"name": "Generation Failed (credits auto-refunded)",
"type": "n8n-nodes-base.noOp",
"position": [
31968,
11712
],
"parameters": {},
"typeVersion": 1
},
{
"id": "ada5238b-46a0-4044-8c07-73a772884308",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
28752,
11008
],
"parameters": {
"color": 7,
"width": 560,
"height": 1108,
"content": "## AI Writes the Post, Canvora Designs It \u2192 Publish to LinkedIn\n\n### How it works\nOn a schedule, an AI model writes one specific LinkedIn post about your topic.\nCanvora turns that concept into a finished, on-brand **LinkedIn visual**, and\nthe workflow **publishes the post + image straight to LinkedIn** \u2014 no manual\nstep. Because Canvora returns a hosted image URL, the visual is downloaded and\nattached natively (no separate S3/Cloudinary upload needed).\n\n### Setup steps\n- Create a free Canvora account at canvora.ai \u2014 free credits, no card \u2014 and\n copy an API key from Integrations \u2192 API Keys (all plans).\n- In each Canvora HTTP Request node, add a **Header Auth** credential:\n name `X-API-Key`, value your `vd_...` key.\n- Add your OpenAI credential (or swap the node for Claude / Gemini).\n- Connect your LinkedIn credential (personal or organization).\n- Edit \"Set Post Parameters\" \u2014 set your topic and optional `brandId`.\n\n### Customization\n- Change the cron in the trigger to your posting cadence.\n- Swap `linkedin_post` for `linkedin_carousel` to publish a multi-slide post\n (100+ formats: GET https://api.canvora.ai/api/formats).\n- Pass a `brandId` (GET /api/brands) to lock the visual to your brand kit.\n- Prefer human review? Change the LinkedIn node to \"create draft\" or route to\n a Gmail draft first.\n- Cost: 1 visual = 10 credits per post.\n"
},
"typeVersion": 1
},
{
"id": "01a2bcdd-9b99-4cad-a7d6-376dda824f23",
"name": "Sticky Note100",
"type": "n8n-nodes-base.stickyNote",
"position": [
29408,
11120
],
"parameters": {
"color": 7,
"width": 908,
"height": 358,
"content": "## Write the post\n\nOn a schedule, set your topic and an AI model writes one specific LinkedIn post; the text is extracted for Canvora."
},
"typeVersion": 1
},
{
"id": "eb3c1faa-84c2-4928-b228-7d9f99c103ea",
"name": "Sticky Note101",
"type": "n8n-nodes-base.stickyNote",
"position": [
30400,
11040
],
"parameters": {
"color": 7,
"width": 256,
"height": 390,
"content": "## Design the visual\n\nSends the post concept to Canvora, which designs an on-brand LinkedIn visual."
},
"typeVersion": 1
},
{
"id": "e0cbdc00-c3ca-4d90-9e10-c51fde1af01d",
"name": "Sticky Note102",
"type": "n8n-nodes-base.stickyNote",
"position": [
30768,
11120
],
"parameters": {
"color": 7,
"width": 650,
"height": 530,
"content": "## Poll generation status\n\nWaits between checks, fetches the state, and loops until the visual finishes or it times out."
},
"typeVersion": 1
},
{
"id": "55011942-ad57-4ccb-88f6-4aecae5365b1",
"name": "Sticky Note103",
"type": "n8n-nodes-base.stickyNote",
"position": [
31504,
11120
],
"parameters": {
"color": 7,
"width": 908,
"height": 310,
"content": "## Publish to LinkedIn\n\nOn success, downloads the hosted visual and publishes the post + image straight to LinkedIn."
},
"typeVersion": 1
},
{
"id": "835a92fd-c6a8-4497-bf84-2f8b92f165d2",
"name": "Sticky Note104",
"type": "n8n-nodes-base.stickyNote",
"position": [
31904,
11488
],
"parameters": {
"color": 7,
"width": 256,
"height": 390,
"content": "## Handle failure\n\nIf generation fails or times out, credits are refunded automatically."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "e7f2528c-6006-427c-a661-91a4ce958533",
"nodeGroups": [],
"connections": {
"Wait 30s": {
"main": [
[
{
"node": "Fetch Generation Status",
"type": "main",
"index": 0
}
]
]
},
"If Timed Out": {
"main": [
[
{
"node": "Generation Failed (credits auto-refunded)",
"type": "main",
"index": 0
}
],
[
{
"node": "Wait 30s",
"type": "main",
"index": 0
}
]
]
},
"Download Visual": {
"main": [
[
{
"node": "Publish to LinkedIn",
"type": "main",
"index": 0
}
]
]
},
"Pick Visual URL": {
"main": [
[
{
"node": "Download Visual",
"type": "main",
"index": 0
}
]
]
},
"Extract Post Text": {
"main": [
[
{
"node": "Post Concept to Canvora",
"type": "main",
"index": 0
}
]
]
},
"If Generation Done": {
"main": [
[
{
"node": "If Generation Succeeded",
"type": "main",
"index": 0
}
],
[
{
"node": "If Timed Out",
"type": "main",
"index": 0
}
]
]
},
"Every Tue & Thu 9am": {
"main": [
[
{
"node": "Set Post Parameters",
"type": "main",
"index": 0
}
]
]
},
"Set Post Parameters": {
"main": [
[
{
"node": "Write LinkedIn Post",
"type": "main",
"index": 0
}
]
]
},
"Write LinkedIn Post": {
"main": [
[
{
"node": "Extract Post Text",
"type": "main",
"index": 0
}
]
]
},
"Fetch Generation Status": {
"main": [
[
{
"node": "If Generation Done",
"type": "main",
"index": 0
}
]
]
},
"If Generation Succeeded": {
"main": [
[
{
"node": "Pick Visual URL",
"type": "main",
"index": 0
}
],
[
{
"node": "Generation Failed (credits auto-refunded)",
"type": "main",
"index": 0
}
]
]
},
"Post Concept to Canvora": {
"main": [
[
{
"node": "Wait 30s",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs on a Tue/Thu schedule to generate a LinkedIn post with OpenAI, create a matching LinkedIn-ready image via the Canvora API, and then publish the post text plus the downloaded image to LinkedIn. Runs every Tuesday and Thursday at 9:00 AM. Sets the post topic…
Source: https://n8n.io/workflows/17746/ — 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.
Daily trigger scans your Notion database for unpublished blog ideas AI generates complete blog posts + engaging LinkedIn content using OpenAI (Blog Posting is not implemented yet) Creates custom image
Automate LinkedIn Posts with AI. Uses scheduleTrigger, stickyNote, notion, linkedIn. Scheduled trigger; 11 nodes.
This template is based on the following template. Thank you for the groundwork, Matheus. Store your snippets of text in a Notion table. Each snippet should have an image associated with it (copy + pas
AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets
Overview This is a production-grade, fully automated stock analysis system built entirely in n8n. It combines institutional-level financial analysis, dual AI model consensus, and a self-improving back