{ "id": "TApiWf50AvailCheck01", "name": "Transcript Availability Checker (TranscriptAPI)", "nodes": [ { "parameters": {}, "id": "50505050-5050-4050-8050-505050505001", "name": "Start", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ -100, 0 ] }, { "parameters": { "jsCode": "// Paste a SMALL sample of video URLs/IDs to check (start small).\nconst videoUrls = ['REPLACE_WITH_VIDEO_URL_OR_ID_1', 'REPLACE_WITH_VIDEO_URL_OR_ID_2'];\nreturn videoUrls.map((u) => ({ json: { videoUrl: u } }));" }, "id": "50505050-5050-4050-8050-505050505002", "name": "Set Video List", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 120, 0 ] }, { "parameters": { "url": "https://transcriptapi.com/api/v2/youtube/transcript", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "video_url", "value": "={{ $json.videoUrl }}" }, { "name": "format", "value": "json" } ] }, "options": { "batching": { "batch": { "batchSize": 5, "batchInterval": 1000 } } } }, "id": "50505050-5050-4050-8050-505050505003", "name": "Get Transcript (TranscriptAPI)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 340, 0 ], "credentials": { "httpHeaderAuth": { "id": "REPLACE_TRANSCRIPTAPI_CRED_ID", "name": "TranscriptAPI - Authorization Bearer" } }, "onError": "continueRegularOutput", "retryOnFail": false }, { "parameters": { "jsCode": "// One availability/status row per video. Credit-safe: failed/4xx/5xx/429 cost 0 credits;\n// retry recommendation avoids re-running known-permanent failures (no_captions/invalid_id).\nconst out = [];\nfor (const item of $input.all()) {\n const d = item.json || {};\n if (Array.isArray(d.transcript) && d.transcript.length > 0) {\n out.push({ json: { videoId: d.video_id || null, status: 'available', errorReason: null, httpCode: 200, retryRecommendation: 'none', dedupeKey: d.video_id || null } });\n } else {\n const err = d.error || {};\n const code = err.httpCode || err.code || d.statusCode || null;\n let reason = 'unknown', retry = 'maybe';\n if (code == 404) { reason = 'no_captions'; retry = 'no'; }\n else if (code == 422) { reason = 'invalid_id'; retry = 'no'; }\n else if (code == 429) { reason = 'rate_limited_or_no_credits'; retry = 'later'; }\n else if (code && String(code).charAt(0) === '5') { reason = 'server_error'; retry = 'later'; }\n out.push({ json: { videoId: d.video_id || null, status: 'unavailable', errorReason: reason, httpCode: code, retryRecommendation: retry, dedupeKey: d.video_id || null } });\n }\n}\nreturn out;" }, "id": "50505050-5050-4050-8050-505050505004", "name": "Classify Availability", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 560, 0 ] } ], "connections": { "Start": { "main": [ [ { "node": "Set Video List", "type": "main", "index": 0 } ] ] }, "Set Video List": { "main": [ [ { "node": "Get Transcript (TranscriptAPI)", "type": "main", "index": 0 } ] ] }, "Get Transcript (TranscriptAPI)": { "main": [ [ { "node": "Classify Availability", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1" }, "pinData": {} }