In short. Collect every search-results event, parse markers from accumulated text, match result identifiers to URLs, and validate links before display.
Definition: Streaming citation parsing collects source records and answer text from Perplexity's Agent API, then matches inline reference markers to source records through their
idfield. As of 17 October 2026, the official cookbook demonstrates this with numbered markers such as[1]for thefastpreset.
Key facts
- Perplexity's streaming citation cookbook uses
response.reasoning.search_resultsfor source batches andresponse.output_text.deltafor answer fragments. - The Output Control documentation enables streaming with
stream=Truein Python orstream: truein TypeScript. - The Web Search documentation identifies each result's
idandurlas the source of truth for citations and says inline markers depend on the prompt.
How are sources collected across the stream?
Perplexity's cookbook describes server-sent events, a stream of named events carrying results or generated text. Each search produces a source batch. Multi-step presets can run several searches within a response, sharing a citation identifier space. Each batch is appended to the collected results.
The following Python excerpt adapts the cookbook's collection and parsing logic. It operates on an existing stream and retains the complete answer for reference extraction:
import re
full_content = ""
search_results = []
for event in stream:
if event.type == "response.reasoning.search_results":
search_results.extend(event.results or [])
if event.type == "response.output_text.delta":
full_content += event.delta
url_map = {r["id"]: r["url"] for r in search_results}
used_refs = sorted(set(
int(m) for m in re.findall(r"\[(\d+)\]", full_content)
))
resolved = {ref: url_map[ref] for ref in used_refs if ref in url_map}
This follows the cookbook's dictionary-based streaming example. Its separate example using the Perplexity SDK accesses result properties as r.id and r.url.
How are reference markers turned into links?
The cookbook's progressive display example scans accumulated text because individual fragments can split a marker across chunks. Parsing only the latest fragment can miss a reference. Its set of reference numbers also prevents repeated occurrences of the same marker from increasing the live source counter.
After collection, the parser matches each number to a result's id. The cookbook's formatting function replaces matching markers with Markdown links and appends a reference list using the corresponding titles and URLs. If a marker has no matching result, its guidance is to display the number without a link. An unresolved marker therefore calls for checking that every source batch has been collected.
For a website citation report, the cookbook's final summary supplies distinct counts: sources found in the search results and unique reference identifiers used in the answer. These counts can differ.
What does URL validation check?
The cookbook's validation example checks URL structure before testing reachability. Its Python function accepts http or https with a nonempty network location. It then sends a HEAD request to check reachability, follows redirects, and applies a timeout of 5.0 seconds. The example marks a returned status below 400 as valid and reports malformed URLs and timeouts separately.
For many sources, the same guide recommends concurrency limits on validation requests. It also instructs applications to use URLs returned in search_results, because URLs generated in answer text can be hallucinated.
Related terms
- How do Perplexity Agent API source identifiers map to cited URLs?
- How do I request inline citation markers from Perplexity's Agent API?
- Citation tracking
- How do I check whether a citation supports an answer's claim?
FAQ
Does the same expression parse every preset's citations?
The cookbook's preset guidance distinguishes fast markers such as [1] from low markers such as [web:1]. You need a parser matching the selected format; the numeric-only expression above handles the former.
How can I request markers when the answer omits them?
The Web Search documentation suggests explicitly asking for inline bracketed citations, with one source per bracket, such as [1][2]. You can still obtain source records from search_results when the answer omits markers.
Sources
- Perplexity, "Streaming Citation Parsing", undated
- Perplexity, "Output Control", undated
- Perplexity, "Web Search", undated
Check how a page reads to answer engines. Open the GEO score analyzer