{ "kind": "open-flow-workflow", "version": 1, "name": "SEO Seed Keywords", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_00bd6a1573362bed": { "name": "Ideal customer profile", "kind": "start", "inputDefs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "product" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "pain_points" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "goals" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "current_solutions" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "expertise_level" } ] }, "n_b4ee5837ce51fd21": { "inputs": { "product": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00bd6a1573362bed", "output": "product" } ] }, "pain_points": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00bd6a1573362bed", "output": "pain_points" } ] }, "goals": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00bd6a1573362bed", "output": "goals" } ] }, "current_solutions": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00bd6a1573362bed", "output": "current_solutions" } ] }, "expertise_level": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_00bd6a1573362bed", "output": "expertise_level" } ] } }, "name": "Prepare complete profile", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "product" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "pain_points" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "goals" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "current_solutions" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "expertise_level" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "icp" } ], "name": "Prepare complete profile", "moduleId": "n_3687b3846af5e18f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_95d5ec1bcbe63045": { "inputs": { "icp": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b4ee5837ce51fd21", "output": "icp" } ] } }, "name": "Generate seed keywords", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "items": { "type": "object" }, "type": "array" }, "nullable": true, "handle": "messages", "value": null }, { "jsonSchema": { "items": { "type": "object" }, "minItems": 1, "type": "array" }, "nullable": false, "handle": "template", "value": [ { "role": "system", "content": "You are an expert SEO strategist tasked with generating 15–20 head search terms (seed keywords) for a B2B SaaS company. Create keywords relevant to the ideal customer profile." }, { "role": "user", "content": "Analyze the complete ideal customer profile below. Generate 15–20 relevant seed keywords reflecting customer needs, challenges, goals, and search behavior. Use head terms broad enough for an SEO foundation and specific enough to reach this customer. Include product, problem, solution, industry, technology, and integration topics when relevant. Cover awareness, consideration, and decision stages, with informational, navigational, commercial, and transactional intents. Suggest a mix of competitive and less competitive terms, and consider emerging industry needs when relevant. Avoid overly generic terms. Consider industry terminology and location only when supported by the profile. Use lowercase without punctuation and trim surrounding whitespace.\n\nIdeal customer profile:\n{{icp}}\n\nReturn only JSON with this structure: {\"answer\":[\"first keyword\",\"second keyword\"]}. Include 15–20 strings and no analysis text." } ] }, { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "model", "value": { "model": "claude-sonnet-4-6", "max_tokens": 4096 } }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "icp" } ], "outputs": [ { "description": "Generated response.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Generate seed keywords", "executor": { "kind": "llm", "mode": "chat" } } }, "n_2b2b5e4c0a487e20": { "inputs": { "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_95d5ec1bcbe63045", "output": "output" } ] } }, "name": "Validate keyword list", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "text" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1 }, "minItems": 15, "maxItems": 20 }, "nullable": false, "handle": "keywords" } ], "name": "Validate keyword list", "moduleId": "n_e9f90b38244e8ba2", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_5c560fc89784e5d0": { "name": "SEO keyword ideas", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1 }, "minItems": 15, "maxItems": 20 }, "nullable": false, "handle": "keywords" } ], "outputMappings": { "keywords": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2b2b5e4c0a487e20", "output": "keywords" } ] } } } }, "edges": [ { "source": "n_00bd6a1573362bed", "target": "n_b4ee5837ce51fd21" }, { "source": "n_b4ee5837ce51fd21", "target": "n_95d5ec1bcbe63045" }, { "source": "n_95d5ec1bcbe63045", "target": "n_2b2b5e4c0a487e20" }, { "source": "n_2b2b5e4c0a487e20", "target": "n_5c560fc89784e5d0" } ] } }, "modules": { "n_3687b3846af5e18f": { "name": "Prepare complete profile", "imports": [], "source": "export default function prepareProfile(inputs) {\n const profile = {};\n for (const name of ['product', 'pain_points', 'goals', 'current_solutions', 'expertise_level']) {\n if (typeof inputs[name] !== 'string' || !inputs[name].trim()) throw new Error('Provide the ideal customer profile field: ' + name);\n profile[name] = inputs[name].trim();\n }\n return { icp: JSON.stringify(profile, null, 2) };\n}\n" }, "n_e9f90b38244e8ba2": { "name": "Validate keyword list", "imports": [], "source": "export default function readKeywords({ text }) {\n let parsed;\n try { parsed = JSON.parse(text); } catch { throw new Error('The model did not return keyword JSON.'); }\n if (!Array.isArray(parsed?.answer) || parsed.answer.length < 15 || parsed.answer.length > 20 || parsed.answer.some((keyword) => typeof keyword !== 'string' || !keyword.trim())) throw new Error('Expected 15–20 nonempty seed keywords in answer.');\n return { keywords: parsed.answer.map((keyword) => keyword.trim().toLowerCase()) };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }