Tools
Citations
The agent tools API provides two types of citation information: All Citations (a complete list of all sources encountered) and Inline Citations (markdown-style links embedded directly in the response text).
All Citations
The citations attribute on the response object provides a comprehensive list of URLs for all sources the agent encountered during its search process. This list is always returned by default — no additional configuration is required.
Citations are automatically collected from successful tool executions and provide full traceability of the agent's information sources. They are returned when the agentic request completes.
Note that not every URL in this list will necessarily be directly referenced in the final answer. The agent may examine a source during its research process and determine it is not sufficiently relevant to the user's query, but the URL will still appear in this list for transparency.
Python
response.citations
Output
[
'https://x.com/i/user/1912644073896206336',
'https://x.com/i/status/1975607901571199086',
'https://x.ai/news',
'https://docs.x.ai/developers/release-notes',
...
]
Inline Citations
Inline citations are markdown-style links (e.g., [[1]](https://x.ai/news)) inserted directly into the response text at the points where the model references sources. In addition to these visible links, structured metadata is available on the response object with precise positional information.
Important: Enabling inline citations does not guarantee that the model will cite sources on every answer. The model decides when and where to include citations based on the context and nature of the query.
Enabling Inline Citations
Inline citations are returned by default with the Responses API. For the xAI SDK, you can explicitly request them with include=["inline_citations"]:
import os
from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import web_search, x_search
client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
model="grok-4-1-fast-reasoning",
tools=[
web_search(),
x_search(),
],
include=["inline_citations"], # Enable inline citations
)
chat.append(user("What is xAI?"))
response = chat.sample()
# Access the response text (includes inline citation markdown)
print(response.content)
Markdown Citation Format
When inline citations are enabled, the model will insert markdown-style citation links directly into the response text:
Output
The latest announcements from xAI, primarily from their official X account (@xai) and website (x.ai/news), date back to November 19, 2025.[[1]](https://x.ai/news/)[[2]](https://x.ai/)[[3]](https://x.com/i/status/1991284813727474073)
When rendered as markdown, this displays as clickable links:
The latest announcements from xAI, primarily from their official X account (@xai) and website (x.ai/news), date back to November 19, 2025.[1][2][3]
The format is [[N]](url) where:
Nis the sequential display number for the citation starting from 1urlis the source URL
Citation numbering: Citation numbers always start from 1 and increment sequentially. If the same source is cited again later in the response, the original citation number will be reused.
Accessing Structured Inline Citation Data
Structured inline citation data provides precise positional information about each citation in the response text.
Response Format
Each citation annotation contains:
| Field | Type | Description |
|---|---|---|
type | string | Always "url_citation" |
url | string | The source URL |
start_index | int | Character position where the citation starts in the response text |
end_index | int | Character position where the citation ends (exclusive) |
title | string | The citation number (e.g., "1", "2") |
# After streaming or sampling completes, access the structured inline citations:
for citation in response.inline_citations:
print(f"Citation [{citation.id}]:")
print(f" Position: {citation.start_index} to {citation.end_index}")
# Check citation type
if citation.HasField("web_citation"):
print(f" Web URL: {citation.web_citation.url}")
elif citation.HasField("x_citation"):
print(f" X URL: {citation.x_citation.url}")
Output
Citation [1]:
Position: 37 to 76
Web URL: https://x.ai/news/grok-4-fast
Citation [2]:
Position: 124 to 171
X URL: https://x.com/xai/status/1234567890
Using Position Indices
The start_index and end_index values follow Python slice convention:
start_index: Character position of the first[of the citationend_index: Character position immediately after the closing)(exclusive)
Extract the exact citation markdown from the response text using a simple slice:
Python
content = response.content
for citation in response.inline_citations:
# Extract the markdown link from the response text
citation_text = content[citation.start_index:citation.end_index]
print(f"Citation text: {citation_text}")
Streaming Inline Citations
During streaming, inline citations are accumulated and available on the final response. The markdown links appear in real-time in the chunk.content as the model generates text:
Python
for response, chunk in chat.stream():
# Markdown links appear in chunk.content in real-time
if chunk.content:
print(chunk.content, end="", flush=True)
# Inline citations can also be accessed per-chunk during streaming
for citation in chunk.inline_citations:
print(f"\nNew citation: [{citation.id}]")
# After streaming, access all accumulated inline citations
print("\n\nAll inline citations:")
for citation in response.inline_citations:
url = ""
if citation.HasField("web_citation"):
url = citation.web_citation.url
elif citation.HasField("x_citation"):
url = citation.x_citation.url
print(f" [{citation.id}] {url}")