Tech & Trust Profile

Get latest tech & trust data

Changed on

Get the latest tech & trust profile data for all competitors in a project. Returns security headers, trust signals, technology stack, robots.txt analysis, AI access, and DNS infrastructure. Trust signals are a fixed set of 26 things we look for on a HOMEPAGE, in 5 categories — each category description names its exact membership and its denominator, so a count of 0 means none of THOSE signals was found and nothing more. Do not infer a signal a category does not list. 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. Two degradations are partial and worth distinguishing: shielded response headers null the security grade and score while the HTML-derived trust and tech counts stay real, and an unreadable robots.txt withholds the AI-access verdicts — under aiAccess the assistantAccess and modelTrainingAccess keys are OMITTED rather than nulled or emptied, because an empty array would claim we evaluated every assistant and none can reach the site. aiAccess itself is ABSENT on a check that carries no AI-access information — that is neither could_not_measure nor openness, so check the key exists before branching on it. Where it is present, check aiAccess.measurement.status before reading the verdicts: measured_no_policy_found is a real result — the site publishes no robots.txt, which under the standard allows every crawler — and could_not_measure is the only status that withholds verdicts. 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.

get/v1/projects/{projectId}/tech-trust

Request

  • Base URL: https://api.competlab.com
  • URL: https://api.competlab.com/v1/projects/{projectId}/tech-trust
  • Auth: API key in header CL-API-Key

Path parameters

projectIdstring required
Example:507f1f77bcf86cd799439011

Project ID

Query parameters

view'compact' | 'full'
Example:compact

How much of the response to return. compact: each crawler's catalog facts (its purpose and whether a robots.txt rule against it binds) are stated once in crawlerCatalog instead of on every verdict that names it. full: every row of every list, as stored — large, and meant for export rather than for reading. Omitted, the API's default view applies: compact on /v1.

Response

Example response

{
  "item": {
    "readingGuide": {
      "summary.pages": "Pages the engines RETRIEVED while answering, never pages they cited."
    },
    "lastUpdatedAt": "2026-03-15T10:00:00.000Z",
    "summary": {
      "competitorsChecked": 6,
      "competitorsSuccessful": 5,
      "customer": {
        "domain": "yoursite.com",
        "securityScore": 72,
        "securitySignalsAvailable": {
          "reason": "site_uses_behavioral_protection"
        },
        "trustSignalCount": 8,
        "techStackCount": 14,
        "techTrustAnalysisAvailable": {
          "reason": "tech_trust_fetch_failed"
        }
      },
      "topSecurityCompetitor": {
        "domain": "rival.com",
        "securityScore": 95
      },
      "topTrustCompetitor": {
        "domain": "other.com",
        "trustSignalCount": 15
      },
      "securityScoreGap": -23,
      "trustSignalGap": -7,
      "comparableCompetitors": 4
    },
    "competitors": [
      {
        "domain": "competitor.com",
        "securityHeaders": {
          "score": 85,
          "hsts": true,
          "csp": true,
          "xFrameOptions": true,
          "xContentTypeOptions": true,
          "signalsAvailable": {
            "reason": "site_uses_behavioral_protection"
          }
        },
        "trustSignals": {
          "totalCount": 10,
          "categories": {
            "compliance": 3,
            "reviews": 4,
            "socialProof": 2,
            "certifications": 1,
            "disclosures": 1
          }
        },
        "technologyStack": {
          "tech": [
            "React",
            "Next.js",
            "TypeScript"
          ],
          "growth": [
            "Google Analytics",
            "HubSpot"
          ],
          "engagement": [
            "Intercom",
            "Zendesk"
          ],
          "totalCount": 12,
          "partialDetection": {
            "reason": "site_uses_behavioral_protection"
          }
        },
        "robotsTxt": {
          "exists": true,
          "totalRules": 5,
          "robotsTxtAvailable": {
            "reason": "access_http_error_status"
          }
        },
        "aiAccess": {
          "measurement": {
            "status": "measured",
            "measuredAt": "2026-08-13T04:12:00.000Z",
            "couldNotMeasureReason": "access_http_error_status",
            "sourcesRead": {
              "robotsTxt": {
                "state": "read",
                "reason": "access_http_error_status",
                "httpStatusCode": 200
              },
              "pageMetaRobotsTag": {
                "state": "read",
                "reason": "access_http_error_status",
                "httpStatusCode": 200
              },
              "httpResponseHeaders": {
                "state": "read",
                "reason": "access_http_error_status",
                "httpStatusCode": 200
              }
            },
            "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."
              }
            ]
          },
          "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."
                }
              ]
            }
          ],
          "rulesThatMayNotWork": [
            {
              "userAgentInFile": "ChatGPT-User",
              "directiveInFile": "Disallow: /",
              "whyItMayNotWork": "operator_exempts_user_initiated_requests",
              "explanation": {
                "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."
              }
            }
          ],
          "rulesWithUnintendedScope": [
            {
              "userAgentInFile": "GPTBot",
              "kind": "escapes_restrictions_others_get",
              "affectedRules": [
                "Disallow: /use-cases/fintech",
                "Disallow: /events/*"
              ],
              "explanation": {
                "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."
              }
            }
          ],
          "additionalObservations": [
            {
              "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."
            }
          ],
          "crawlerCatalogVersion": "2026-08-13"
        },
        "dnsInfrastructure": {
          "emailProvider": "Google Workspace",
          "dnsProvider": "Cloudflare",
          "emailProviderAvailable": {
            "reason": "dns_lookup_failed"
          },
          "dnsProviderAvailable": {
            "reason": "dns_lookup_failed"
          }
        }
      }
    ]
  }
}

Changes

    • breaking

      the response property ////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property /////////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property //////////// became optional for the status

    • breaking

      the response property /////////////// became optional for the status

    • breaking

      the response property /////////////// became optional for the status

    • info

      added the new optional query request parameter view

    • info

      added the non-success response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • warning

      added the new not_found enum value to the / response property for the response status