Skip to content

Working with citations

Grounded prose answers cite their sources inline with [N] markers (e.g. "Revenue grew 12% [1]."). The completed response attaches a structured url_citation annotation for every marker, so you don’t have to parse the prose to wire up tooltips, footnotes, or fact-checking.

Schema-based JSON responses instead return clean field values with an empty annotations array. Citation syntax is removed from grounded prose fields; numbers remain native JSON numbers. Strings constrained by enum, const, or format remain exact machine values without grounding. You can inspect field provenance by opening the request in Cemented’s report interface.

Annotations live on the assistant message’s output_text content part, beside that part’s text property. (The OpenAI SDK also exposes the combined text as the derived response.output_text convenience accessor.) For each [N], you get one entry:

{
"type": "url_citation",
"start_index": 14,
"end_index": 17,
"url": "https://nvidianews.nvidia.com/...",
"title": "NVIDIA Announces Q3 FY2026 Results",
"cited_text": "Revenue for the third quarter ended October 26 was $35.1 billion, up 94% from a year ago"
}
  • start_index / end_index are byte offsets of the [N] marker in the content part’s text value — slice them out to highlight or replace the marker.
  • url and title identify the source.
  • cited_text is the verbatim source excerpt that supports the cited claim.

Walk the annotations right-to-left so earlier offsets stay valid as you splice into the text.

from openai import OpenAI
client = OpenAI(api_key="ck-...", base_url="https://www.cemented.ai/v1")
response = client.responses.create(
model="sonnet",
input="What did NVIDIA report in its latest 10-Q?",
extra_body={"vendor_events": False},
)
text = response.output_text
annotations = [
a
for item in response.output
if item.type == "message"
for part in item.content
if part.type == "output_text"
for a in part.annotations
if a.type == "url_citation"
]
# Build a deduped footnote list and rewrite [N] markers to footnote
# numbers so the answer reads naturally.
seen, footnotes = {}, []
for a in annotations:
if a.url not in seen:
seen[a.url] = len(footnotes) + 1
footnotes.append((seen[a.url], a.title, a.url, a.cited_text))
# Replace from the right so earlier offsets stay valid.
for a in sorted(annotations, key=lambda x: -x.start_index):
n = seen[a.url]
text = text[: a.start_index] + f"[^{n}]" + text[a.end_index :]
print(text)
for n, title, url, excerpt in footnotes:
print(f'[^{n}]: [{title}]({url}) — "{excerpt}"')