{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Long Video to Short Clips \u2014 Opus Clip + Airtable + Cloudinary + Buffer",
  "tags": [],
  "nodes": [
    {
      "id": "a1b0a7b8-377b-429c-817b-a0f4f43f93a7",
      "name": "Weekly Content Creation",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Runs once a week and starts the clipping pipeline. Change day and hour here.",
      "position": [
        624,
        224
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1.3
    },
    {
      "id": "17b90d91-49ae-4dee-9e5e-63b95fb9ac2d",
      "name": "Send to Opus",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Creates a clip project at Opus Clip. IMPORTANT: replace the webhook url in the JSON body with the production URL of the 'Wait for Opus' node. Edit brandTemplateId and clipDurations to change the look and length of the clips.",
      "position": [
        1312,
        336
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 4.4
    },
    {
      "id": "74b6fdc4-817c-48b1-a75d-ff8d7e479ad3",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "notes": "Turns the API's data array into one item per clip.",
      "position": [
        1520,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "77455f98-58a9-4fab-8112-831695befef9",
      "name": "Get Clips",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Lists the finished clips. The project id is taken straight from the Opus callback, so nothing needs to be filled in here. Uses the same Header Auth credential as 'Send to Opus'.",
      "position": [
        1296,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 4.4
    },
    {
      "id": "bc9eec78-4a04-4211-8eec-51a1a19e29f6",
      "name": "Limit",
      "type": "n8n-nodes-base.limit",
      "notes": "Keeps a maximum of 10 clips per video. Lower this if one video should not flood your posting queue.",
      "position": [
        1744,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "97b476e5-3570-4da4-974d-eeb53b8c5bde",
      "name": "Download Clips",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Downloads the rendered clip as a binary file.",
      "position": [
        2416,
        1024
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 4.4
    },
    {
      "id": "85dee5cd-38ac-4f8b-a441-94f5b44900a6",
      "name": "Search Todo",
      "type": "n8n-nodes-base.airtable",
      "notes": "Fetches up to 2 rows from the Concepts table where Status = 'Todo', oldest ID first. Raise the limit to clip more videos per run.",
      "position": [
        864,
        336
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "2b4a0531-87bb-4bb2-b8b7-c93fcfaab433",
      "name": "Update Status Processed",
      "type": "n8n-nodes-base.airtable",
      "notes": "Immediately flips the row to 'Processed' so the same video is never sent to Opus twice, even if the run is repeated.",
      "position": [
        1088,
        336
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "49da4901-872a-4789-aaec-9cc821ea2cd4",
      "name": "Get All Ready",
      "type": "n8n-nodes-base.airtable",
      "notes": "Fetches every Content row with status 'Ready to Post'. These are the clips still waiting to be published.",
      "position": [
        864,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "41e9e1fc-504a-4ac4-aefe-671e316456e1",
      "name": "Sort Random",
      "type": "n8n-nodes-base.sort",
      "notes": "Shuffles the queue so clips are not always published in the order they were created.",
      "position": [
        1088,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "41ccc2a2-b4be-4baf-b9cb-3bf139e0e875",
      "name": "Pick First",
      "type": "n8n-nodes-base.limit",
      "notes": "Keeps one clip. That single clip is what gets posted in this slot.",
      "position": [
        1312,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "26c92290-34ae-4a59-9d42-db0061fd694a",
      "name": "Add to Content",
      "type": "n8n-nodes-base.airtable",
      "notes": "Creates a row in the Content table with the title, the public video URL and status 'Ready to Post'.",
      "position": [
        2864,
        1024
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "fd41a689-4b40-456a-b744-9f025d6c0743",
      "name": "Post Reel",
      "type": "@bufferapp/n8n-nodes-buffer.buffer",
      "notes": "Publishes the clip as an Instagram Reel through Buffer. Fill in your own organization and channel ID.",
      "position": [
        1536,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "9be8132f-8e1e-4c18-95fa-1587f065994b",
      "name": "Wait for Opus",
      "type": "n8n-nodes-base.webhook",
      "notes": "Opus calls this webhook when rendering is finished. Copy its Production URL and paste it into the JSON body of 'Send to Opus'.",
      "position": [
        624,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.1
    },
    {
      "id": "13664b5b-9d30-4b91-ad31-e4fd41ba3577",
      "name": "Respond to Opus",
      "type": "n8n-nodes-base.respondToWebhook",
      "notes": "Answers Opus with a 200 straight away, so the callback does not time out while the rest of the workflow runs.",
      "position": [
        848,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1.5
    },
    {
      "id": "11fac70c-f567-4a09-ac7e-8fed54189833",
      "name": "Update Status Posted",
      "type": "n8n-nodes-base.airtable",
      "notes": "Sets the row to 'Posted' so the same clip is never published twice.",
      "position": [
        1984,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "52377902-3677-47a9-80a4-5887dacf3981",
      "name": "Post TikTok",
      "type": "@bufferapp/n8n-nodes-buffer.buffer",
      "notes": "Publishes the same clip to TikTok through Buffer. Delete this node if you only want Instagram.",
      "position": [
        1760,
        1504
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "0863035b-d405-4e4b-b9e5-1474a9a57283",
      "name": "Cron 3PM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "First posting slot of the day. Change the hour here.",
      "position": [
        624,
        1424
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1.3
    },
    {
      "id": "f0be9b3c-c6c1-4ea8-a22d-934897def67f",
      "name": "Cron 8PM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Second posting slot of the day. Delete this node if once a day is enough.",
      "position": [
        624,
        1616
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1.3
    },
    {
      "id": "50325e9a-e077-4164-b942-2857f2856f2e",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "notes": "Processes the clips one by one. Output 'done' ends the run, output 'loop' handles the next clip.",
      "position": [
        2192,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 3
    },
    {
      "id": "d87bc134-ce20-4932-a33d-8ba6087b3c33",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "notes": "End of the loop. Add a Slack or email node here if you want a notification when all clips are in.",
      "position": [
        2416,
        832
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "d843b18f-15dc-486f-a17f-e4d4ab5b070e",
      "name": "Manual Creation",
      "type": "n8n-nodes-base.manualTrigger",
      "notes": "Click this to process a video immediately instead of waiting for the weekly run.",
      "position": [
        624,
        432
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1
    },
    {
      "id": "dc57a4c6-45e9-4fbf-bde3-fb42be4f10ae",
      "name": "Upload to Cloudinary",
      "type": "n8n-nodes-cloudinary.cloudinary",
      "notes": "Social APIs need a public URL, not a file. Cloudinary hosts the video and returns that URL. Any public file host works here.",
      "position": [
        2640,
        1024
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2
    },
    {
      "id": "21b5fc84-7511-431f-8021-7ac787f61565",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "notes": "Waits one hour before fetching the clips. Opus reports 'done' before every export file is actually available.",
      "position": [
        1072,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 1.1
    },
    {
      "id": "7628f51e-c7c7-42d1-ab5e-e8c67e0e94a6",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "notes": "Drops clips that have no export URL yet, so the download step cannot fail on an empty file.",
      "position": [
        1968,
        912
      ],
      "parameters": {},
      "notesInFlow": false,
      "typeVersion": 2.3
    },
    {
      "id": "9c61fe1a-a3e4-4e87-b717-e3c1f818ec4b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        0
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "0b7bdd9b-2a5a-49d1-a593-89536aa1fc67",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        688
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "4f99d7e9-cfc4-4e09-871d-48e8e66a98a2",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        1280
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "77a1b74f-2fbb-4daa-92b5-1458dd45a53d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        912
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "225a5e1a-4a50-40be-8d8f-4ddaf20733b7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "content": ""
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Get Clips",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cron 3PM": {
      "main": [
        [
          {
            "node": "Get All Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cron 8PM": {
      "main": [
        [
          {
            "node": "Get All Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Clips": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Reel": {
      "main": [
        [
          {
            "node": "Post TikTok",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick First": {
      "main": [
        [
          {
            "node": "Post Reel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post TikTok": {
      "main": [
        [
          {
            "node": "Update Status Posted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Todo": {
      "main": [
        [
          {
            "node": "Update Status Processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort Random": {
      "main": [
        [
          {
            "node": "Pick First",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Ready": {
      "main": [
        [
          {
            "node": "Sort Random",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Opus": {
      "main": [
        [
          {
            "node": "Respond to Opus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to Content": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Clips": {
      "main": [
        [
          {
            "node": "Upload to Cloudinary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Download Clips",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Creation": {
      "main": [
        [
          {
            "node": "Search Todo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond to Opus": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Cloudinary": {
      "main": [
        [
          {
            "node": "Add to Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Status Processed": {
      "main": [
        [
          {
            "node": "Send to Opus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Content Creation": {
      "main": [
        [
          {
            "node": "Search Todo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}