tryAGI.Xai 0.0.0-dev.23

Prefix Reserved
This is a prerelease version of tryAGI.Xai.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package tryAGI.Xai --version 0.0.0-dev.23
                    
NuGet\Install-Package tryAGI.Xai -Version 0.0.0-dev.23
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="tryAGI.Xai" Version="0.0.0-dev.23" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="tryAGI.Xai" Version="0.0.0-dev.23" />
                    
Directory.Packages.props
<PackageReference Include="tryAGI.Xai" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add tryAGI.Xai --version 0.0.0-dev.23
                    
#r "nuget: tryAGI.Xai, 0.0.0-dev.23"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package tryAGI.Xai@0.0.0-dev.23
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=tryAGI.Xai&version=0.0.0-dev.23&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=tryAGI.Xai&version=0.0.0-dev.23&prerelease
                    
Install as a Cake Tool

Xai

Nuget package dotnet License: MIT Discord

Disclaimer: This package is not affiliated with, endorsed by, or sponsored by xAI. xAI and Grok are trademarks of xAI Corp.

Features 🔥

  • Fully generated C# SDK based on a hand-curated xAI OpenAPI specification using AutoSDK
  • Same day update to support new features
  • All modern .NET features - nullability, trimming, NativeAOT, etc.
  • Comprehensive API coverage:
    • Chat completions (streaming, tool calling, reasoning, structured output, deferred)
    • Vision (image input with Grok Vision models)
    • Image generation & editing (Grok Imagine)
    • Video generation with polling helper
    • Text-to-speech (multiple voices)
    • Realtime voice WebSocket client (bidirectional audio/text, VAD, tools)
    • Embeddings, Batches, Files, Collections

Usage

using Xai;

using var client = new XaiClient(apiKey);

Chat Completion

var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is the meaning of life?",
        },
    ]);

Console.WriteLine(response.Choices![0].Message?.Content);

Streaming

await foreach (var chunk in client.Chat.CreateChatCompletionAsStreamAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Tell me a short story.",
        },
    ]))
{
    Console.Write(chunk.Choices?[0].Delta?.Content);
}

Tool Calling

using System.Text.Json;

var tools = new List<ChatCompletionTool>
{
    new ChatCompletionTool
    {
        Type = ChatCompletionToolType.Function,
        Function = new FunctionDefinition
        {
            Name = "get_weather",
            Description = "Get the current weather for a location.",
            Parameters = JsonSerializer.Deserialize<JsonElement>("""
                {
                    "type": "object",
                    "properties": {
                        "location": { "type": "string", "description": "The city name." }
                    },
                    "required": ["location"]
                }
                """),
        },
    },
};

var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is the weather in San Francisco?",
        },
    ],
    tools: tools,
    toolChoice: new OneOf<CreateChatCompletionRequestToolChoice?, ChatCompletionNamedToolChoice>(
        CreateChatCompletionRequestToolChoice.Auto));

var toolCall = response.Choices![0].Message!.ToolCalls![0];
Console.WriteLine($"{toolCall.Function.Name}({toolCall.Function.Arguments})");

Reasoning

var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is 15 * 37? Think step by step.",
        },
    ],
    reasoningEffort: CreateChatCompletionRequestReasoningEffort.High);

Console.WriteLine(response.Choices![0].Message?.ReasoningContent); // reasoning trace
Console.WriteLine(response.Choices![0].Message?.Content);          // final answer

Structured Output (JSON Schema)

var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Extract the capital of France.",
        },
    ],
    responseFormat: new ResponseFormat
    {
        Type = ResponseFormatType.JsonSchema,
        JsonSchema = new ResponseFormatJsonSchema
        {
            Name = "capital_response",
            Strict = true,
            Schema = new
            {
                type = "object",
                properties = new
                {
                    country = new { type = "string" },
                    capital = new { type = "string" },
                },
                required = new[] { "country", "capital" },
                additionalProperties = false,
            },
        },
    });

Console.WriteLine(response.Choices![0].Message?.Content);
// {"country":"France","capital":"Paris"}

Vision (Image Input)

var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-2-vision",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = new OneOf<string, IList<ChatCompletionContentPart>>(
                new List<ChatCompletionContentPart>
                {
                    new ChatCompletionContentPart
                    {
                        Type = ChatCompletionContentPartType.Text,
                        Text = "Describe this image in one sentence.",
                    },
                    new ChatCompletionContentPart
                    {
                        Type = ChatCompletionContentPartType.ImageUrl,
                        ImageUrl = new ChatCompletionContentPartImageUrl
                        {
                            Url = "https://example.com/image.png",
                        },
                    },
                }),
        },
    ]);

Console.WriteLine(response.Choices![0].Message?.Content);

Image Generation

var response = await client.Images.CreateImageAsync(
    model: "grok-imagine-image",
    prompt: "A futuristic cityscape at sunset");

Console.WriteLine(response.Data![0].Url);

Image Editing

var response = await client.Images.CreateImageEditAsync(
    model: "grok-2-image",
    prompt: "Add a red hat to the person in the image",
    image: new ImageInput
    {
        Url = "https://example.com/photo.png",
    });

Console.WriteLine(response.Data![0].Url);

Video Generation

var status = await client.GenerateAndWaitAsync(
    new CreateVideoRequest
    {
        Model = "grok-imagine-video",
        Prompt = "A gentle ocean wave rolling onto a sandy beach at sunset",
        Duration = 3,
        Resolution = CreateVideoRequestResolution.x480p,
    },
    pollingInterval: TimeSpan.FromSeconds(10),
    timeout: TimeSpan.FromMinutes(5));

Console.WriteLine(status.Video?.Url);

Text-to-Speech

byte[] audioBytes = await client.Audio.CreateSpeechAsync(
    model: "tts-1",
    input: "Hello from xAI!",
    voice: CreateSpeechRequestVoice.Eve);

File.WriteAllBytes("output.mp3", audioBytes);

Realtime Voice

using var voiceClient = new RealtimeVoiceClient(apiKey);
await voiceClient.ConnectAsync();

// Configure session
await voiceClient.SendEventAsync(RealtimeClientEvent.SessionUpdate(new RealtimeSessionConfig
{
    Voice = "Eve",
    Instructions = "You are a helpful assistant.",
    Modalities = ["text", "audio"],
    TurnDetection = new RealtimeTurnDetection
    {
        Type = "server_vad",
        Threshold = 0.85,
        SilenceDurationMs = 500,
    },
}));

// Send a text message and request response
await voiceClient.SendEventAsync(RealtimeClientEvent.UserMessage("Say hello!"));
await voiceClient.SendEventAsync(RealtimeClientEvent.CreateResponse(["text"]));

// Receive events
await foreach (var serverEvent in voiceClient.ReceiveUpdatesAsync(cancellationToken))
{
    if (serverEvent.IsAudioTranscriptDelta)
        Console.Write(serverEvent.Delta);
    else if (serverEvent.IsResponseDone)
        break;
}

Responses API

// Create a response (stored server-side)
var response = await client.Responses.CreateResponseAsync(
    model: "grok-3-mini",
    input: "What is 2+2? Answer with just the number.");

Console.WriteLine(response.Output);

// Retrieve a stored response
var retrieved = await client.Responses.GetResponseAsync(response.Id!);

// Delete a stored response
await client.Responses.DeleteResponseAsync(response.Id!);

Deferred Completions

// Submit a deferred request (processed asynchronously)
var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Explain what a quasar is in two sentences.",
        },
    ],
    deferred: true);

// Poll for the result
var result = await client.Chat.GetDeferredCompletionAsync(response.Id!);
Console.WriteLine(result.Choices![0].Message?.Content);

// Or use the convenience helper that submits + polls automatically:
var completed = await client.CreateDeferredAndWaitAsync(
    new CreateChatCompletionRequest
    {
        Model = "grok-3-mini",
        Messages = [
            new ChatCompletionMessage
            {
                Role = ChatCompletionMessageRole.User,
                Content = "Write a haiku about programming.",
            },
        ],
    },
    pollingInterval: TimeSpan.FromSeconds(5),
    timeout: TimeSpan.FromMinutes(2));

Console.WriteLine(completed.Choices![0].Message?.Content);

Microsoft.Extensions.AI

This SDK covers xAI-specific endpoints (images, video, realtime, etc.). For standard IChatClient/IEmbeddingGenerator support, use CustomProviders.XAi() from the tryAGI.OpenAI package:

using tryAGI.OpenAI;
using Microsoft.Extensions.AI;

using var api = CustomProviders.XAi("API_KEY");
IChatClient chatClient = api;

var response = await chatClient.GetResponseAsync("Hello from Grok!");
Console.WriteLine(response.Text);

Chat Completion

Send a simple chat completion request.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Create a chat completion with a simple user message.
var response = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Say 'Hello, World!' and nothing else.",
        },
    ]);

Console.WriteLine(response.Choices![0].Message?.Content);

Chat Completion Streaming

Stream a chat completion response token by token.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Stream the response and print each chunk as it arrives.
var chunks = new List<CreateChatCompletionStreamResponse>();
await foreach (var chunk in client.Chat.CreateChatCompletionAsStreamAsync(
    model: modelId,
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Tell me a short story.",
        },
    ]))
{
    chunks.Add(chunk);
    Console.Write(chunk.Choices?[0].Delta?.Content);
}

Tool Calling

Use function tools to let the model call external functions.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Define a function tool with a JSON Schema for its parameters.
var tools = new List<ChatCompletionTool>
{
    new ChatCompletionTool
    {
        Type = ChatCompletionToolType.Function,
        Function = new FunctionDefinition
        {
            Name = "get_weather",
            Description = "Get the current weather for a location.",
            Parameters = JsonSerializer.Deserialize<JsonElement>("""
                {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name."
                        }
                    },
                    "required": ["location"]
                }
                """),
        },
    },
};

// Send a message that should trigger the tool call.
var response = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is the weather in San Francisco?",
        },
    ],
    tools: tools,
    toolChoice: new OneOf<CreateChatCompletionRequestToolChoice?, ChatCompletionNamedToolChoice>(
        CreateChatCompletionRequestToolChoice.Auto));

var choice = response.Choices![0];

// Inspect the tool call the model wants to make.
var toolCall = choice.Message!.ToolCalls![0];

Console.WriteLine($"{toolCall.Function.Name}({toolCall.Function.Arguments})");

Parallel Tool Calls

Call multiple tools in parallel within a single response.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Define multiple tools that the model can call simultaneously.
var tools = new List<ChatCompletionTool>
{
    new ChatCompletionTool
    {
        Type = ChatCompletionToolType.Function,
        Function = new FunctionDefinition
        {
            Name = "get_weather",
            Description = "Get the current weather for a location.",
            Parameters = JsonSerializer.Deserialize<JsonElement>("""
                {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name."
                        }
                    },
                    "required": ["location"]
                }
                """),
        },
    },
    new ChatCompletionTool
    {
        Type = ChatCompletionToolType.Function,
        Function = new FunctionDefinition
        {
            Name = "get_time",
            Description = "Get the current time for a timezone.",
            Parameters = JsonSerializer.Deserialize<JsonElement>("""
                {
                    "type": "object",
                    "properties": {
                        "timezone": {
                            "type": "string",
                            "description": "The IANA timezone name."
                        }
                    },
                    "required": ["timezone"]
                }
                """),
        },
    },
};

// Enable `parallelToolCalls` so the model can invoke multiple tools at once.
var response = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages:
    [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What's the weather in Tokyo and what time is it in America/New_York?",
        },
    ],
    tools: tools,
    parallelToolCalls: true,
    toolChoice: new OneOf<CreateChatCompletionRequestToolChoice?, ChatCompletionNamedToolChoice>(
        CreateChatCompletionRequestToolChoice.Auto));

var choice = response.Choices![0];
    "parallel tool calls should produce at least 2 tool calls");

var functionNames = choice.Message.ToolCalls.Select(tc => tc.Function.Name).ToList();

foreach (var tc in choice.Message.ToolCalls)
{
    Console.WriteLine($"{tc.Function.Name}({tc.Function.Arguments})");
}

Reasoning

Use reasoning effort to get step-by-step thinking from grok-3-mini.

var client = new XaiClient(apiKey);

// Enable reasoning with high effort to get a thinking trace alongside the answer.
var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-3-mini",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is 15 * 37? Think step by step.",
        },
    ],
    reasoningEffort: CreateChatCompletionRequestReasoningEffort.High);

var message = response.Choices![0].Message;
    "grok-3-mini with high reasoning effort should return reasoning content");

Console.WriteLine($"Reasoning: {message.ReasoningContent}");
Console.WriteLine($"Answer: {message.Content}");

Seed Determinism

Use a fixed seed and temperature=0 for reproducible output.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

const int seed = 42;
const string prompt = "What is the capital of Japan? Answer with just the city name.";

// Send the same request twice with the same seed and temperature=0.
var response1 = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages:
    [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = prompt,
        },
    ],
    seed: seed,
    temperature: 0);

var response2 = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages:
    [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = prompt,
        },
    ],
    seed: seed,
    temperature: 0);

var content1 = response1.Choices![0].Message?.Content;
var content2 = response2.Choices![0].Message?.Content;

// With the same seed and temperature=0, outputs should be identical.
    "same seed and temperature=0 should produce deterministic output");

Console.WriteLine($"Response 1: {content1}");
Console.WriteLine($"Response 2: {content2}");

Vision

Analyze an image using a vision-capable model.

var client = new XaiClient(apiKey);

// Send both text and an image URL as a multi-part content message.
var response = await client.Chat.CreateChatCompletionAsync(
    model: "grok-2-vision",
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = new OneOf<string, IList<ChatCompletionContentPart>>(
                new List<ChatCompletionContentPart>
                {
                    new ChatCompletionContentPart
                    {
                        Type = ChatCompletionContentPartType.Text,
                        Text = "Describe this image in one sentence.",
                    },
                    new ChatCompletionContentPart
                    {
                        Type = ChatCompletionContentPartType.ImageUrl,
                        ImageUrl = new ChatCompletionContentPartImageUrl
                        {
                            Url = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/NewTux.svg/150px-NewTux.svg.png",
                        },
                    },
                }),
        },
    ]);

Console.WriteLine(response.Choices![0].Message?.Content);

Image Generation

Generate an image from a text prompt.

var client = new XaiClient(apiKey);

// Generate an image using the Grok Imagine model.
var response = await client.Images.CreateImageAsync(
    model: "grok-imagine-image",
    prompt: "A simple red circle on a white background");

Console.WriteLine(response.Data![0].Url);

Image Editing

Edit an existing image using a text prompt.

var client = new XaiClient(apiKey);

// Edit an image by providing a source image URL and an instruction prompt.
var response = await client.Images.CreateImageEditAsync(
    model: "grok-2-image",
    prompt: "Add a red hat to the person in the image",
    image: new ImageInput
    {
        Url = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png",
    });

Console.WriteLine(response.Data![0].Url);

Video Generation

Generate a video from a text prompt using the polling helper.

var client = new XaiClient(apiKey);

// Use the `GenerateAndWaitAsync` helper to submit a video request and poll until done.
var status = await client.GenerateAndWaitAsync(
    new CreateVideoRequest
    {
        Model = "grok-imagine-video",
        Prompt = "A gentle ocean wave rolling onto a sandy beach at sunset",
        Duration = 3,
        Resolution = CreateVideoRequestResolution.x480p,
    },
    pollingInterval: TimeSpan.FromSeconds(10),
    timeout: TimeSpan.FromMinutes(5));

Console.WriteLine(status.Video?.Url);

Text to Speech

Convert text to speech audio.

var client = new XaiClient(apiKey);

// Generate speech audio from text. Available voices: Eve, Ara, Rex, Sal, Leo.
byte[] audioBytes = await client.Audio.CreateSpeechAsync(
    model: "tts-1",
    input: "Hello from xAI!",
    voice: CreateSpeechRequestVoice.Eve);

    "audio output should contain meaningful data");

Console.WriteLine($"Generated {audioBytes.Length} bytes of audio.");

Responses API

Create, retrieve, and delete server-stored responses.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Create a response that is stored server-side for later retrieval.
var response = await client.Responses.CreateResponseAsync(
    model: modelId,
    input: "What is 2+2? Answer with just the number.");

Console.WriteLine($"Response: {response.Output}");

// Retrieve the stored response by ID.
var retrieved = await client.Responses.GetResponseAsync(response.Id!);

Console.WriteLine($"Retrieved: {retrieved.Id}");

// Delete the stored response when no longer needed.
var deleted = await client.Responses.DeleteResponseAsync(response.Id!);

Console.WriteLine($"Deleted: {deleted.Deleted}");

Deferred Completion

Submit a chat completion for asynchronous processing and poll for the result.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Submit a deferred request — it returns immediately with a request ID.
var response = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages: [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Explain what a quasar is in two sentences.",
        },
    ],
    deferred: true);

// Poll for the result (the request is processed asynchronously).
await Task.Delay(TimeSpan.FromSeconds(5));

var result = await client.Chat.GetDeferredCompletionAsync(response.Id!);

Console.WriteLine(result.Choices![0].Message?.Content);

Realtime Voice

Connect to the Realtime Voice Agent WebSocket API for bidirectional text/audio streaming.

var apiKey =
    Environment.GetEnvironmentVariable("XAI_API_KEY") is { Length: > 0 } apiKeyValue
        ? apiKeyValue
        : throw new AssertInconclusiveException("XAI_API_KEY environment variable is not found.");

// Create a WebSocket client and connect to the xAI Realtime API.
using var client = new XaiRealtimeClient(apiKey);
await client.ConnectAsync();

// Configure the session with voice, instructions, and turn detection.
await client.SendSessionUpdateAsync(new SessionUpdatePayload
{
    Session = new SessionConfig
    {
        Voice = SessionConfigVoice.Eve,
        Instructions = "You are a helpful assistant. Respond briefly.",
        Modalities = ["text", "audio"],
        TurnDetection = new TurnDetection
        {
            Type = "server_vad",
            Threshold = 0.85,
            SilenceDurationMs = 500,
        },
    },
});

// Send a text message and request a text response.
await client.SendConversationItemCreateAsync(new ConversationItemCreatePayload
{
    Item = new ConversationItem
    {
        Type = "message",
        Role = "user",
        Content = [new ContentPart { Type = "input_text", Text = "Say hello!" }],
    },
});
await client.SendResponseCreateAsync(new ResponseCreatePayload
{
    Response = new ResponseConfig
    {
        Modalities = ["text"],
    },
});

// Receive server events until the response is complete.
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var receivedSessionUpdated = false;
var receivedResponseDone = false;
string? transcriptText = null;

await foreach (var serverEvent in client.ReceiveUpdatesAsync(cts.Token))
{
    if (serverEvent.IsSessionUpdated)
    {
        receivedSessionUpdated = true;
    }
    else if (serverEvent.IsResponseOutputAudioTranscriptDelta)
    {
        transcriptText = (transcriptText ?? "") + serverEvent.ResponseOutputAudioTranscriptDelta?.Delta;
        Console.Write(serverEvent.ResponseOutputAudioTranscriptDelta?.Delta);
    }
    else if (serverEvent.IsResponseDone)
    {
        receivedResponseDone = true;
        break;
    }
    else if (serverEvent.IsError)
    {
    }
}

Multi-Turn Conversation

Continue a conversation across multiple turns with system instructions and history.

var client = new XaiClient(apiKey);
var modelId = GetModelId();

// Pass a system message and conversation history to maintain context across turns.
var response = await client.Chat.CreateChatCompletionAsync(
    model: modelId,
    messages:
    [
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.System,
            Content = "You are a helpful math tutor. Always show your work.",
        },
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "What is 7 * 8?",
        },
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.Assistant,
            Content = "7 * 8 = 56",
        },
        new ChatCompletionMessage
        {
            Role = ChatCompletionMessageRole.User,
            Content = "Now divide that result by 4.",
        },
    ]);

var content = response.Choices![0].Message?.Content;
    "56 / 4 = 14, and the model should reference the previous result");

Console.WriteLine(content);

Search uploaded document collections using hybrid search.

var client = new XaiClient(apiKey);

var collectionId =
    Environment.GetEnvironmentVariable("XAI_COLLECTION_ID") is { Length: > 0 } value
        ? value
        : throw new AssertInconclusiveException(
            "XAI_COLLECTION_ID environment variable is not found.");

// Search across document collections using hybrid (semantic + keyword) mode.
var response = await client.Collections.SearchDocumentsAsync(
    query: "What is xAI?",
    collectionIds: [collectionId],
    mode: SearchDocumentsRequestMode.Hybrid,
    maxNumResults: 5);

foreach (var result in response.Results!)
{
    Console.WriteLine($"Score: {result.Score:F3} — {result.Content?[..Math.Min(80, result.Content?.Length ?? 0)]}...");
}

File Upload

Upload a file for use with the Batch API.

var client = new XaiClient(apiKey);

// Upload a file by providing its content, filename, and purpose.
var content = "Hello from xAI SDK integration test."u8.ToArray();

var file = await client.Files.UploadFileAsync(
    file: content,
    filename: "test-upload.txt",
    purpose: "batch");

Console.WriteLine($"Uploaded: {file.Id} ({file.Bytes} bytes)");

API Key Info

Retrieve information about the current API key.

var client = new XaiClient(apiKey);

// Check the current API key's metadata — useful for diagnostics and validation.
var info = await client.Auth.GetApiKeyInfoAsync();

Console.WriteLine($"Key: {info.RedactedApiKey}");
Console.WriteLine($"User: {info.UserId}");

Support

Priority place for bugs: https://github.com/tryAGI/Xai/issues Priority place for ideas and general questions: https://github.com/tryAGI/Xai/discussions Discord: https://discord.gg/Ca2xhfBf3v

Acknowledgments

JetBrains logo

This project is supported by JetBrains through the Open Source Support Program.

CodeRabbit logo

This project is supported by CodeRabbit through the Open Source Support Program.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.0-dev.60 49 5/21/2026
0.0.0-dev.58 53 5/4/2026
0.0.0-dev.57 62 5/3/2026
0.0.0-dev.44 71 4/1/2026
0.0.0-dev.43 62 3/29/2026
0.0.0-dev.40 156 3/28/2026
0.0.0-dev.37 59 3/28/2026
0.0.0-dev.36 59 3/28/2026
0.0.0-dev.34 68 3/27/2026
0.0.0-dev.25 57 3/20/2026
0.0.0-dev.23 58 3/20/2026
0.0.0-dev.22 52 3/20/2026
0.0.0-dev.21 60 3/19/2026
0.0.0-dev.20 57 3/19/2026
0.0.0-dev.19 59 3/19/2026
0.0.0-dev.18 58 3/19/2026
0.0.0-dev.17 53 3/19/2026
0.0.0-dev.16 54 3/19/2026
0.0.0-dev.15 57 3/19/2026
0.0.0-dev.14 57 3/19/2026
Loading failed