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:

  • N is the sequential display number for the citation starting from 1
  • url is 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:

FieldTypeDescription
typestringAlways "url_citation"
urlstringThe source URL
start_indexintCharacter position where the citation starts in the response text
end_indexintCharacter position where the citation ends (exclusive)
titlestringThe 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 citation
  • end_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}")