CitationBenchTalk to Sales
API referenceResearch

Research · ICP API — Generate & Manage Ideal Customer Profile Segments

Generate, edit, and persist Ideal Customer Profile segments from a domain or seed text — heavyweight context that drives keyword labeling, content angles, outreach personalization, and forum selection.

Generate, edit, and persist Ideal Customer Profile (ICP) segments for a workspace. ICPs are heavyweight context — they drive every downstream agent (keyword labeling defaults, content tone, content angle selection, outreach personalization).

Conceptual overview

An ICP is a structured customer-segment description: name, job-to-be-done, pain points, budget shape, where they spend time. Most workspaces have 2–4 segments. The agent uses them to:

  • Bias keyword labels toward the right relevance class
  • Choose content angles that match each segment's pain
  • Pick which subreddits / forums to scrape for discussion research
  • Personalize outreach drafts

ICPs are persistent — generated once (usually during bootstrap_brand), then edited as you learn more. The first version is rough; the third version is excellent.

Endpoints

MethodPathPurpose
POST/v1/research/icpGenerate ICP segments from a URL
GET/v1/research/icpGet current ICPs for the workspace
GET/v1/research/icp/{segmentId}Get one segment
POST/v1/research/icp/segmentAdd a segment manually
PATCH/v1/research/icp/{segmentId}Update a segment
DELETE/v1/research/icp/{segmentId}Remove a segment

POST /v1/research/icp

POST /v1/research/icp HTTP/1.1
Authorization: Bearer sk_live_***
X-Workspace-Id: ws_acme

{
  "domain":      "acme.com",
  "depth":       "thorough",
  "segmentCount":3,
  "customInstructions": "Focus on enterprise buyers in fintech and the engineering-leadership persona."
}
FieldTypeRequiredDefaultNotes
domainstringyes (one of)Crawl this domain to derive ICPs
seedTextstringyes (one of)Or paste in marketing copy / product description
depth"fast" | "thorough"no"thorough"fast skips the crawl, uses workspace's existing brand profile
segmentCountnumberno3How many segments to produce (typically 2–4)
customInstructionsstringnoFree-form steering
replacebooleannofalseIf true, replaces existing ICPs; if false, appends

Response

{
  "invocationId": "inv_***",
  "agentId": "agt_***",
  "skill": "research.icp",
  "status": "RUNNING",
  "estimatedCost": { "credits": 15, "durationSeconds": 120 }
}

Final result

{
  "invocationId": "inv_***",
  "agentId": "agt_***",
  "skill": "research.icp",
  "status": "SUCCEEDED",
  "creditsUsed": 14,
  "result": {
    "segments": [
      {
        "id": "seg_***",
        "name": "Engineering leadership at fintech",
        "jobToBeDone": "Ship faster without burning the team out",
        "pain": "Capacity is opaque; tickets pile up; oncall is a tax",
        "budgetShape": "$200-800/month per seat; quarterly buys",
        "buyingProcess": "Eng manager evaluates, CTO signs off, finance reviews quarterly",
        "channels": [
          "r/projectmanagement",
          "Lenny's Newsletter",
          "Hacker News"
        ],
        "competitors": ["Linear", "Jira", "Asana"],
        "confidence": 0.91,
        "sourceCitations": [
          "acme.com/customers/fintech-eng-team",
          "acme.com/blog/capacity-tracking"
        ]
      },
      { "...": "..." }
    ]
  },
  "raw": "I crawled 14 pages and synthesized three segments. The fintech engineering-leader segment is dominant in the customer logos ...",
  "files": ["agent-workspace/icp-evidence.md", "agent-output/icps.json"]
}

GET /v1/research/icp

curl https://api.citationbench.com/v1/research/icp \
  -H "Authorization: Bearer sk_live_***" \
  -H "X-Workspace-Id: ws_acme"

Returns the current ICP segments for the workspace.

{
  "segments": [
    {
      "id":            "seg_***",
      "name":          "Engineering leadership at fintech",
      "jobToBeDone":   "...",
      "pain":          "...",
      "budgetShape":   "...",
      "channels":      [...],
      "competitors":   [...],
      "createdAt":     "2026-02-01T...",
      "updatedAt":     "2026-05-15T..."
    }
  ]
}

POST /v1/research/icp/segment

Add a segment manually (skip the generation step).

curl -X POST .../v1/research/icp/segment -d '{
  "name":         "Design agency owners",
  "jobToBeDone":  "Track time across many client projects without becoming a tracker themselves",
  "pain":         "Existing tools assume one team, not 12 client engagements running concurrently",
  "budgetShape":  "$50-200/month per seat",
  "channels":     ["r/agency", "Bench Talk"]
}'

Returns the new segment.


PATCH /v1/research/icp/{segmentId}

Partial update.

curl -X PATCH .../v1/research/icp/seg_*** -d '{
  "pain": "Refined: existing tools force monthly billing UI that doesn't match agency project-based cycles"
}'

DELETE /v1/research/icp/{segmentId}

Soft-delete a segment. Tools that referenced it will no longer use it as default context.


MCP

> Generate ICPs for acme.com.

Claude calls research.icp.generate.

> Tighten the pain statement for the fintech-eng segment.

Claude calls research.icp.update.


Errors

StatusCodeCause
400validation_errorNeed either domain or seedText
422segment_limit_reachedWorkspace cap on segments (default 10)
503crawl_failedCouldn't crawl the domain

Cost

ActionCredits
POST /v1/research/icp (thorough)15
POST /v1/research/icp (fast)8
Other endpointsfree

Use cases (string things together)

A. ICPs drive keyword labeling

After generating ICPs, re-run keyword labeling so the agent uses the new context:

curl -X POST .../v1/research/icp -d '{"domain":"acme.com"}'
# (wait for completion)
curl -X POST .../v1/keywords/relabel -d '{"scope":{}}'

B. Personalize outreach per ICP

The link_building.serp_outreach skill uses ICPs to pick the most relevant angle when drafting emails. Editing your ICPs changes the next batch of drafts.

C. ICPs as part of bootstrap

bootstrap_brand runs research.icp as one of its 7 steps. You can also re-run it standalone any time.

D. Multi-ICP content briefs

A landing page can target a specific ICP segment:

curl -X POST .../v1/produce/landing-page -d '{
  "keywordId":     "kw_***",
  "icpSegmentId":  "seg_***"
}'

The agent writes copy aligned to that segment's pain + budget shape.

On this page