AI Crawler Checker
REST endpoints for AI Crawler Checker. 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 }.
Check AI crawler accessibility for a domain
/v1/tools/ai-crawler-checkerCheck which AI ASSISTANTS can fetch a public domain’s pages, read from its robots.txt. assistantAccess is the answer: one verdict per assistant — ChatGPT, Claude, Perplexity, Microsoft Copilot, Google AI Overviews, Gemini Apps — with the crawlers that decided each named beside it. Count that array for totals; no count is stored and there is deliberately no overall score, because a weighted index has no unit and shifts when our crawler catalog moves rather than when the site does. Every tracked crawler is also returned individually with what it is FOR, the line of robots.txt that decided it, and whether a rule NAMED it or a User-agent: * catch-all swept it up — the second is usually accidental and is the more actionable finding. modelTrainingAccess is reported separately and NEUTRALLY: blocking training crawlers is a legitimate content decision and is never a gap, with one mechanical exception the response documents. This reads permission, not outcomes — it never claims a site is or is not cited. When robots.txt cannot be read, the read outcome is returned and the entire verdict layer is ABSENT rather than assumed. Optionally tailor the industry context. Stateless live check — no project required, no data is persisted.
Request body — application/json
| Field | Type | Description |
|---|---|---|
domain | string | Target domain to check. Accepts a bare hostname or a full URL — normalized (lowercased, scheme and path stripped) before checking. |
industry | string | Industry context used to tailor crawler recommendations and benchmarks. Defaults to “other” when omitted. Values: news-media, arts-entertainment, law-government, finance-healthcare, saas-tech, ecommerce, other. |
Request
curl -X POST "https://api.competlab.com/v1/tools/ai-crawler-checker" \
-H "CL-API-Key: YOUR_COMPETLAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"domain":"stripe.com","industry":"saas-tech"}'Response 200 OK
Example
{
"item": {
"domain": "competlab.com",
"fetchedAt": "2026-05-16T14:30:00.000Z",
"industry": "saas-tech",
"scopeOfAnswer": "This reads your robots.txt — the access rules you publish. It does not measure whether AI assistants actually cite you. Rules written into the page itself, such as meta robots and X-Robots-Tag, don't change these verdicts; we report those separately in the homepage results, along with whether we could read that page at all.",
"crawlers": [
{
"userAgent": "GPTBot",
"displayName": "GPTBot",
"operator": "OpenAI",
"crawlerPurpose": "collects_training_data",
"honoursRobotsTxt": "yes",
"honoursRobotsTxtEvidence": "operator_documented",
"operatorDocumentationUrl": "https://platform.openai.com/docs/bots",
"operatorDocsLastCheckedOn": "2026-08-13",
"status": "blocked",
"matchingDirective": "Disallow: /",
"matchingDirectiveLine": 14,
"ruleAudience": "wildcard_catch_all"
}
],
"robotsTxt": {
"found": true,
"read": {
"state": "read",
"reason": "access_http_error_status",
"httpStatusCode": 503
},
"content": "User-agent: GPTBot\nDisallow: /\n\nUser-agent: *\nAllow: /\n",
"statusCode": 200
},
"homepage": {
"read": {
"state": "read",
"reason": "access_http_error_status",
"httpStatusCode": 503
},
"metaTags": [
{
"name": "robots",
"content": "noai, noimageai"
}
],
"xRobotsTag": "noai, noimageai"
},
"llmsTxt": {
"read": {
"state": "read",
"reason": "access_http_error_status",
"httpStatusCode": 503
},
"sectionCount": 12,
"linkCount": 47,
"approxTokens": 1850
},
"llmsFullTxt": {
"read": {
"state": "read",
"reason": "access_http_error_status",
"httpStatusCode": 503
},
"sectionCount": 12,
"linkCount": 47,
"approxTokens": 1850
},
"assistantAccess": [
{
"assistantName": "ChatGPT",
"crawlerAccessStatus": "can_reach_site",
"appliesTo": "whole_site",
"decidedByCrawlers": [
{
"userAgentToken": "OAI-SearchBot",
"crawlerPurpose": "fetches_pages_to_cite_in_answers",
"honoursRobotsTxt": "yes",
"honoursRobotsTxtEvidence": "operator_documented",
"decidedByRuleFor": "wildcard_catch_all",
"decidedByDirective": "Disallow: /",
"decidedByLineNumber": 14
}
],
"explanations": [
{
"code": "training_blocked",
"text": "Blocking a training crawler asks these operators not to use your content for model training. It does not affect whether AI assistants can cite you."
}
]
}
],
"modelTrainingAccess": [
{
"modelOperatorName": "OpenAI",
"trainingAccessStatus": "may_use_content_for_training",
"decidedByCrawlers": [
{
"userAgentToken": "OAI-SearchBot",
"crawlerPurpose": "fetches_pages_to_cite_in_answers",
"honoursRobotsTxt": "yes",
"honoursRobotsTxtEvidence": "operator_documented",
"decidedByRuleFor": "wildcard_catch_all",
"decidedByDirective": "Disallow: /",
"decidedByLineNumber": 14
}
],
"explanations": [
{
"code": "training_blocked",
"text": "Blocking a training crawler asks these operators not to use your content for model training. It does not affect whether AI assistants can cite you."
}
]
}
],
"industryPosition": {
"industryLabel": "SaaS & Tech",
"industryAnyAiCrawlerBlockRate": 25,
"figureIsMeasured": false,
"source": "arxiv:2510.09031",
"sourceDate": "2025-10",
"insight": "~25% of saas & tech sites block at least one AI crawler of some kind — most often a training crawler, which does not affect whether assistants can cite them. (arxiv:2510.09031, 2025-10.)"
},
"recommendations": [
{
"id": "answer-time-crawler-swept-up-by-wildcard",
"title": "A catch-all rule is blocking crawlers it was never written for",
"description": "OAI-SearchBot and PerplexityBot are blocked by your `User-agent: *` rule, not by any rule naming them. A named group replaces the wildcard group rather than adding to it, so naming a crawler and allowing it lifts it out of that rule and changes nothing else you wrote.",
"priority": "high"
}
]
}
}Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_parameters · invalid_run_id · invalid_check_id | Bad request — the payload failed validation. |
| 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. |
| 429 | rate_limit_exceeded | Rate limit exceeded — retry with backoff. |
| 502 | bad_gateway | Upstream 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.