Content
REST endpoints for Content. Base URL https://api.competlab.com; every request needs a CL-API-Key header (see Authentication). Responses wrap in { item } or { items }; errors in { error }.
Get latest content intelligence data
/v1/projects/{projectId}/contentGet the latest content intelligence data for all competitors in a project. Returns URL counts, content categorization, strategic URL analysis, and competitive gap assessment. Use this to understand the content landscape across competitors.
Path parameters
| Name | Type | Description |
|---|---|---|
projectId | string | Project ID |
Request
curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content" \
-H "CL-API-Key: YOUR_COMPETLAB_API_KEY"Response 200 OK
Example
{
"item": {
"lastUpdatedAt": "2026-03-15T10:00:00.000Z",
"summary": {
"sitemapsChecked": 8,
"sitemapsSuccessful": 7,
"customer": {
"domain": "yoursite.com",
"totalUrls": 350,
"strategicUrls": 280,
"categorizedCounts": {
"blog": 120,
"docs": 80,
"tools": 5,
"landing": 30,
"legal": 10,
"caseStudies": 0,
"comparison": 3,
"integrations": 25,
"changelog": 15,
"webinars": 2,
"other": 60
}
},
"topCompetitor": {
"domain": "rival.com",
"strategicUrls": 420
},
"strategicUrlGap": -140,
"overallRank": 3,
"comparableCompetitors": 4,
"criticalGaps": [
{
"category": "caseStudies",
"categoryLabel": "Case Studies",
"competitorsWithContent": 3,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Create 3-5 case studies showcasing customer success stories"
}
],
"significantGaps": [
{
"category": "blog",
"categoryLabel": "Blog Posts",
"customerCount": 5,
"competitorAverage": 25,
"competitorMax": 42,
"gapPercentage": -80,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Increase blog output to at least match competitor average of 25 posts"
}
],
"advantages": [
{
"category": "docs",
"categoryLabel": "Documentation",
"customerCount": 120,
"competitorMax": 45,
"leadAmount": 75
}
],
"onTrack": [
{
"category": "landing",
"categoryLabel": "Landing Pages",
"customerCount": 30,
"competitorMax": 35,
"differencePercent": -14
}
],
"totalCriticalGaps": 2,
"totalSignificantGaps": 1,
"totalAdvantages": 3,
"totalOnTrack": 4
},
"competitors": [
{
"domain": "competitor.com",
"isOwn": false,
"totalUrls": 450,
"strategicUrls": 380,
"categorizedCounts": {
"blog": 150,
"docs": 100,
"tools": 10,
"landing": 40,
"legal": 15,
"caseStudies": 8,
"comparison": 5,
"integrations": 30,
"changelog": 20,
"webinars": 7,
"other": 65
},
"sitemapCount": 2
}
]
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scope | The CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope. |
| 404 | project_not_found | No project matches the id in the path. |
Every error uses the shared { error: { code, message, status } } envelope; code is one of the values listed above.
{
"error": {
"code": "api_key_invalid",
"message": "Invalid API key",
"status": 401
}
}Get content intelligence run history
/v1/projects/{projectId}/content/historyGet paginated history of content intelligence monitoring runs for a project. Each entry includes run timing and summary statistics with gap analysis.
Path parameters
| Name | Type | Description |
|---|---|---|
projectId | string | Project ID |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | number | Page number (1-indexed). Default 1. Min 1. | |
limit | number | Number of items per page. Default 20. Range 1–100. |
Request
curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content/history?page=1&limit=20" \
-H "CL-API-Key: YOUR_COMPETLAB_API_KEY"Response 200 OK
Example
{
"items": [
{
"runId": "507f1f77bcf86cd799439011",
"completedAt": "2026-03-15T10:00:00.000Z",
"summary": {
"sitemapsChecked": 8,
"sitemapsSuccessful": 7,
"customer": {
"domain": "yoursite.com",
"totalUrls": 350,
"strategicUrls": 280,
"categorizedCounts": {
"blog": 120,
"docs": 80,
"tools": 5,
"landing": 30,
"legal": 10,
"caseStudies": 0,
"comparison": 3,
"integrations": 25,
"changelog": 15,
"webinars": 2,
"other": 60
}
},
"topCompetitor": {
"domain": "rival.com",
"strategicUrls": 420
},
"strategicUrlGap": -140,
"overallRank": 3,
"comparableCompetitors": 4,
"criticalGaps": [
{
"category": "caseStudies",
"categoryLabel": "Case Studies",
"competitorsWithContent": 3,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Create 3-5 case studies showcasing customer success stories"
}
],
"significantGaps": [
{
"category": "blog",
"categoryLabel": "Blog Posts",
"customerCount": 5,
"competitorAverage": 25,
"competitorMax": 42,
"gapPercentage": -80,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Increase blog output to at least match competitor average of 25 posts"
}
],
"advantages": [
{
"category": "docs",
"categoryLabel": "Documentation",
"customerCount": 120,
"competitorMax": 45,
"leadAmount": 75
}
],
"onTrack": [
{
"category": "landing",
"categoryLabel": "Landing Pages",
"customerCount": 30,
"competitorMax": 35,
"differencePercent": -14
}
],
"totalCriticalGaps": 2,
"totalSignificantGaps": 1,
"totalAdvantages": 3,
"totalOnTrack": 4
}
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 47,
"totalPages": 3,
"hasMore": true
}
}Paginated — pass page and limit query parameters and follow pagination.hasMore to page through the full set.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scope | The CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope. |
Every error uses the shared { error: { code, message, status } } envelope; code is one of the values listed above.
{
"error": {
"code": "api_key_invalid",
"message": "Invalid API key",
"status": 401
}
}Get content intelligence data for a specific run
/v1/projects/{projectId}/content/history/{runId}Get full content intelligence data for a specific historical monitoring run, including per-competitor URL counts, content categorization, and strategic URL metrics.
Path parameters
| Name | Type | Description |
|---|---|---|
runId | string | Run ID |
projectId | string | Project ID |
Request
curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content/history/507f1f77bcf86cd799439012" \
-H "CL-API-Key: YOUR_COMPETLAB_API_KEY"Response 200 OK
Example
{
"item": {
"runId": "507f1f77bcf86cd799439011",
"completedAt": "2026-03-15T10:00:00.000Z",
"summary": {
"sitemapsChecked": 8,
"sitemapsSuccessful": 7,
"customer": {
"domain": "yoursite.com",
"totalUrls": 350,
"strategicUrls": 280,
"categorizedCounts": {
"blog": 120,
"docs": 80,
"tools": 5,
"landing": 30,
"legal": 10,
"caseStudies": 0,
"comparison": 3,
"integrations": 25,
"changelog": 15,
"webinars": 2,
"other": 60
}
},
"topCompetitor": {
"domain": "rival.com",
"strategicUrls": 420
},
"strategicUrlGap": -140,
"overallRank": 3,
"comparableCompetitors": 4,
"criticalGaps": [
{
"category": "caseStudies",
"categoryLabel": "Case Studies",
"competitorsWithContent": 3,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Create 3-5 case studies showcasing customer success stories"
}
],
"significantGaps": [
{
"category": "blog",
"categoryLabel": "Blog Posts",
"customerCount": 5,
"competitorAverage": 25,
"competitorMax": 42,
"gapPercentage": -80,
"leader": {
"domain": "competitor.com",
"count": 42,
"exampleUrls": [
"https://competitor.com/blog/post-1",
"https://competitor.com/blog/post-2"
]
},
"actionHint": "Increase blog output to at least match competitor average of 25 posts"
}
],
"advantages": [
{
"category": "docs",
"categoryLabel": "Documentation",
"customerCount": 120,
"competitorMax": 45,
"leadAmount": 75
}
],
"onTrack": [
{
"category": "landing",
"categoryLabel": "Landing Pages",
"customerCount": 30,
"competitorMax": 35,
"differencePercent": -14
}
],
"totalCriticalGaps": 2,
"totalSignificantGaps": 1,
"totalAdvantages": 3,
"totalOnTrack": 4
},
"competitors": [
{
"domain": "competitor.com",
"isOwn": false,
"totalUrls": 450,
"strategicUrls": 380,
"categorizedCounts": {
"blog": 150,
"docs": 100,
"tools": 10,
"landing": 40,
"legal": 15,
"caseStudies": 8,
"comparison": 5,
"integrations": 30,
"changelog": 20,
"webinars": 7,
"other": 65
},
"sitemapCount": 2
}
]
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scope | The CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope. |
| 404 | run_not_found | No run matches the id in the path. |
Every error uses the shared { error: { code, message, status } } envelope; code is one of the values listed above.
{
"error": {
"code": "api_key_invalid",
"message": "Invalid API key",
"status": 401
}
}Get content changelog
/v1/projects/{projectId}/content/changelogGet paginated changelog of detected URL changes across competitor sitemaps. Each item shows numeric counts per category plus up to 3 sample URLs per category by default — safe for any token budget. Supports filtering by competitorId and category query parameters. Pass allUrlsPerCategory=true for the full URL list per category (warning: high-activity competitors can produce large responses; combine with filters to scope, and check the truncated flag in the response — when true, the byte cap fired and items/URLs were trimmed).
Path parameters
| Name | Type | Description |
|---|---|---|
projectId | string | Project ID |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | number | Page number (1-indexed). Default 1. Min 1. | |
limit | number | Number of items per page. Default 20. Range 1–100. | |
competitorId | string | Filter by competitor ID | |
category | string | Filter by content category (blog, docs, tools, landing, legal, caseStudies, comparison, integrations, changelog, webinars, other) | |
allUrlsPerCategory | boolean | By default each item returns up to 3 sample URLs per category. Set true to return the full URL list per category. High-activity competitors can produce large responses — combine with category and competitorId filters to scope. Subject to an internal byte cap; check truncated in the response. |
Request
curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content/changelog?page=1&limit=20&competitorId=507f1f77bcf86cd799439011&category=blog&allUrlsPerCategory=false" \
-H "CL-API-Key: YOUR_COMPETLAB_API_KEY"Response 200 OK
Example
{
"items": [
{
"competitorDomain": "competitor.com",
"sitemapUrl": "https://competitor.com/sitemap.xml",
"checkedAt": "2026-03-15T10:00:00.000Z",
"totalAdded": 5,
"totalRemoved": 2,
"addedByCategory": {
"blog": [
"https://competitor.com/blog/new-post"
],
"docs": [
"https://competitor.com/docs/new-guide"
]
},
"removedByCategory": {
"landing": [
"https://competitor.com/old-landing"
]
},
"addedCounts": {
"blog": 1,
"docs": 1
},
"removedCounts": {
"landing": 1
}
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 47,
"totalPages": 3,
"hasMore": true
},
"truncated": false
}Paginated — pass page and limit query parameters and follow pagination.hasMore to page through the full set.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scope | The CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope. |
Every error uses the shared { error: { code, message, status } } envelope; code is one of the values listed above.
{
"error": {
"code": "api_key_invalid",
"message": "Invalid API key",
"status": 401
}
}