keyword_cluster — Keyword Research Cluster
| Field | Value |
|---|---|
| Type key | keyword_cluster |
| Label | Keyword Research Cluster |
| Agent queue | keyword-researcher |
| Plan tier | Free+ (starter, growth, professional) |
| Credits/unit | 1 |
| Monthly range | 1 (once per month) |
What it produces
A set of keyword groups for the tenant’s niche — each group contains a named collection of keywords annotated with estimated search volume, keyword difficulty, intent, and category. The raw JSON is stored in Activity.outputPayload; the worker also parses it and writes structured rows to the Keyword, KeywordGroup, and KeywordGroupItem DB tables.
Typical JSON structure (stored in outputPayload):
{
"groups": [
{
"name": "Core Service Keywords",
"purpose": "content",
"keywords": [
{ "keyword": "landscaping services London", "searchVolume": "1K-10K", "difficulty": "medium", "intent": "commercial", "category": "core" },
{ "keyword": "garden design London", "searchVolume": "1K-10K", "difficulty": "medium", "intent": "commercial", "category": "local" },
{ "keyword": "lawn care services near me", "searchVolume": "10K-100K","difficulty": "high", "intent": "transactional", "category": "local" }
]
}
]
}The first keyword in each group is flagged as isPrimary = true in KeywordGroupItem.
Pipeline sequence
keyword-researcher ──→ Deliverable: pending_review
│
[DM approves keyword groups]
[at /seo/keyword-groups in DM portal]
│
content-brief-writer and blog-writer pick up approved cluster dataHITL gate present. The Deliverable moves to pending_review after the worker runs. The DM must approve each KeywordGroup individually in the DM portal before the cluster is considered ready.
Status machine
Status tracked on the parent Activity record only.
| Activity status | Meaning |
|---|---|
pending | Scheduled, waiting |
queued | Submitted to BullMQ |
in_progress | Worker running |
done | Cluster written, outputPayload saved |
failed | Worker error |
The Deliverable moves from generating → pending_review on done. It advances to approved only after the DM approves keyword groups in the DM portal.
HITL gates
DM review required. After the worker runs, each KeywordGroup starts at status = "pending_review". The DM approves groups individually in the DM portal at /seo/keyword-groups. Status flow: pending_review → approved.
Dependencies
None. The keyword researcher uses tenant business context (industry, location, services, competitors) from the client context file and the strategy document.
Depended on by:
content_brief— cluster data (primary keyword, intent, variants) is injected into the brief writer’s context.blog_post— primary keyword from the cluster is referenced in the blog writer’s prompt.
DB records created
| Record | Created by | Notes |
|---|---|---|
DeliverableTemplate | deliverable-planner | 1 cluster per month |
Activity | activity-planner | type = keyword_cluster; runs early in the month before briefs |
Deliverable | keyword-researcher worker | Moves to pending_review on completion (not auto-approved) |
Keyword | keyword-researcher worker | One row per keyword across all groups; source="agent", status="active" |
KeywordGroup | keyword-researcher worker | One row per group; status="pending_review" |
KeywordGroupItem | keyword-researcher worker | Join table; first keyword in each group has isPrimary=true |
Raw JSON is also written to Activity.outputPayload.
Key rules
- Only 1 keyword cluster is planned per month — it provides context for all blog posts in that period.
- The cluster activity should run early in the monthly cycle so that content briefs and blog posts can use the research.
- There is no client-visible deliverable card for the cluster — it is a pipeline input, not a client deliverable.