Retour au blog

API & SDKGuide

Première requête en C# avec openai-dotnet : endpoint, clé, réponse

Envoyez votre première complétion de chat depuis une application console C# : définissez l'Endpoint dans la bibliothèque OpenAI .NET officielle, lisez la clé depuis l'env, affichez la réponse et la raison de fin.

Par CheapTokens TeamPublié le 5 min de lecture

Couverture : C# et la bibliothèque OpenAI .NET connectés à l'endpoint CheapTokens
Sur cette page
  1. Ce qu'il vous faut
  2. Construire l'application console
  3. Le code, ligne par ligne
  4. Ce que vous devriez voir
  5. Basculer un service existant
  6. Combien coûte une requête
  7. Si ça ne fonctionne pas

Pour envoyer une requête depuis C# vers CheapTokens, conservez la bibliothèque OpenAI officielle pour .NET et définissez OpenAIClientOptions.Endpoint sur https://api.cheaptokens.dev/v1. Passez l'identifiant complet du modèle, par exemple deepseek-ai/DeepSeek-V4-Flash-0731, et lisez la clé depuis une variable d'environnement. Les appels ChatClient et CompleteChat restent exactement tels qu'ils sont dans les exemples OpenAI.

Supposez que vous avez déjà un service ASP.NET qui communique avec OpenAI et que vous voulez essayer un autre endpoint et un autre modèle sans toucher au reste du code. Avant de brancher quoi que ce soit, vérifiez les trois points qui posent généralement problème (clé, endpoint, identifiant du modèle) dans une petite application console. C'est ce que nous construisons ici. Les détails ci-dessous proviennent du README de la bibliothèque sur GitHub (openai/openai-dotnet, consulté le 5 novembre 2026) et de la documentation CheapTokens : la page de documentation indique la même URL de base.

Ce qu'il vous faut#

Le paquet s'appelle OpenAI sur NuGet. La dernière version stable au 5 novembre 2026 est 2.15.0 (son entrée de changelog est datée du 4 novembre). Il cible .NET 8 et .NET Standard 2.0, et le README indique qu'il fonctionne avec toutes les applications .NET Standard 2.0, donc un projet plus ancien convient aussi.

Trois valeurs entrent dans l'application :

  • URL de base : https://api.cheaptokens.dev/v1 (compatible avec OpenAI Chat Completions) ;
  • identifiant du modèle : deepseek-ai/DeepSeek-V4-Flash-0731. Utilisez l'identifiant complet, le nom court d'un tableau de prix n'est pas accepté. DeepSeek-V4-Flash dispose d'une fenêtre de contexte de 380K et de jusqu'à 32 768 jetons de sortie par réponse, à un prix unique quel que soit le moment de la journée ;
  • une clé API issue de votre compte CheapTokens, conservée dans une variable d'environnement. Si vous ne savez pas comment la stocker, lisez comment stocker une clé API en toute sécurité.

Construire l'application console#

Étape par étape

Créez le projet et exécutez-le

Créer un projet console

bash
dotnet new console -o FirstRequest
cd FirstRequest

Ajouter le paquet

bash
dotnet add package OpenAI

Placer la clé dans une variable d'environnement

Dans bash ou zsh :

bash
export CHEAPTOKENS_API_KEY=your-key

Dans Windows PowerShell :

powershell
$env:CHEAPTOKENS_API_KEY = "your-key"

Collez le code et exécutez

Remplacez le contenu de Program.cs par le code de la section suivante, puis exécutez dotnet run.

Terminal avec les cinq commandes qui créent et exécutent l'application console
Les cinq commandes : créer le projet, entrer dans le dossier, ajouter le paquet, définir la clé, exécuter.

Le code, ligne par ligne#

csharp
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;

string? apiKey = Environment.GetEnvironmentVariable("CHEAPTOKENS_API_KEY");
if (string.IsNullOrEmpty(apiKey))
{
    Console.WriteLine("Set CHEAPTOKENS_API_KEY first.");
    return;
}

ChatClient client = new(
    model: "deepseek-ai/DeepSeek-V4-Flash-0731",
    credential: new ApiKeyCredential(apiKey),
    options: new OpenAIClientOptions
    {
        Endpoint = new Uri("https://api.cheaptokens.dev/v1")
    });

ChatCompletion completion = client.CompleteChat("Explain in two sentences what a token is.");

Console.WriteLine(completion.Content[0].Text);
Console.WriteLine($"finish_reason: {completion.FinishReason}");

Le README montre ce schéma pour « un proxy ou un LLM auto-hébergé compatible OpenAI » : l'endpoint va dans OpenAIClientOptions, la clé dans un ApiKeyCredential (elle vit dans System.ClientModel, d'où le premier using). La vérification en haut est la nôtre : elle affiche un message clair si la variable n'est pas définie.

CompleteChat avec une chaîne simple envoie un message utilisateur et attend la réponse complète. Le texte de la réponse se trouve dans completion.Content[0].Text. La raison de fin se trouve dans completion.FinishReason.

Flux : clé depuis l'env, ChatClient avec Endpoint, CompleteChat, texte et FinishReason
Ce qui se passe dans le programme, de la clé à la réponse affichée.

Ce que vous devriez voir#

Vous devriez obtenir une courte explication des jetons et une ligne avec la raison de fin ; après une fin normale, c'est Stop (le README compare FinishReason avec ChatFinishReason.Stop). La formulation de la réponse change d'une exécution à l'autre.

La deuxième ligne est celle qui vaut la peine d'être lue. Le README compare FinishReason avec ChatFinishReason.Stop (le modèle a terminé de lui-même) et ChatFinishReason.ToolCalls (le modèle veut appeler un outil). Tout autre valeur que Stop dans un simple chat signifie que la réponse s'est terminée pour une autre raison, et le suspect habituel est une limite de longueur. Si vous voyez une réponse qui s'arrête au milieu d'une phrase, cet article explique finish_reason et max_tokens.

Basculer un service existant#

Si votre service crée déjà un ChatClient pour OpenAI, vous changez deux choses : la chaîne du modèle et les options. Le reste des appels continue de fonctionner.

Comparer

Même client, deux lignes modifiées

Avant

csharp
ChatClient client = new(
    model: "your-current-model",
    credential: new ApiKeyCredential(apiKey));

Après

csharp
ChatClient client = new(
    model: "deepseek-ai/DeepSeek-V4-Flash-0731",
    credential: new ApiKeyCredential(apiKey),
    options: new OpenAIClientOptions
    {
        Endpoint = new Uri("https://api.cheaptokens.dev/v1")
    });

Pour les requêtes courtes, il existe une seconde option : zai-org/GLM-5.3-Flash (contexte de 390K, jusqu'à 8 192 jetons de sortie). Vous ne changez que la chaîne model. Une liste des identifiants que votre clé peut utiliser est à une requête de distance, voir Lister les modèles avec GET /v1/models.

Combien coûte une requête#

Supposons qu'un service traite 1 000 requêtes par jour, chacune d'environ 300 jetons en entrée et 400 jetons en sortie. Une telle requête coûte $0.000045 sur DeepSeek-V4-Flash. Le tableau ci-dessous montre les mêmes 1 000 requêtes sur les trois modèles, à côté d'OpenRouter. Au total, en comptant l'entrée et la sortie ensemble, DeepSeek-V4-Flash est moins cher qu'OpenRouter. Les prix actuels sont sur la page de tarification, et la page DeepSeek liste ce que le modèle offre.

Modèle Par requête 1 000 requêtes OpenRouter, 1 000 requêtes
GLM-5.3-Flash $0.000022 $0.022 $0.0433
DeepSeek-V4-Flash $0.000045 $0.0445 $0.077
MiniMax-M2.7 $0.000075 $0.075 $0.90

300 tokens d'entrée et 400 tokens de sortie par requête. Les prix par million de tokens sont actuels et évoluent avec nos tarifs ; la colonne OpenRouter indique des prix de référence pour la même charge de travail.

Si ça ne fonctionne pas#

  • 401. La clé est absente ou incorrecte. Affichez si la variable est définie (la vérification dans le code le fait) et assurez-vous que dotnet run est lancé dans le même terminal où vous avez exécuté export (ou $env:) : la variable n'existe que dans cette session.
  • 404. Le plus souvent, c'est l'identifiant du modèle : un nom court au lieu du deepseek-ai/DeepSeek-V4-Flash-0731 complet, ou un endpoint sans /v1 (vérifiez aussi que OpenAIClientOptions est bien passé à ChatClient). Les détails sont dans API 401 ou 404 : mauvaise clé, URL de base ou identifiant de modèle.
  • error CS0246: The type or namespace name 'ApiKeyCredential' could not be found. La ligne using System.ClientModel; manque en haut de Program.cs.

La même idée dans un autre langage : la version Go avec openai-go.