Citation Lexical Coverage
knowledge.citation_lexical_coverage
Overview
This measures wording overlap only; it never reports semantic support, truth or entailment. Send an answer (we segment it into claims) or the claims you segmented yourself, plus the sources they cite, and for each claim we resolve its citation markers, find the best matching window inside each cited source, and report how much of the claim's vocabulary that window covers. A citation aimed at the wrong paragraph or the wrong document shows up clearly. A fabrication that borrows the source's own words does not, and no lexical check can catch it. Markers are matched by a closed grammar rather than a pattern you supply, and a marker naming a source you did not send comes back as unresolved instead of being ignored. Neither your claims nor your sources are returned: you get ids, offsets and numbers, so the response stays small enough to store.
A citation is the part of a generated answer a reader is most likely to trust and least likely to check. Confirming that the cited text at least contains the claim's own vocabulary catches the common failure — a marker pointing at the wrong place — cheaply, deterministically, and without sending anything to a model.
Reliability
BEST_EFFORT because lexical overlap is not semantic evidence. meetsThreshold means only that the cited window contains the configured share of the claim's words. It cannot catch a plausible-sounding invention built from the source's vocabulary. The measurement itself is fully deterministic — the same claims, sources and settings always give the same verdicts and the same spans, and nothing here reads a clock or a random number. Terms are case-folded but never re-normalised, so every offset points into the text you submitted. Failures, none of which get better on their own: CITATION_INPUT_INVALID means you sent neither answer nor claims, the answer was empty or segmented into nothing, a claims entry was malformed or repeated an id, or an entry carried a property we do not accept; CITATION_SOURCE_INVALID means sources was empty or an entry was missing its id or text; CITATION_SOURCE_ID_DUPLICATE means two sources share an id, and the error says which position repeated it; CITATION_LIMIT_EXCEEDED means more than 500 sources or claims, an answer segmenting into more than 500 claims, a text over its character limit, more than 20000 claim-against-source comparisons, or a scan reaching 2000000 matched positions — check the answer in parts; CITATION_MARKER_GRAMMAR_UNSUPPORTED means markerGrammar or claimSegmentation named something that does not exist, and the accepted values come back with the error; CITATION_COVERAGE_PARAMETER_INVALID means a coverage setting was outside its range or named an unknown method.
Context footprint
The response carries ids, offsets, coverage scores and reason codes only, never your claims or sources. At most 500 claim entries come back, each with at most 64 citation entries. A successful call costs 1 execution credit.
When to use it
After a retrieval-augmented answer is produced and before it reaches a reader, or in review, when you want the evidence span for each claim.
When you need factual verification, when citations have to be discovered in free prose, or when the sources are not in your hands.
Powered by Squillify's own closed marker grammar and windowed lexical-overlap measurement. No model, no reranker and no third-party citation parser is involved.
Scope
Non-goals
- Does not judge whether a claim is true, only whether the cited text covers it
- Does not discover citations in prose — no URLs, DOIs or author-year forms
- Does not fetch a source or follow a link
- Does not compile a citation pattern you supply
- Does not return your claim text or your source text
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response does not contain submitted content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| answer | string | No | Required unless claims is provided. Answer of 1 to 200000 characters to segment and scan for markers. |
| claims | array | No | Required unless answer is provided. From 1 through 500 closed claims; when both arrive, claims wins. |
| sources | array | Yes | From 1 through 500 closed sources {id, text} that citations resolve against. |
| markerGrammar | string | No | How a citation looks; omit it for BRACKET_NUMERIC. |
| claimSegmentation | string | No | How an answer is split; omit it for SENTENCE, and it is ignored when you send claims. |
| coverage | object | No | Closed coverage measurement; omit it for TOKEN_OVERLAP at threshold 0.35, shingleSize 3 and spanWindowChars 2000. |
| requireCitation | boolean | No | Whether an uncited claim is an error; omit it for true. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| passesPolicy | boolean | Yes | True when no claim raised an error-severity issue. |
| claims | array | Yes | One closed claim report per checked claim in order, with ids, citations, scores and reasons rather than claim or source text. |
| coverageIssues | array | Yes | Claims that did not meet the coverage policy, each a closed {id, reasonCode} object. |
| summary | object | Yes | Closed counts and settings receipt with claimCount, meetsThresholdCount, coverageIssueCount, uncitedCount, unresolvedCitationCount, method, threshold, markerGrammar, claimSegmentation, spanWindowChars and truncated. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"knowledge.citation_lexical_coverage","input":{"answer":"Refunds take 30 days. [1]","sources":[{"id":"policy","text":"Refunds take 30 days from the charge."}],"coverage":{"method":"TOKEN_OVERLAP","threshold":0.35}}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("knowledge.citation_lexical_coverage", {"answer":"We refund an unused subscription within 30 days of the charge. [1] Every refund is paid in the original currency. [2]","sources":[{"id":"policy","text":"Refunds. We refund an unused subscription within 30 days of the charge, provided the original order id is supplied."},{"id":"shipping","text":"Shipping. Parcels leave the warehouse within two working days."}],"coverage":{"threshold":0.5}});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| CITATION_INPUT_INVALID | 400 | No | The request payload failed this skill's input validation. |
| CITATION_SOURCE_INVALID | 400 | No | The request payload failed this skill's input validation. |
| CITATION_SOURCE_ID_DUPLICATE | 400 | No | The request payload failed this skill's input validation. |
| CITATION_LIMIT_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
| CITATION_MARKER_GRAMMAR_UNSUPPORTED | 400 | No | The skill does not support the requested variant. |
| CITATION_COVERAGE_PARAMETER_INVALID | 400 | No | The request payload failed this skill's input validation. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not judge whether a claim is true, only whether the cited text covers it
- Does not discover citations in prose — no URLs, DOIs or author-year forms
- Does not fetch a source or follow a link
- Does not compile a citation pattern you supply
- Does not return your claim text or your source text
- Fact-checking a claim against the world rather than against a source
- Extracting citations from free prose, which text.extract_citations handles
- Detecting a fabrication written in the source's own vocabulary
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "knowledge.citation_lexical_coverage",
"input": {
"answer": "We refund an unused subscription within 30 days of the charge. [1] Every refund is paid in the original currency. [2]",
"sources": [
{
"id": "policy",
"text": "Refunds. We refund an unused subscription within 30 days of the charge, provided the original order id is supplied."
},
{
"id": "shipping",
"text": "Shipping. Parcels leave the warehouse within two working days."
}
],
"coverage": {
"threshold": 0.5
}
}
}Examples
An answer segmented into sentences, one claim above threshold and one below
{
"answer": "We refund an unused subscription within 30 days of the charge. [1] Every refund is paid in the original currency. [2]",
"sources": [
{
"id": "policy",
"text": "Refunds. We refund an unused subscription within 30 days of the charge, provided the original order id is supplied."
},
{
"id": "shipping",
"text": "Shipping. Parcels leave the warehouse within two working days."
}
],
"coverage": {
"threshold": 0.5
}
}{
"summary": {
"claimCount": 2,
"meetsThresholdCount": 1,
"coverageIssueCount": 1,
"uncitedCount": 0,
"unresolvedCitationCount": 0,
"method": "TOKEN_OVERLAP",
"threshold": 0.5,
"markerGrammar": "BRACKET_NUMERIC",
"claimSegmentation": "SENTENCE",
"spanWindowChars": 2000,
"truncated": false
},
"claims": [
{
"id": "claim-1",
"citations": [
{
"reference": "1",
"resolved": true,
"sourceId": "policy"
}
],
"meetsThreshold": true,
"bestSourceId": "policy",
"bestSpan": {
"start": 9,
"end": 70
},
"coverageScore": 0.9167,
"reasonCode": "MEETS_THRESHOLD",
"severity": "NONE"
},
{
"id": "claim-2",
"citations": [
{
"reference": "2",
"resolved": true,
"sourceId": "shipping"
}
],
"meetsThreshold": false,
"bestSourceId": "shipping",
"bestSpan": {
"start": 24,
"end": 27
},
"coverageScore": 0.1111,
"reasonCode": "BELOW_THRESHOLD",
"severity": "ERROR"
}
],
"passesPolicy": false,
"coverageIssues": [
{
"id": "claim-2",
"reasonCode": "BELOW_THRESHOLD"
}
]
}Claims you segmented yourself, with one citation that resolves to nothing
{
"markerGrammar": "BRACKET_ID",
"claims": [
{
"text": "Partial months are not refunded.",
"citations": [
"terms"
],
"id": "c1"
},
{
"text": "Refunds are approved automatically.",
"citations": [
"missing-source"
],
"id": "c2"
}
],
"sources": [
{
"id": "terms",
"text": "Partial months are not refunded. A refund needs the original order id."
}
]
}{
"summary": {
"claimCount": 2,
"meetsThresholdCount": 1,
"coverageIssueCount": 1,
"uncitedCount": 0,
"unresolvedCitationCount": 1,
"method": "TOKEN_OVERLAP",
"threshold": 0.35,
"markerGrammar": "BRACKET_ID",
"claimSegmentation": "SENTENCE",
"spanWindowChars": 2000,
"truncated": false
},
"claims": [
{
"id": "c1",
"citations": [
{
"reference": "terms",
"resolved": true,
"sourceId": "terms"
}
],
"meetsThreshold": true,
"bestSourceId": "terms",
"bestSpan": {
"start": 0,
"end": 31
},
"coverageScore": 1,
"reasonCode": "MEETS_THRESHOLD",
"severity": "NONE"
},
{
"id": "c2",
"citations": [
{
"reference": "missing-source",
"resolved": false
}
],
"meetsThreshold": false,
"coverageScore": 0,
"reasonCode": "CITATION_UNRESOLVED",
"severity": "ERROR"
}
],
"passesPolicy": false,
"coverageIssues": [
{
"id": "c2",
"reasonCode": "CITATION_UNRESOLVED"
}
]
}Recommended use cases
- Catch a generated answer citing the wrong paragraph of the right document
- Gate a retrieval-augmented answer on a declared lexical-coverage threshold
- Show a reviewer the exact source span behind each cited claim
Avoid for
- Fact-checking a claim against the world rather than against a source
- Extracting citations from free prose, which text.extract_citations handles
- Detecting a fabrication written in the source's own vocabulary
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.