The Citations API, quoted directly
Everything on this site is a direct generalization of Anthropic's real Citations API, documented at platform.claude.com/docs/en/build-with-claude/citations (mirrored in this repo at docs/docs/platform.claude.com/docs/en/build-with-claude/citations.md). This page is the citation trail.
1. What the feature does
"Claude is capable of providing detailed citations when answering questions about documents, helping you track and verify information sources in responses."
— citations.md, opening paragraph. Enabled per-document in the Messages API with "citations": {"enabled": true} on a document content block.
"All active models support citations, with the exception of Haiku 3."
— citations.md. This feature is also eligible for Zero Data Retention (ZDR) — when an organization has a ZDR arrangement, data sent through this feature is not stored after the API response returns.
2. Three location types, three field sets
"Citations reference specific locations in source documents. The format of these citations are dependent on the type of document being cited from."
— citations.md, "How citations work." The doc spells out exactly which fields belong to which type. This site's citations table copies every one of these field names, unmodified:
char_location — plain text documents
{
"type": "char_location",
"cited_text": "The exact text being cited", # not counted towards output tokens
"document_index": 0,
"document_title": "Document Title",
"start_char_index": 0, # 0-indexed
"end_char_index": 50, # exclusive
}
page_location — PDF documents
{
"type": "page_location",
"cited_text": "The exact text being cited", # not counted towards output tokens
"document_index": 0,
"document_title": "Document Title",
"start_page_number": 1, # 1-indexed
"end_page_number": 2, # exclusive
}
content_block_location — custom content documents
{
"type": "content_block_location",
"cited_text": "The exact text being cited", # not counted towards output tokens
"document_index": 0,
"document_title": "Document Title",
"start_block_index": 0, # 0-indexed
"end_block_index": 1, # exclusive
}
The doc's own summary table:
| Type | Best for | Chunking | Citation format |
|---|---|---|---|
| Plain text | Simple text documents, prose | Sentence | Character indices (0-indexed) |
| PDF files with text content | Sentence | Page numbers (1-indexed) | |
| Custom content | Lists, transcripts, special formatting, more granular citations | No additional chunking | Block indices (0-indexed) |
3. Indices are precise, and inconsistently indexed on purpose
"Document indices are 0-indexed from the list of all document content blocks in the request (spanning across all messages). Character indices are 0-indexed with exclusive end indices. Page numbers are 1-indexed with exclusive end page numbers. Content block indices are 0-indexed with exclusive end indices from the content list provided in the custom content document."
— citations.md, "Citation indices." Page numbers are the one 1-indexed field in the whole schema — this site's start_page_number/end_page_number columns preserve that quirk exactly rather than normalizing it away, because normalizing it would make a stored citation disagree with the API response it was copied from.
4. cited_text is free
"The cited_text field is provided for convenience and does not count towards output tokens... When passed back in subsequent conversation turns, cited_text is also not counted towards input tokens."
— citations.md, "Token costs." This is why cited_text is stored as a plain, un-truncated TEXT NOT NULL column here rather than something summarized or size-limited — the API itself treats the full quote as essentially free, so the durable record should too.
5. A full response, for context
A real Messages API response with citations enabled interleaves plain text blocks with cited text blocks, each citation carrying its own type and location fields:
{
"content": [
{"type": "text", "text": "According to the document, "},
{
"type": "text",
"text": "the grass is green",
"citations": [
{
"type": "char_location",
"cited_text": "The grass is green.",
"document_index": 0,
"document_title": "Example Document",
"start_char_index": 0,
"end_char_index": 20
}
]
}
]
}
Each object inside a citations array in a response like this is exactly one row in this site's citations table, plus source_site/source_url/context_note to say who made the citation durable and why.
What this site adds
The Citations API's own schema lives inside one Messages API response, scoped to one conversation turn. This site is the same schema factored out into a small typed primitive — citations in D1 — that any site in this ecosystem can create, list, and link to, so "a citation to exact locations in a source document" stops being a response format and becomes a live, queryable, cross-site record. See the live board.