Skip to Content

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

GET/v1/projects/{projectId}/content

Get 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.

Returns · { item }

Path parameters

NameTypeDescription
projectIdstringProject ID

Request

curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content" \ -H "CL-API-Key: YOUR_COMPETLAB_API_KEY"

Response 200 OK

{ "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

StatusCodeMeaning
401api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scopeThe CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope.
404project_not_foundNo 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

GET/v1/projects/{projectId}/content/history

Get paginated history of content intelligence monitoring runs for a project. Each entry includes run timing and summary statistics with gap analysis.

Returns · { items, pagination }

Path parameters

NameTypeDescription
projectIdstringProject ID

Query parameters

NameTypeRequiredDescription
pagenumberPage number (1-indexed). Default 1. Min 1.
limitnumberNumber of items per page. Default 20. Range 1100.

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

{ "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

StatusCodeMeaning
401api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scopeThe 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

GET/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.

Returns · { item }

Path parameters

NameTypeDescription
runIdstringRun ID
projectIdstringProject ID

Request

curl "https://api.competlab.com/v1/projects/507f1f77bcf86cd799439011/content/history/507f1f77bcf86cd799439012" \ -H "CL-API-Key: YOUR_COMPETLAB_API_KEY"

Response 200 OK

{ "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

StatusCodeMeaning
401api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scopeThe CL-API-Key is missing, malformed, revoked, expired, or lacks the required scope.
404run_not_foundNo 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

GET/v1/projects/{projectId}/content/changelog

Get 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).

Returns · { items, pagination, truncated }

Path parameters

NameTypeDescription
projectIdstringProject ID

Query parameters

NameTypeRequiredDescription
pagenumberPage number (1-indexed). Default 1. Min 1.
limitnumberNumber of items per page. Default 20. Range 1100.
competitorIdstringFilter by competitor ID
categorystringFilter by content category (blog, docs, tools, landing, legal, caseStudies, comparison, integrations, changelog, webinars, other)
allUrlsPerCategorybooleanBy 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

{ "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

StatusCodeMeaning
401api_key_missing · api_key_invalid · api_key_revoked · api_key_expired · insufficient_scopeThe 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 } }
Last updated on