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.

Configuring Inline Citations

Inline citation behavior differs between the Responses API and the xAI Python SDK (gRPC chat API).

The Responses API behaviour applies to the following clients:

  • cURL against /v1/responses
  • Python (OpenAI SDK)
  • JavaScript (AI SDK via xai.responses())
  • JavaScript (OpenAI SDK)
Responses API
(cURL, Python/JS OpenAI SDK, JS AI SDK)
xAI Python SDK
DefaultEnabled — response text may include [[N]](url) links without extra configurationDisabled — omit include, or do not pass "inline_citations"
EnableEnabled by default, no additional action needed.Pass include=["inline_citations"] to the chat.create() method
DisablePass include=["no_inline_citations"]Disabled by default

When inline citations are disabled, the response text will not contain any [[N]](url) markdown links. The annotations field on output_text content blocks may still be present, but annotations only list sources encountered during search — they will not have positional references into the response text.

Enabled (default for Responses API; opt-in for xAI Python SDK)

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.3",
    tools=[
        web_search(),
        x_search(),
    ],
    include=["inline_citations"],  # Enable inline citations (opt-in for xAI Python SDK)
)

chat.append(user("What is xAI?"))
response = chat.sample()

# Access the response text (includes inline citation markdown)
print(response.content)

Disabled (opt-out for Responses API; default for xAI Python SDK)

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("XAI_API_KEY"),
    base_url="https://api.x.ai/v1",
)

response = client.responses.create(
    model="grok-4.3",
    input=[
        {"role": "user", "content": "What is xAI?"}
    ],
    tools=[
        {"type": "web_search"},
    ],
    include=["no_inline_citations"],  # Disable inline citations
)

# Response text will not contain inline citation markdown
for item in response.output:
    if item.type == "message":
        for content in item.content:
            if content.type == "output_text":
                print(content.text)

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.

Image Embeds

When enable_image_search is enabled on the web_search tool, Grok may embed image results as Markdown images instead of numbered text citations:

Output

Here are images of Starship on the launch pad:
![Why the SpaceX Starship launch pad matters](https://www.astronomy.com/wp-content/uploads/2024/09/starship-test-flight-mission-scaled.jpg)

The format is ![alt](url) where:

  • alt is a short description or title for the image
  • url is the image source URL

Accessing Structured Inline Citation Data

Structured inline citation data provides precise positional information about each citation in the response text.

Response Format

When inline citations are enabled, each output_text content block includes an annotations array with structured citation metadata (URL, character offsets, and label):

JSON

{
  "created_at": 1781829888,
  "completed_at": 1781829888,
  "id": "5808284d-ae14-9981-9289-73515f67ebda",
  "max_output_tokens": null,
  "model": "grok-4.3",
  "object": "response",
  "output": [
    ...
    {
      "content": [
        {
          "type": "output_text",
          "text": "**xAI is an artificial intelligence company founded by Elon Musk in March 2023.** Its stated mission is to \"understand the universe\" by building advanced AI systems that accelerate human scientific discovery.[[1]](https://x.ai/company)\n\n### Key Details\n- **Flagship product**: Grok, a family of frontier AI models focused on reasoning, code, voice, image generation, and video. These are trained on massive infrastructure, including what the company describes as the world's largest supercluster (Colossus). Grok powers chatbots, APIs, and multimodal tools available via a unified API.[[2]](https://x.ai/)\n- **Current status (as of mid-2026)**: xAI operates as a subsidiary of SpaceX following an acquisition in February 2026. It is also connected to the X social platform (formerly Twitter), which xAI effectively became the parent of in 2025. The company has expanded into data centers and enterprise AI offerings (e.g., integrations with Amazon Bedrock and Databricks).[[3]](https://en.wikipedia.org/wiki/XAI_(company))\n- **Headquarters and team**: Based in the Stanford Research Park in Palo Alto, California. It was initially founded with a team of AI researchers and is led by Elon Musk as CEO.\n\nxAI positions itself as building maximally truth-seeking AI, distinct from other labs in its approach. Its official website (x.ai) highlights developer tools, API access, and ongoing model releases. Note that there is an unrelated blockchain/gaming project called Xai (xai.games), but the primary reference to \"xAI\" in this context is Musk's AI venture.[[4]](https://xai.games/)\n\nFor the latest updates, check x.ai or @xai on X.",
          "logprobs": [],
          "annotations": [
            {
              "type": "url_citation",
              "url": "https://x.ai/company",
              "start_index": 208,
              "end_index": 235,
              "title": "1"
            },
            {
              "type": "url_citation",
              "url": "https://x.ai/",
              "start_index": 585,
              "end_index": 605,
              "title": "2"
            },
            {
              "type": "url_citation",
              "url": "https://en.wikipedia.org/wiki/XAI_(company)",
              "start_index": 972,
              "end_index": 1022,
              "title": "3"
            },
            {
              "type": "url_citation",
              "url": "https://xai.games/",
              "start_index": 1555,
              "end_index": 1580,
              "title": "4"
            }
          ]
        }
      ],
      "id": "msg_5808284d-ae14-9981-9289-73515f67ebda",
      "role": "assistant",
      "type": "message",
      "status": "completed"
    }
  ],
  "parallel_tool_calls": true,
  "previous_response_id": null,
  "reasoning": {
    "effort": "low",
    "summary": "detailed"
  },
  ...
}

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 label; for text citations, this is the visible citation number (e.g., "1", "2")

Image embeds can also produce annotation metadata. The annotation title is not shown in the Markdown image.

# 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}")

Last updated: June 19, 2026