Claude citations: char_location, page_location and more
Set citations: {"enabled": true} on every document block in the request. Claude then returns text blocks with a citations list, where each entry carries the exact cited_text and a location: character offsets for plain text, page numbers for PDFs, or block indices for custom content.
How it works
Citations must be enabled on all or none of the documents in a request. The API chunks each document to set the smallest unit Claude can cite. Plain text and PDFs are chunked into sentences. Custom content documents are used as-is, so each content block you supply is one citable unit, which suits transcripts and bullet lists.
The optional title and context fields are passed to the model but are never cited from. Only text citations are supported, so a scanned PDF with no extractable text cannot be cited, even though Claude can still read the pages.
Reading the location
Plain text returns char_location with start_char_index and end_char_index: 0-indexed, end exclusive. PDFs return page_location with start_page_number and end_page_number: 1-indexed, end exclusive. Custom content returns content_block_location with start_block_index and an end index: 0-indexed, end exclusive. The document index is 0-indexed across all document blocks in the request, spanning all messages.
So a PDF citation with start_page_number 5 and end_page_number 6 points at page 5 only. When streaming, citations arrive as citations_delta events, so a handler that reads only text_delta drops them.
Cost and limits
Enabling citations adds a small number of input tokens for system prompt additions and chunking. The cited_text field does not count toward output tokens, and it is not counted as input when you pass it back in later turns. You can cache the source documents with cache_control, but not the citation blocks.
Citations cannot be combined with structured outputs. If citations are enabled on any document or search_result block and the request also sets output_config.format, the API returns a 400.
Where the exam catches people
Believing PDF page numbers are 0-indexed like character offsets: page_location page numbers are 1-indexed, with an exclusive end.
Believing quoted text is billed twice: cited_text counts toward neither output tokens nor input tokens on replay.
Believing you can enable citations on just some documents: it is all or none within a request.
Believing citations and output_config.format can be used together: the request is rejected with a 400.