Skip to Content

Agent Adoption

REST endpoints for Agent Adoption. 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 }.

Start an async agent-adoption scan

POST/v1/tools/agent-adoption/scans

Start an asynchronous AI agent-adoption scan for a public domain. Runs 25 checks across four categories — discoverability (robots.txt, sitemap.xml, Link headers), accessControl (AI bot rules, content signals, web-bot-auth, robots-allow-all), contentReadability (/llms.txt, markdown negotiation, rendering strategy, page size, redirects, agents.md, cache headers), and agentEndpoints (OpenAPI catalog, OAuth discovery, MCP server card, A2A agent card, agent skills). Returns sub-second with item: { id, status: "queued", createdAt, expiresAt } — poll GET /v1/tools/agent-adoption/scans/{scanId} until status is completed or failed. Most scans complete in 35–60 seconds; slow or JS-heavy domains can take up to ~3 minutes. Result and error payloads are persisted for 24h, after which the scan auto-deletes and GET returns 404. No project required. Suitable for AI-adoption audits, agent-adoption maturity assessments, and pre-launch agentic-commerce reviews — and the only supported shape for MCP clients (Cursor / Claude Desktop hardcode 60-second tool-call timeouts).

Returns · { item }

Request bodyapplication/json

FieldTypeDescription
domainstringTarget domain to scan for AI-agent readiness. Accepts a bare hostname or a full URL — normalized (lowercased, scheme and path stripped) before scanning.
debugModebooleanWhen true, include the full HTTP trace (evidence) for every check in the response. Defaults to false.
includeFixPromptsbooleanWhen true, include a copy-paste remediation prompt (fixPrompt) for each failed, scored check. Defaults to false.

Request

curl -X POST "https://api.competlab.com/v1/tools/agent-adoption/scans" \ -H "CL-API-Key: YOUR_COMPETLAB_API_KEY" \ -H "Content-Type: application/json" \ -d '{"domain":"stripe.com","debugMode":false,"includeFixPrompts":false}'

Response 200 OK

{ "item": { "id": "6638e9a1b2c3d4e5f6a7b8c9", "status": "queued", "createdAt": "2026-05-17T14:30:00.000Z", "expiresAt": "2026-05-18T14:30:00.000Z" } }

Errors

StatusCodeMeaning
400invalid_parametersBad request — the payload failed validation.
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.
429rate_limit_exceededRate limit exceeded — retry with backoff.
502bad_gatewayUpstream fetch failed (e.g. the target page could not be retrieved).

Every error uses the shared { error: { code, message, status } } envelope; code is one of the values listed above.

{ "error": { "code": "invalid_parameters", "message": "Domain is required", "status": 400 } }

Transient failures (429, 5xx) are safe to retry with exponential backoff.

Get an async agent-adoption scan by ID

GET/v1/tools/agent-adoption/scans/{scanId}

Get the current state of an async agent-adoption scan. Returns the scan’s lifecycle (queued / running / completed / failed) along with createdAt and expiresAt always, plus startedAt once the runner picks it up and completedAt once it reaches a terminal state. On completed the full canonical scan response is in item.result. On failed the failure details are in item.error with a machine-readable code — currently homepage_fetch_failed (upstream homepage fetch threw) or scan_failed (any other error during scan execution). Scoped to the API key’s organization — cross-tenant access, never-existed IDs, expired IDs (24h TTL), and malformed IDs all return 404 scan_not_found with an identical envelope to prevent existence-disclosure. Typically sub-second — safe to poll on a 2–5 second interval depending on your timeout budget.

Returns · { item }

Path parameters

NameTypeDescription
scanIdstring

Request

curl "https://api.competlab.com/v1/tools/agent-adoption/scans/65a1b2c3d4e5f6a7b8c9d0e1" \ -H "CL-API-Key: YOUR_COMPETLAB_API_KEY"

Response 200 OK

{ "item": { "id": "6638e9a1b2c3d4e5f6a7b8c9", "status": "completed", "createdAt": "2026-05-17T14:30:00.000Z", "expiresAt": "2026-05-18T14:30:00.000Z", "startedAt": "2026-05-17T14:30:00.412Z", "completedAt": "2026-05-17T14:30:08.420Z", "result": { "specVersion": "1.0.0", "profile": "b2b-saas", "scanner": { "name": "CompetLab Agent-Adoption Scanner", "version": "0.8.0" }, "domain": "stripe.com", "finalUrl": "https://stripe.com/", "scannedAt": "2026-05-17T14:30:08.000Z", "score": 72, "level": 2, "levelName": "AI-Aware", "categoryReports": [ { "category": "discoverability", "description": "Whether AI agents can find your site through standard discovery mechanisms (robots.txt, sitemaps, link headers).", "score": 100, "passed": 1, "failed": 0, "neutral": 0, "checks": [ { "id": "robots-txt-exists", "category": "discoverability", "status": "pass", "scored": true, "weight": 10, "message": "robots.txt found at https://stripe.com/robots.txt with 3 user-agent rules", "description": "Verifies a /robots.txt file exists and is fetchable.", "durationMs": 142, "dependsOn": [], "specUrls": [ "https://www.rfc-editor.org/rfc/rfc9309" ] } ] }, { "category": "accessControl", "description": "Whether your access rules deliberately allow or block AI agents.", "score": 100, "passed": 1, "failed": 0, "neutral": 0, "checks": [ { "id": "ai-bot-rules", "category": "accessControl", "status": "pass", "scored": true, "weight": 7, "message": "Explicit rules found for 4 known AI user-agents", "description": "Checks whether robots.txt declares explicit rules for known AI crawlers.", "durationMs": 38, "dependsOn": [ "robots-txt-exists" ], "specUrls": [ "https://platform.openai.com/docs/bots" ] } ] }, { "category": "contentReadability", "description": "Whether your content is structured for efficient agent consumption.", "score": 0, "passed": 0, "failed": 1, "neutral": 0, "checks": [ { "id": "llms-txt-exists", "category": "contentReadability", "status": "fail", "scored": true, "weight": 4, "message": "No /llms.txt file found", "description": "Verifies a /llms.txt file exists at the site root.", "durationMs": 51, "dependsOn": [], "specUrls": [ "https://llmstxt.org/" ] } ] }, { "category": "agentEndpoints", "description": "Whether you expose machine-readable agent endpoints (MCP, A2A, OAuth discovery).", "score": 0, "passed": 0, "failed": 0, "neutral": 1, "checks": [ { "id": "mcp-server-card", "category": "agentEndpoints", "status": "neutral", "scored": false, "weight": 0, "message": "No MCP server card detected (informational)", "description": "Looks for a published MCP server card advertising agent tools.", "durationMs": 44, "dependsOn": [], "specUrls": [ "https://modelcontextprotocol.io/" ] } ] } ], "clusters": [ { "name": "htmlPath", "kind": "coefficient", "triggered": true, "coefficient": 1, "appliesTo": [ "rendering-strategy", "page-size-html" ], "message": "Standard HTML path detected — no rendering penalties applied." }, { "name": "spaRenderingCap", "kind": "cap", "triggered": false, "message": "No SPA rendering cap applied." }, { "name": "noViablePathCap", "kind": "cap", "triggered": false, "message": "A viable agent path exists — no cap applied." } ], "meta": { "checksEvaluated": 25, "checksSkipped": 0, "scanDurationMs": 8420, "counters": { "fetches": { "total": 28, "success": 22, "wafBlocked": 0, "notFound": 5, "failed": 1 }, "heavyFetchCalls": { "total": 2, "success": 2, "unavailable": 0 } } } } } }

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.
404scan_not_foundNo scan matches the id in the path.
429rate_limit_exceededRate limit exceeded — retry with backoff.

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 } }

Transient failures (429, 5xx) are safe to retry with exponential backoff.

Last updated on