{
  "name": "SEO Keyword → Blog + Featured Image → WordPress",
  "nodes": [
    {
      "id": "9e07a9aa-73d4-4109-9dbf-53a4e24de26f",
      "name": "When Keyword Submitted",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        48528,
        17680
      ],
      "parameters": {
        "options": {},
        "formTitle": "Generate an SEO article",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Target keyword",
              "requiredField": true
            },
            {
              "fieldLabel": "Brand ID (optional)"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "77380b0e-bc69-429c-ad4c-3941b17b841b",
      "name": "Write SEO Article",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        48752,
        17680
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are an SEO content writer. Write a complete, publish-ready blog article optimized for the keyword \"{{ $('When Keyword Submitted').item.json['Target keyword'] }}\". Return STRICT JSON only: {\"title\": \"...\", \"body_html\": \"<p>...</p>\", \"summary\": \"one-sentence summary for the featured image\"}. No preamble, no markdown fences."
            }
          ]
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "fa79f947-e26b-4984-b1a0-a9e6d3b40c8c",
      "name": "Parse Article JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        49024,
        17680
      ],
      "parameters": {
        "jsCode": "const raw = $json.message?.content ?? $json.text ?? $json.content ?? '';\nlet a; try { a = JSON.parse(raw); } catch(e) {\n  const m = String(raw).match(/\\{[\\s\\S]*\\}/); a = m ? JSON.parse(m[0]) : { title:'Untitled', body_html:String(raw), summary:'' };\n}\nreturn [{ json: a }];"
      },
      "typeVersion": 2
    },
    {
      "id": "99a2b135-2f3d-4049-814a-d412f9886d45",
      "name": "Post Article to Canvora",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        49312,
        17680
      ],
      "parameters": {
        "url": "https://api.canvora.ai/api/generations",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify(Object.assign({\n  inputType: 'text',\n  inputContent: $('Parse Article JSON').item.json.summary || $('Parse Article JSON').item.json.title,\n  title: 'Blog visuals: ' + $('Parse Article JSON').item.json.title,\n  outputFormats: ['blog_featured', 'og_image']\n}, $('When Keyword Submitted').item.json['Brand ID (optional)'] ? { brandId: $('When Keyword Submitted').item.json['Brand ID (optional)'] } : {})) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "bd2085f2-f7d2-4ba1-b193-912343938393",
      "name": "Wait 30s",
      "type": "n8n-nodes-base.wait",
      "position": [
        49648,
        17680
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "e97e47a1-abd8-447e-ac7f-a6e656a2c4dc",
      "name": "Fetch Generation Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        49872,
        17680
      ],
      "parameters": {
        "url": "=https://api.canvora.ai/api/generations/{{ $('Post Article to Canvora').item.json.generation.id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "35509118-effe-4272-bf9c-0984f825eec9",
      "name": "If Generation Done",
      "type": "n8n-nodes-base.if",
      "position": [
        50080,
        17680
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "t11",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ ['completed','failed','partial','cancelled'].includes($json.generation.status) }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2ea05fd4-32e6-462f-9558-5b31bf2a82c0",
      "name": "If Timed Out",
      "type": "n8n-nodes-base.if",
      "position": [
        50080,
        17888
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "t12",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $runIndex >= 20 }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "7b5c78d7-69d2-4b2e-bc20-45ed4b13b6c5",
      "name": "If Generation Succeeded",
      "type": "n8n-nodes-base.if",
      "position": [
        50432,
        17680
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "t13",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ ['completed','partial'].includes($json.generation.status) }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6d39c73d-154a-4b94-8e08-aa3663664169",
      "name": "Build WordPress Post",
      "type": "n8n-nodes-base.code",
      "position": [
        50640,
        17680
      ],
      "parameters": {
        "jsCode": "const g = $input.first().json.generation;\nconst outs = g.outputs || [];\nconst featured = (outs.find(o => o.format === 'blog_featured') || outs[0] || {}).fileUrl || '';\nconst a = $('Parse Article JSON').item.json;\nconst content = (featured ? `<figure><img src=\"${featured}\" alt=\"${a.title}\"/></figure>\\n` : '') + (a.body_html || '');\nreturn [{ json: { title: a.title, content, featured } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "7a00b066-3170-4eff-bef3-852885758df8",
      "name": "Create WordPress Draft",
      "type": "n8n-nodes-base.wordpress",
      "position": [
        50848,
        17680
      ],
      "parameters": {
        "title": "={{ $json.title }}",
        "additionalFields": {
          "status": "draft",
          "content": "={{ $json.content }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1b3e7c2b-eeda-4ee3-bcd1-cdb0f2d9c16f",
      "name": "Generation Failed (credits auto-refunded)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        50768,
        18096
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "54ccb76b-8311-4d3f-8c2d-c377df93e517",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        47808,
        17408
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 1160,
        "content": "## SEO Keyword → Blog Article + Featured Image → WordPress\n\n### How it works\nSubmit a target keyword through the built-in form. An AI model writes a\ncomplete, SEO-optimized article, then Canvora designs a matching **featured\nimage** and **Open Graph card** – on brand, in your colors and fonts. The\nfinished post is created as a **WordPress draft** with the image embedded,\nready for you to review and publish.\n\n### Setup steps\n- Create a free Canvora account at canvora.ai – free credits, no card – and\n  copy an API key from Integrations → API Keys (available on 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 to the \"Write SEO Article\" node (swap for Claude\n  or Gemini if you prefer).\n- Connect your WordPress site credential.\n- Open the form URL from the trigger node and submit a keyword to test.\n\n### Customization\n- Add `blog_header` or an `instagram_post` to `outputFormats` for a fuller\n  social kit (100+ formats: GET https://api.canvora.ai/api/formats).\n- Pass a `brandId` (GET /api/brands) to lock every visual to your brand kit.\n- Swap the form trigger for a Google Sheets or Airtable row to run a keyword\n  queue on a schedule.\n- Cost: 2 visuals = 20 credits per article.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0fdb4f13-908a-4be3-bae8-be80c599566d",
      "name": "Sticky Note100",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48480,
        17520
      ],
      "parameters": {
        "color": 7,
        "width": 682,
        "height": 358,
        "content": "## Write the SEO article\n\nA form takes a target keyword; an AI model writes a full, SEO-optimized article and returns clean JSON."
      },
      "typeVersion": 1
    },
    {
      "id": "2a8de4a1-f196-4d0b-b905-50daeb4b2407",
      "name": "Sticky Note101",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        49248,
        17440
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 390,
        "content": "## Design the visuals\n\nSends the article to Canvora, which designs a featured image and an Open Graph card — on brand."
      },
      "typeVersion": 1
    },
    {
      "id": "e88e5dac-81fe-4eff-902a-767ac81bc09a",
      "name": "Sticky Note102",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        49568,
        17520
      ],
      "parameters": {
        "color": 7,
        "width": 698,
        "height": 594,
        "content": "## Poll generation status\n\nWaits between checks, fetches the state, and loops until the visuals finish or it times out."
      },
      "typeVersion": 1
    },
    {
      "id": "1dfd6f21-ce1c-4870-a25f-7bc23d819c81",
      "name": "Sticky Note103",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        50368,
        17520
      ],
      "parameters": {
        "color": 7,
        "width": 666,
        "height": 310,
        "content": "## Publish to WordPress\n\nOn success, embeds the featured image and creates a WordPress draft, ready to review and publish."
      },
      "typeVersion": 1
    },
    {
      "id": "279df6d3-89d4-4537-b7e1-5efb3c0d8175",
      "name": "Sticky Note104",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        50720,
        17872
      ],
      "parameters": {
        "color": 7,
        "height": 390,
        "content": "## Handle failure\n\nIf generation fails or times out, credits are refunded automatically."
      },
      "typeVersion": 1
    }
  ],
  "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
          }
        ]
      ]
    },
    "Write SEO Article": {
      "main": [
        [
          {
            "node": "Parse Article JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Generation Done": {
      "main": [
        [
          {
            "node": "If Generation Succeeded",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If Timed Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Article JSON": {
      "main": [
        [
          {
            "node": "Post Article to Canvora",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build WordPress Post": {
      "main": [
        [
          {
            "node": "Create WordPress Draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Keyword Submitted": {
      "main": [
        [
          {
            "node": "Write SEO Article",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Generation Status": {
      "main": [
        [
          {
            "node": "If Generation Done",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Generation Succeeded": {
      "main": [
        [
          {
            "node": "Build WordPress Post",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Generation Failed (credits auto-refunded)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Article to Canvora": {
      "main": [
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "active": false
}
