SDK · Stable
.NET / C# SDK
Official FluxChat SDK for .NET. ASP.NET Core, Blazor, MAUI and console apps — async throughout, HttpClient under the hood, System.Text.Json models.
Installation
dotnet add package FluxChatCreate a client
The base URL defaults to https://api.fluxchat-corp.com/api/v2 — production. Pass it explicitly to target dev.
using FluxChat;
var client = new FluxChatClient(Environment.GetEnvironmentVariable("FLUXCHAT_API_KEY")!);ask()
Send a message and get the assistant's reply. Pass context to inject real-time data the bot treats as a priority source of truth, above the knowledge base. A sessionId keeps multi-turn history without persisting a conversation.
var response = await client.AskAsync(
"Quels sont vos horaires ?",
context: "Utilisateur : Alice, Plan : Pro",
sessionId: mySessionId);
Console.WriteLine(response.Reply);Human handoff (support thread)
When the bot can't help, hand the visitor to a human. This creates a real support ticket in the organization's dashboard — and unlike a contact form, the conversation stays open in the same thread: the visitor polls it, the agent answers into it.
var support = client.Support();
// 1. Hand off — with the same sessionId you pass to AskAsync, the bot's side
// of the conversation is copied into the ticket.
var ticket = await support.EscalateAsync(
"Jordan Mbeki",
"jordan@example.com",
"Mon virement est bloqué depuis hier.",
mySessionId);
// 2. Follow the thread: the e-mail proves the ticket is theirs.
var thread = await support.ThreadAsync(ticket.TicketId, "jordan@example.com");
foreach (var m in thread.Messages)
Console.WriteLine($"{m.Role}: {m.Content}"); // bot | visitor | agent
if (thread.AgentConnected)
Console.WriteLine($"{thread.AgentName} is answering");
// 3. Let them reply into it.
await support.ReplyAsync(ticket.TicketId, "jordan@example.com", "La référence est 4821.");- Ownership is the e-mail. A wrong e-mail and a non-existent ticket both return
404, deliberately — a guessed ticket id reveals nothing. The lookup is also scoped to the organization behind your API key. - Polled, not pushed. There is no socket on the public surface. 5s is the cadence the official widget uses and what the route's limits are sized for: 60 reads/min, 30 replies/min, 5 escalations/min.
- Statuses:
open→in_progress→resolved→closed. A reply to a resolved ticket reopens it; a closed one refuses the write (403) rather than swallowing a message nobody will read. - Requires the organization's plan to include
supportTickets(403otherwise).
Knowledge base
Create, update and delete articles. Write operations need a key with the bot:write scope, or an admin JWT.
var kb = client.Knowledge(jwtToken);
var article = await kb.CreateAsync("Délais de livraison", "Livraison sous 48 h en RDC.");
await kb.DeleteAsync(article.Id);Errors
Every failure is typed: an API error carries the HTTP status and the server's message, a network error wraps the transport failure, and a config error is raised before any request leaves.
try
{
await support.ThreadAsync(ticketId, "someone@else.com");
}
catch (FluxChatApiException ex)
{
// 404 both when the ticket does not exist and when the e-mail does not
// own it — deliberately indistinguishable.
Console.WriteLine($"{ex.StatusCode} {ex.Message}");
}
catch (FluxChatNetworkException ex)
{
Console.WriteLine($"transport failure: {ex.Message}");
}