If you already call OpenAI from C# with the official OpenAI .NET SDK, you can point the same client at Wren R1 without changing your call sites. The client takes an endpoint, so the base URL becomes a configuration value.

using System;
using System.ClientModel;
using OpenAI;
using OpenAI.Audio;
using OpenAI.Chat;

string apiKey = Environment.GetEnvironmentVariable("WEBWRIGHT_API_KEY")
    ?? throw new InvalidOperationException("WEBWRIGHT_API_KEY is not set");

OpenAIClient client = new(
    new ApiKeyCredential(apiKey),
    new OpenAIClientOptions { Endpoint = new Uri("https://webwright.ai/v1") });

A chat completion

The chat endpoint accepts the standard OpenAI chat payload, so the request you already write works here. Create a ChatClient for the model and call it.

ChatClient chat = client.GetChatClient("wren-r1");

ChatCompletion completion = await chat.CompleteChatAsync("Reply with the single word: ready");
Console.WriteLine(completion.Content[0].Text);

Streaming a chat completion

For long responses, call the streaming variant and read each update as it arrives. The synchronous form returns a CollectionResult<StreamingChatCompletionUpdate>; the async form returns an AsyncCollectionResult<StreamingChatCompletionUpdate>.

await foreach (StreamingChatCompletionUpdate update in chat.CompleteChatStreamingAsync("Count from 1 to 5."))
{
    foreach (ChatMessageContentPart part in update.ContentUpdate)
    {
        Console.Write(part.Text);
    }
}

Transcribing audio

The same client and endpoint reach the transcription endpoint. Create an AudioClient for the transcription model, pass the audio file, and read the transcript text.

AudioClient audio = client.GetAudioClient("whisper-large-v3-turbo");

AudioTranscription transcription = await audio.TranscribeAudioAsync("meeting.mp3");
Console.WriteLine(transcription.Text);

If you need timings for a downstream step, ask for the verbose format and the granularities you consume.

AudioTranscriptionOptions options = new()
{
    ResponseFormat = AudioTranscriptionFormat.Verbose,
    TimestampGranularities = AudioTimestampGranularities.Word | AudioTimestampGranularities.Segment,
};

AudioTranscription timed = await audio.TranscribeAudioAsync("meeting.mp3", options);
foreach (TranscribedSegment segment in timed.Segments)
{
    Console.WriteLine($"{segment.StartTime.TotalMilliseconds:0} ms: {segment.Text}");
}

One endpoint, one key

Chat and transcription share the endpoint and the key. Read both from the environment, keep them out of source control, and the endpoint stays a value your deployment can change without touching the call sites.

The WebWright Team