Research · Competitor API — Track Backlinks, Keywords & Overlap Matrices
Add competitors as first-class workspace resources, then pull their backlinks, ranking keywords, and keyword overlap matrices against your own library — the data layer behind gap analysis and outreach.
Track competitors and pull intelligence about them: their backlinks, the keywords they rank for, the keyword overlap matrix against your own library. Competitors are workspace-scoped first-class resources — you add them once, then any tool can reference them.
Conceptual overview
A competitor is a domain you're tracking against your workspace. Each adds three queryable data sources:
- Backlinks — every site linking to the competitor (via Ahrefs), scored by domain quality and relevance to your offering
- Keywords — every keyword the competitor ranks for, with position + estimated traffic
- Overlap matrix — your keyword library × theirs; reveals what they have that you don't (and vice versa)
This is the data layer behind Link Building · competitor link outreach (turn competitor backlinks into your outreach targets) and Research · content gap (find topics they cover that you don't).
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/research/competitor | Add a competitor |
| GET | /v1/research/competitor | List tracked competitors |
| GET | /v1/research/competitor/{id} | Get one competitor + summary stats |
| PATCH | /v1/research/competitor/{id} | Update tags / notes / weight |
| DELETE | /v1/research/competitor/{id} | Stop tracking |
| POST | /v1/research/competitor/{id}/backlinks | Pull / refresh backlink data |
| POST | /v1/research/competitor/{id}/keywords | Pull / refresh keyword data |
| GET | /v1/research/competitor/{id}/backlinks | List stored backlinks |
| GET | /v1/research/competitor/{id}/keywords | List stored keywords |
| GET | /v1/research/competitor/{id}/overlap | Keyword overlap matrix vs. your workspace |
POST /v1/research/competitor
curl -X POST https://api.citationbench.com/v1/research/competitor \
-H "Authorization: Bearer sk_live_***" \
-H "X-Workspace-Id: ws_acme" \
-d '{
"domain": "monday.com",
"weight": "incumbent",
"tags": ["enterprise", "pm-category"],
"notes": "Primary incumbent in enterprise PM"
}'| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
domain | string | yes | — | The competitor's primary domain |
weight | enum | no | "alternative" | incumbent, alternative, complementary, inspiration — drives how their data is used in scoring |
tags | string[] | no | — | — |
notes | string | no | — | Free text |
Response
{
"id": "cmp_***",
"domain": "monday.com",
"weight": "incumbent",
"tags": ["enterprise", "pm-category"],
"stats": {
"backlinks": null,
"keywords": null,
"lastBacklinkPullAt": null,
"lastKeywordPullAt": null
},
"createdAt": "2026-05-24T08:01:00Z"
}stats populates after you pull data via the sub-endpoints.
POST /v1/research/competitor/{id}/backlinks
Pulls fresh backlink data from Ahrefs and stores CompetitorPage + CompetitorKeyword records.
curl -X POST https://api.citationbench.com/v1/research/competitor/cmp_***/backlinks \
-d '{
"limit": 5000,
"minDomainRating":30,
"linkType": "dofollow"
}'| Field | Notes |
|---|---|
limit | Max backlinks to store (default 1000) |
minDomainRating | Floor for DR (default 0) |
linkType | dofollow, nofollow, all |
country | Filter by linking domain country |
freshness | cached returns the last pull; default refetches |
Returns an invocationId. On completion, result includes counts and a sample.
{
"result": {
"pulled": 4247,
"stored": 4108,
"byDR": { "80+": 132, "60-79": 821, "40-59": 1947, "<40": 1208 },
"byCountry": { "us": 2641, "uk": 481, "in": 312 }
}
}POST /v1/research/competitor/{id}/keywords
Pulls every keyword the competitor ranks for.
curl -X POST .../v1/research/competitor/cmp_***/keywords \
-d '{
"topPosition": 20,
"minVolume": 100,
"freshness": "now"
}'Stores CompetitorKeyword + CompetitorKeywordRank records.
GET /v1/research/competitor/{id}/backlinks
curl -G .../v1/research/competitor/cmp_***/backlinks \
--data-urlencode "minDR=40" \
--data-urlencode "relevance=high" \
--data-urlencode "limit=100"{
"data": [
{
"id": "cbl_***",
"sourceDomain": "engineering-blog.com",
"sourceUrl": "https://engineering-blog.com/best-pm-tools",
"targetUrl": "https://monday.com/features",
"domainRating": 62,
"linkType": "dofollow",
"anchorText": "monday.com's project management",
"relevanceScore": 0.84,
"achievabilityScore": 0.71,
"firstSeenAt": "2024-08-12",
"lastSeenAt": "2026-05-15"
}
],
"nextCursor": null,
"total": 4108
}achievabilityScore is our heuristic for "how likely you could earn this link too" — based on domain authority, content type, prior outreach receptivity.
GET /v1/research/competitor/{id}/keywords
curl -G .../v1/research/competitor/cmp_***/keywords \
--data-urlencode "topPosition=10" \
--data-urlencode "limit=200"{
"data": [
{
"id": "ckw_***",
"keyword": "project management software",
"position": 1,
"estimatedTraffic": 28400,
"intent": "PURCHASE"
}
],
"total": 7281
}GET /v1/research/competitor/{id}/overlap
Compute the keyword overlap matrix between your workspace and the competitor.
curl https://api.citationbench.com/v1/research/competitor/cmp_***/overlap{
"competitorId": "cmp_***",
"competitorDomain": "monday.com",
"summary": {
"competitorKeywords": 7281,
"ourKeywords": 612,
"shared": 184,
"competitorOnly": 7097,
"ourOnly": 428,
"overlapRatio": 0.3
},
"topGaps": [
{
"keyword": "engineering capacity tracking",
"competitorRank": 8,
"ourRank": null,
"volume": 540
},
{
"keyword": "sprint planning for distributed teams",
"competitorRank": 4,
"ourRank": null,
"volume": 720
}
],
"topWins": [
{
"keyword": "open source project management",
"ourRank": 6,
"competitorRank": 42,
"volume": 280
}
]
}MCP
> Add monday.com as a competitor and pull their keywords + backlinks.Claude calls research.competitor.add, then research.competitor.keywords, then research.competitor.backlinks.
> What keywords does monday.com rank for that we don't?Claude calls research.competitor.overlap and renders the topGaps.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | validation_error | Missing / malformed domain |
| 409 | competitor_exists | Already tracking |
| 503 | ahrefs_unavailable | Backlink pull failed |
| 503 | dataforseo_unavailable | Keyword pull failed |
Cost
| Action | Credits |
|---|---|
POST /v1/research/competitor | free |
POST /backlinks | 30 (one-time pull; refresh costs 30) |
POST /keywords | 20 |
GET /overlap | 2 (computed on demand) |
| All other GETs | free |
Use cases (string things together)
A. Steal-from-competitor outreach
# 1. Track + pull
COMP=$(curl -sf -X POST .../v1/research/competitor -d '{"domain":"monday.com"}' | jq -r '.id')
curl -X POST .../v1/research/competitor/$COMP/backlinks
# 2. Pitch our content to the same backlink sources
curl -X POST .../v1/link-building/competitor-outreach -d "{
\"competitorId\": \"$COMP\",
\"ourContentUrl\": \"https://acme.com/blog/engineering-team-capacity-tracking\",
\"minDR\": 40
}"B. Content gap surface
# 1. Build keyword universe
curl -X POST .../v1/research/keyword -d '{"seed":"project management software"}'
# 2. Add 3 competitors
for D in monday.com asana.com clickup.com; do
curl -X POST .../v1/research/competitor -d "{\"domain\":\"$D\"}"
done
# 3. Pull each one's keywords
# 4. Run overlap → content gap report
curl -X POST .../v1/research/content-gap -d '{
"competitorIds": ["cmp_A", "cmp_B", "cmp_C"]
}'C. Continuous monitoring
# Weekly refresh of competitor keywords
curl -X POST .../v1/agent/invoke -d '{
"skill": "agent.scheduled",
"input": {
"action": "research.competitor.keywords",
"schedule":"weekly:sun:18:00",
"config": { "competitorId": "cmp_***" }
}
}'Related
- API: Research · keyword
- API: Research · content gap
- API: Link Building · competitor link outreach
- Concept: 2D Keyword Labelling
- Playbook: From competitor URL to content plan
SERP gap analysis
Score whether a SERP is winnable by detecting DR, content, brand, and intent cliffs — the highest-ROI question to ask before committing content production to a keyword.
ICP
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.