Skip to Content

Positioning

REST endpoints for Positioning. 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 positioning data

GET/v1/projects/{projectId}/positioning

Get the latest positioning data for all competitors in a project. Returns homepage messaging, value propositions, CTAs, target audience, and competitive messaging analysis. Fields we could not measure are null, with a sibling availability object giving the reason; never read a null as zero, false or absent, and note that a measured 0 / false / empty list is reported as itself and is a real finding. For the messaging strings the distinction is sharp: a measured EMPTY STRING means we read the page and there is genuinely no call to action, which is a finding; a null means we never read it. A project with no completed run for this dimension yet answers 404 no_data_available — not a missing project and not a failed measurement, just nothing measured here so far; the project itself is fine and get_project still describes it. Distinguish it from project_not_found, which means the id is wrong.

Returns · { item }

Path parameters

NameTypeDescription
projectIdstringProject ID

Request

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

Response 200 OK

{ "item": { "lastUpdatedAt": "2026-03-15T10:00:00.000Z", "summary": { "competitorsChecked": 6, "competitorsSuccessful": 5, "customer": { "domain": "yoursite.com", "messagingStrengthScore": 72, "hasSpecificHeadline": true, "hasStrongCta": true, "showsPricing": false, "hasFreeTrial": true, "primaryCta": "Start Free Trial", "mainHeadline": "Ship Projects 10x Faster", "messagingAnalysisAvailable": { "available": false, "reason": "homepage_fetch_failed" } }, "topMessagingCompetitor": { "domain": "rival.com", "messagingStrengthScore": 88, "primaryCta": "Try It Free", "mainHeadline": "The Future of Work" }, "ctaComparison": { "yourCta": "Start Free Trial", "strongestCompetitorCta": "Get Started — It's Free", "strongestCompetitorDomain": "rival.com" }, "pricingComparison": { "competitorsShowingPrice": 3, "competitorsWithFreeTrial": 4, "youShowPrice": false, "youHaveFreeTrial": true }, "messagingScoreGap": -16 }, "competitors": [ { "domain": "competitor.com", "isOwn": false, "homepageUrl": "https://competitor.com", "content": { "pageTitle": "Acme - The #1 Project Management Tool", "pageDescription": "Manage projects, track tasks, and collaborate with your team.", "mainHeadline": "Ship Projects 10x Faster", "tagline": "The all-in-one platform for modern teams", "valueProposition": "Streamline your workflow with AI-powered project management", "primaryCTA": "Start Free Trial", "secondaryCTA": "Book a Demo", "keyOfferings": [ "Task Management", "Time Tracking", "Team Collaboration" ], "targetAudience": "Product teams and agencies", "mainDifferentiator": "AI-powered automation that saves 5 hours per week", "pricingMentioned": true, "startingPrice": "$9/month", "hasFreeTrial": true, "freeTrialDuration": "14 days" } } ] } }

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_found · no_data_availableNo 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 positioning run history

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

Get paginated history of positioning monitoring runs for a project. Each entry includes run timing and summary statistics with messaging gap analysis. Fields we could not measure are null, with a sibling availability object giving the reason; never read a null as zero, false or absent, and note that a measured 0 / false / empty list is reported as itself and is a real finding.

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/positioning/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": { "competitorsChecked": 6, "competitorsSuccessful": 5, "customer": { "domain": "yoursite.com", "messagingStrengthScore": 72, "hasSpecificHeadline": true, "hasStrongCta": true, "showsPricing": false, "hasFreeTrial": true, "primaryCta": "Start Free Trial", "mainHeadline": "Ship Projects 10x Faster", "messagingAnalysisAvailable": { "available": false, "reason": "homepage_fetch_failed" } }, "topMessagingCompetitor": { "domain": "rival.com", "messagingStrengthScore": 88, "primaryCta": "Try It Free", "mainHeadline": "The Future of Work" }, "ctaComparison": { "yourCta": "Start Free Trial", "strongestCompetitorCta": "Get Started — It's Free", "strongestCompetitorDomain": "rival.com" }, "pricingComparison": { "competitorsShowingPrice": 3, "competitorsWithFreeTrial": 4, "youShowPrice": false, "youHaveFreeTrial": true }, "messagingScoreGap": -16 } } ], "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 positioning data for a specific run

GET/v1/projects/{projectId}/positioning/history/{runId}

Get full positioning data for a specific historical monitoring run, including per-competitor homepage messaging, value propositions, CTAs, and audience data. Fields we could not measure are null, with a sibling availability object giving the reason; never read a null as zero, false or absent, and note that a measured 0 / false / empty list is reported as itself and is a real finding. A run that finished but produced no summary answers 404 run_not_summarized, which is a different fact from run_not_found: the run exists, it just has nothing to report. It used to answer 200 with an all-zero summary invented from the missing one.

Returns · { item }

Path parameters

NameTypeDescription
runIdstringRun ID
projectIdstringProject ID

Request

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

Response 200 OK

{ "item": { "runId": "507f1f77bcf86cd799439011", "completedAt": "2026-03-15T10:00:00.000Z", "summary": { "competitorsChecked": 6, "competitorsSuccessful": 5, "customer": { "domain": "yoursite.com", "messagingStrengthScore": 72, "hasSpecificHeadline": true, "hasStrongCta": true, "showsPricing": false, "hasFreeTrial": true, "primaryCta": "Start Free Trial", "mainHeadline": "Ship Projects 10x Faster", "messagingAnalysisAvailable": { "available": false, "reason": "homepage_fetch_failed" } }, "topMessagingCompetitor": { "domain": "rival.com", "messagingStrengthScore": 88, "primaryCta": "Try It Free", "mainHeadline": "The Future of Work" }, "ctaComparison": { "yourCta": "Start Free Trial", "strongestCompetitorCta": "Get Started — It's Free", "strongestCompetitorDomain": "rival.com" }, "pricingComparison": { "competitorsShowingPrice": 3, "competitorsWithFreeTrial": 4, "youShowPrice": false, "youHaveFreeTrial": true }, "messagingScoreGap": -16 }, "competitors": [ { "domain": "competitor.com", "isOwn": false, "homepageUrl": "https://competitor.com", "content": { "pageTitle": "Acme - The #1 Project Management Tool", "pageDescription": "Manage projects, track tasks, and collaborate with your team.", "mainHeadline": "Ship Projects 10x Faster", "tagline": "The all-in-one platform for modern teams", "valueProposition": "Streamline your workflow with AI-powered project management", "primaryCTA": "Start Free Trial", "secondaryCTA": "Book a Demo", "keyOfferings": [ "Task Management", "Time Tracking", "Team Collaboration" ], "targetAudience": "Product teams and agencies", "mainDifferentiator": "AI-powered automation that saves 5 hours per week", "pricingMentioned": true, "startingPrice": "$9/month", "hasFreeTrial": true, "freeTrialDuration": "14 days" } } ] } }

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_found · run_not_summarizedNo 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 } }
Last updated on