Signals Coverage Proof

Signals coverage proof answers one practical question before you use a visitor lane or saved filter:

Do we have enough real people in this result, and did we keep non-human traffic measured separately?

Use it before making site changes, reporting coverage, planning content, or deciding whether a result is large enough to act on. It keeps three views side by side:

ViewWhat it provesWhy it matters
CoverageHow many first-party visitors match the saved filter.You know whether the result is large and fresh enough to use.
Lane separationHow much bot-classed traffic was measured separately from humans.Crawlers, monitors, previews, and automation do not become "people" by accident.
Match readinessHow many matched visitors have first-party identity signals.You can see whether the result has enough first-party signal without exposing raw email or phone values.

The dashboard Signals workspace (Intelligence → Signals at einstein.clickstream.com/intelligence/signals) runs coverage proof, mints the csst_ token for the live Signals Feed, and inspects live visitor contexts. The same dashboard-session APIs back it — POST /api/signals/proof and GET /api/signals/stream-token — and can be called directly from a controlled workflow around the dashboard session, as below.

Beginner Workflow

  1. Pick the site and date range: 24h, 7d, 30d, or 90d.
  2. Leave filters empty for site-wide proof, or add approved saved filters for a narrower result.
  3. Check coverage.segmentVisitors for the matched human-visitor count.
  4. Check coverage.botSuppressedVisitors and coverage.botRate to make sure non-human traffic was measured separately.
  5. Check answerEngine.topCrawledPages against answerEngine.topHumanPages to find coverage gaps.
  6. Turn the findings into a site, content, or instrumentation task. Do not expose the internal filter recipe to end users.

Copy-Paste: Request Proof

Run this from a dashboard-authenticated admin page or server route. The browser must already have a valid dashboard session cookie.

async function requestCoverageProof() {
  const response = await fetch('/api/signals/proof', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({
      siteId: 'site_acd434d3',
      name: 'Docs coverage check',
      filters: [],
      topicIds: [],
      range: '30d',
    }),
  });

  if (!response.ok) {
    throw new Error(`Proof failed: ${response.status}`);
  }

  return response.json();
}

Reading The Response

{
  "proof": {
    "generatedAt": 1778880000000,
    "name": "Docs coverage check",
    "siteId": "site_acd434d3",
    "siteNames": ["Example Site"],
    "filtersEvaluated": 0,
    "topicIdsEvaluated": 0,
    "coverage": {
      "range": "30d",
      "rangeStart": 1776288000000,
      "rangeEnd": 1778880000000,
      "specificity": "site_scope",
      "measuredAgainst": "first_party_visitors",
      "totalVisitors": 1420,
      "humanVisitors": 1310,
      "segmentVisitors": 1310,
      "botSuppressedVisitors": 110,
      "identifiedPeople": 410,
      "humanEvidencePeople": 1310,
      "matchablePeople": 390,
      "hashedIdentifierPeople": 210,
      "consentReadyIdentityPeople": 180,
      "totalEvents": 6200,
      "humanEvents": 5710,
      "botEvents": 490,
      "botRate": 7.9,
      "coverageScore": 100,
      "confidenceScore": 90,
      "matchabilityScore": 30,
      "identityReadinessScore": 14,
      "freshnessScore": 100
    },
    "answerEngine": {
      "aiAgentEvents": 16,
      "aiAgentVisitors": 9,
      "searchCrawlerEvents": 224,
      "searchCrawlerVisitors": 41,
      "topCrawledPages": [
        { "path": "/docs/getting-started", "events": 48, "visitors": 18, "avgBotScore": 84 }
      ],
      "topHumanPages": [
        { "path": "/account/settings", "events": 220, "visitors": 96 }
      ],
      "botRegistry": [
        { "name": "Known crawler", "category": "search_crawler", "events": 80, "visitors": 15, "pagesVisited": 9 }
      ],
      "recommendations": [
        {
          "type": "metadata",
          "priority": "high",
          "message": "High-human pages are not showing bot coverage yet: /account/settings."
        }
      ]
    },
    "readiness": {
      "coverageReady": true,
      "identityCoverageReady": true,
      "consentBound": true,
      "recommendedUse": "hashed_identifiers",
      "blockedReasons": [],
      "readyPeople": 180
    }
  }
}

What The Scores Mean

FieldPlain-English meaning
coverage.totalVisitorsAll first-party visitors in range, before lane separation.
coverage.humanVisitorsVisitors eligible for human analysis after bot-classed traffic is suppressed.
coverage.segmentVisitorsHuman visitors that matched the supplied filters, or all human visitors when filters are empty.
coverage.botSuppressedVisitorsNon-human visitors measured separately from the human result.
coverage.matchablePeopleMatched visitors with a first-party identifier useful for internal matching checks.
coverage.hashedIdentifierPeopleMatched visitors with hashed email or phone available.
coverage.consentReadyIdentityPeopleMatched visitors that have consent-safe hashed identifiers available for the API's readiness output.
coverage.coverageScoreMatched human visitors compared with the human visitors in scope.
coverage.confidenceScoreVolume plus specificity; higher means the proof has stronger evidence.
coverage.matchabilityScoreShare of the result with matchable identity.
coverage.identityReadinessScoreShare of the result with enough consent-safe identity signal for the API's readiness output.
coverage.freshnessScoreHow recently matched visitors were seen.

AI/Search Coverage View

Use answerEngine to compare what machines can see with what humans actually use.

function findDiscoveryGaps(proof) {
  const crawled = new Set(proof.answerEngine.topCrawledPages.map((page) => page.path));
  return proof.answerEngine.topHumanPages
    .filter((page) => !crawled.has(page.path))
    .map((page) => ({
      path: page.path,
      action: 'Add structured content, metadata, and edge capture coverage.',
    }));
}

This is useful for content and SEO work: a page with human use but no crawler coverage is a practical improvement target.

Hashed-Identifier Readiness

Use readiness to decide whether the result is strong enough for on-site decisions, reporting, or content planning:

function hasEnoughIdentitySignal(proof) {
  return (
    proof.readiness.identityCoverageReady &&
    proof.coverage.consentReadyIdentityPeople > 0 &&
    proof.coverage.botSuppressedVisitors >= 0
  );
}

If blockedReasons includes no_hashed_identifiers, the result can still be useful for on-site decisions and content planning, but it is not strong enough for identity-backed reporting. If it includes missing_marketing_consent, fix consent capture before relying on identity-style workflows; that reason name mirrors the SDK consent category.

Privacy Notes

See Also