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:
| View | What it proves | Why it matters |
|---|---|---|
| Coverage | How many first-party visitors match the saved filter. | You know whether the result is large and fresh enough to use. |
| Lane separation | How much bot-classed traffic was measured separately from humans. | Crawlers, monitors, previews, and automation do not become "people" by accident. |
| Match readiness | How 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
- Pick the site and date range:
24h,7d,30d, or90d. - Leave filters empty for site-wide proof, or add approved saved filters for a narrower result.
- Check
coverage.segmentVisitorsfor the matched human-visitor count. - Check
coverage.botSuppressedVisitorsandcoverage.botRateto make sure non-human traffic was measured separately. - Check
answerEngine.topCrawledPagesagainstanswerEngine.topHumanPagesto find coverage gaps. - 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
| Field | Plain-English meaning |
|---|---|
coverage.totalVisitors | All first-party visitors in range, before lane separation. |
coverage.humanVisitors | Visitors eligible for human analysis after bot-classed traffic is suppressed. |
coverage.segmentVisitors | Human visitors that matched the supplied filters, or all human visitors when filters are empty. |
coverage.botSuppressedVisitors | Non-human visitors measured separately from the human result. |
coverage.matchablePeople | Matched visitors with a first-party identifier useful for internal matching checks. |
coverage.hashedIdentifierPeople | Matched visitors with hashed email or phone available. |
coverage.consentReadyIdentityPeople | Matched visitors that have consent-safe hashed identifiers available for the API's readiness output. |
coverage.coverageScore | Matched human visitors compared with the human visitors in scope. |
coverage.confidenceScore | Volume plus specificity; higher means the proof has stronger evidence. |
coverage.matchabilityScore | Share of the result with matchable identity. |
coverage.identityReadinessScore | Share of the result with enough consent-safe identity signal for the API's readiness output. |
coverage.freshnessScore | How 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
- Raw email and phone values are not exposed in Signals coverage proof.
- Dashboard authentication and normal site membership checks apply.
- Bot-classed visitors remain visible in proof and coverage, but stay out of the human result.