> ## Documentation Index
> Fetch the complete documentation index at: https://phaseo.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Démarrage rapide

> Créez une clé API et envoyez votre première requête Phaseo avec un modèle de texte actuel.

Utilisez ce tutoriel pour réussir une requête Phaseo, avec du texte généré ou une décision structurée, et vérifier où apparaît la réponse.

<Note>
  **Vous utilisez un agent de programmation ?** Copiez et collez ce prompt avant de commencer :

  ```text theme={null}
  You are integrating this project with Phaseo Gateway. Read the Phaseo agent guidance at https://phaseo.app/docs/skill.md and the relevant API reference before editing anything. Inspect the existing provider configuration and identify the smallest safe change needed. Use https://api.phaseo.app with a server-side PHASEO_API_KEY, preserve the current provider/model behavior unless I explicitly ask for a migration, and never print or commit credentials. Explain the files you would change and the verification commands first. Do not deploy, rotate keys, send external messages, or make unrelated edits without my approval.
  ```
</Note>

Vous allez :

* créer une clé API
* envoyer une requête texte ou une décision structurée
* lire le texte généré ou les réponses typées
* savoir quoi vérifier en premier si la requête échoue

***

## 1. Créer une clé API

1. Ouvrez le [tableau de bord Phaseo](https://phaseo.app/gateway/keys).
2. Créez une clé dans **Gateway -> Clés**.
3. Copiez-la une seule fois et conservez-la en lieu sûr.

Utilisez ce format :

```http theme={null}
Authorization: Bearer phaseo_v1_sk_<kid>_<secret>
```

<Danger>
  Traitez votre clé API comme un mot de passe. Ne l’exposez pas dans du code côté client.
</Danger>

***

## 2. Envoyer une requête textuelle

Utilisez `POST /v1/responses` pour la première requête. C’est l’endpoint recommandé pour les nouveaux usages de génération de texte.

### Requête

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.phaseo.app/v1/responses \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-6-astra",
      "input": "Reply with: quickstart works"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.phaseo.app/v1/responses", {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "openai/gpt-6-astra",
      input: "Reply with: quickstart works",
    }),
  });

  const data = await response.json();
  const assistantText = data.output
    ?.find((item) => item.type === "message")
    ?.content?.find((part) => part.type === "output_text")
    ?.text;

  console.log(assistantText);
  ```

  ```typescript TypeScript SDK theme={null}
  import Phaseo from "@phaseo/sdk";

  const client = new Phaseo({ apiKey: process.env.PHASEO_API_KEY! });

  const response = await client.generateResponse({
    model: "openai/gpt-6-astra",
    input: "Reply with: quickstart works",
  });

  const assistantText = response.output
    ?.find((item: any) => item.type === "message")
    ?.content?.find((part: any) => part.type === "output_text")
    ?.text;

  console.log(assistantText);
  ```

  ```python Python SDK theme={null}
  from phaseo import Phaseo

  client = Phaseo(api_key="YOUR_API_KEY")

  response = client.generate_response(
      {
          "model": "openai/gpt-6-astra",
          "input": "Reply with: quickstart works",
      }
  )

  assistant_text = next(
      (
          part.get("text")
          for item in response.get("output", [])
          if item.get("type") == "message"
          for part in item.get("content", [])
          if part.get("type") == "output_text"
      ),
      None,
  )

  print(assistant_text)
  ```

  ```go Go SDK theme={null}
  package main

  import (
    "context"
    "fmt"

    phaseo "github.com/phaseoteam/Phaseo/packages/sdk/sdk-go/v3"
  )

  func main() {
    client := phaseo.New("YOUR_API_KEY", "https://api.phaseo.app/v1")
    input := map[string]interface{}{
      "role": "user",
      "content": []map[string]interface{}{
        {
          "type": "input_text",
          "text": "Reply with: quickstart works",
        },
      },
    }

    response, err := client.GenerateResponse(context.Background(), phaseo.ResponsesRequest{
      Model: "openai/gpt-6-astra",
      Input: &input,
    })
    if err != nil {
      panic(err)
    }

    fmt.Println(response)
  }
  ```

  ```csharp C# SDK theme={null}
  using PhaseoSdk;
  using System.Collections.Generic;

  var client = new Phaseo("YOUR_API_KEY");

  var response = await client.GenerateResponse(new Dictionary<string, object>
  {
      ["model"] = "openai/gpt-6-astra",
      ["input"] = "Reply with: quickstart works",
  });

  Console.WriteLine(response);
  ```

  ```php PHP SDK theme={null}
  <?php
  require 'vendor/autoload.php';

  use Phaseo\Sdk\Phaseo;

  $client = new Phaseo(getenv('PHASEO_API_KEY') ?: 'YOUR_API_KEY');

  $response = $client->generateResponse([
      'model' => 'openai/gpt-6-astra',
      'input' => 'Reply with: quickstart works',
  ]);

  print_r($response);
  ```

  ```ruby Ruby SDK theme={null}
  require 'phaseo_sdk'

  client = PhaseoSdk::Phaseo.new(api_key: ENV.fetch('PHASEO_API_KEY', 'YOUR_API_KEY'))

  response = client.generate_response(
    model: 'openai/gpt-6-astra',
    input: 'Reply with: quickstart works',
  )

  puts response
  ```

  ```rust Rust SDK theme={null}
  use phaseo::Phaseo;
  use serde_json::{json, Value};

  fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = Phaseo::from_env()?;
      let response = client.responses(&json!({
          "model": "openai/gpt-6-astra",
          "input": "Reply with: quickstart works"
      }))?;

      let assistant_text = response.body
          .get("output")
          .and_then(Value::as_array)
          .into_iter()
          .flatten()
          .filter(|item| item.get("type").and_then(Value::as_str) == Some("message"))
          .flat_map(|item| {
              item.get("content")
                  .and_then(Value::as_array)
                  .into_iter()
                  .flatten()
          })
          .find_map(|part| {
              (part.get("type").and_then(Value::as_str) == Some("output_text"))
                  .then(|| part.get("text").and_then(Value::as_str))
                  .flatten()
          })
          .unwrap_or("");

      println!("{assistant_text}");
      Ok(())
  }
  ```

  ```typescript Vercel AI SDK theme={null}
  import { phaseo } from "@phaseo/ai-sdk-provider";
  import { generateText } from "ai";

  const result = await generateText({
    model: phaseo("openai/gpt-6-astra"),
    prompt: "Reply with: quickstart works",
  });

  console.log(result.text);
  ```
</CodeGroup>

### Réponse

```json theme={null}
{
  "id": "resp_...",
  "object": "response",
  "created_at": 1730000000,
  "status": "completed",
  "completed_at": 1730000001,
  "model": "openai/gpt-6-astra",
  "output": [
    {
      "type": "message",
      "id": "msg_...",
      "status": "completed",
      "role": "assistant",
      "content": [{ "type": "output_text", "text": "quickstart works", "annotations": [] }]
    }
  ],
  "usage": {
    "input_tokens": 9,
    "output_tokens": 3,
    "total_tokens": 12
  },
  "error": null,
  "incomplete_details": null
}
```

Pour les appels directs à l’API Responses, lisez la réponse de l’assistant dans `output[].content[]`, à l’élément dont `type` vaut `output_text`.

Avec le SDK Vercel AI, lisez la réponse dans `result.text`.

***

## 3. Prendre une décision structurée

Utilisez `POST /v1/decisions` lorsque votre application nécessite des réponses typées plutôt que du texte généré. Phaseo propose Jev 1.13 de TypeSafe avec l’identifiant `typesafe/jev-1.13.0`. Envoyez une valeur `state` et une ou plusieurs questions nommées ; chaque réponse est renvoyée sous le même nom.

<Note>
  Decisions est une fonctionnalité bêta qui peut nécessiter une activation pour l’espace de travail. Jev 1.13 est facturé \$0.042 par million de jetons d’entrée ; les jetons de sortie sont gratuits.
</Note>

Exécutez ces exemples sur votre serveur avec `PHASEO_API_KEY` défini. N’exposez jamais de clé API Gateway dans le code du navigateur.

Les trois types de question sont :

* `choice` sélectionne une option dans un dictionnaire de critères et renvoie les probabilités et la confiance.
* `noul` renvoie une probabilité oui/non entre 0 et 1.
* `score` évalue un tableau ordonné de critères et renvoie un score pondéré par les probabilités.

Vous pouvez combiner plusieurs types de question dans une même requête.

### Requête

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.phaseo.app/v1/decisions \
    -H "Authorization: Bearer $PHASEO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "typesafe/jev-1.13.0",
      "state": {
        "customer_message": "I was charged twice and need help with a refund.",
        "account_tier": "pro",
        "days_waiting": 3
      },
      "questions": {
        "department": {
          "type": "choice",
          "instructions": "Which team should handle this request?",
          "criteria": {
            "billing": "Payments, invoices, refunds, and duplicate charges.",
            "support": "Product usage questions and troubleshooting.",
            "sales": "Upgrades and new accounts."
          }
        },
        "is_urgent": {
          "type": "noul",
          "instructions": "Does this request require urgent handling?",
          "criteria": {
            "true": "The customer is blocked or the issue is time-sensitive.",
            "false": "The request can follow the normal support queue."
          }
        },
        "customer_impact": {
          "type": "score",
          "instructions": "How severe is the customer impact?",
          "criteria": [
            "No impact",
            "Minor inconvenience",
            "Significant impact",
            "Service blocked"
          ]
        }
      }
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.phaseo.app/v1/decisions", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.PHASEO_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "typesafe/jev-1.13.0",
      state: {
        customer_message: "I was charged twice and need help with a refund.",
        account_tier: "pro",
        days_waiting: 3,
      },
      questions: {
        department: {
          type: "choice",
          instructions: "Which team should handle this request?",
          criteria: {
            billing: "Payments, invoices, refunds, and duplicate charges.",
            support: "Product usage questions and troubleshooting.",
            sales: "Upgrades and new accounts.",
          },
        },
        is_urgent: {
          type: "noul",
          instructions: "Does this request require urgent handling?",
          criteria: {
            true: "The customer is blocked or the issue is time-sensitive.",
            false: "The request can follow the normal support queue.",
          },
        },
        customer_impact: {
          type: "score",
          instructions: "How severe is the customer impact?",
          criteria: [
            "No impact",
            "Minor inconvenience",
            "Significant impact",
            "Service blocked",
          ],
        },
      },
    }),
  });

  if (!response.ok) throw new Error(await response.text());
  const data = await response.json();
  console.log(data.answers);
  ```

  ```typescript TypeScript SDK theme={null}
  import Phaseo from "@phaseo/sdk";

  const client = new Phaseo({ apiKey: process.env.PHASEO_API_KEY! });

  const decision = await client.decisions.make({
    model: "typesafe/jev-1.13.0",
    state: {
      customer_message: "I was charged twice and need help with a refund.",
      account_tier: "pro",
      days_waiting: 3,
    },
    questions: {
      department: {
        type: "choice",
        instructions: "Which team should handle this request?",
        criteria: {
          billing: "Payments, invoices, refunds, and duplicate charges.",
          support: "Product usage questions and troubleshooting.",
          sales: "Upgrades and new accounts.",
        },
      },
      is_urgent: {
        type: "noul",
        instructions: "Does this request require urgent handling?",
        criteria: {
          true: "The customer is blocked or the issue is time-sensitive.",
          false: "The request can follow the normal support queue.",
        },
      },
      customer_impact: {
        type: "score",
        instructions: "How severe is the customer impact?",
        criteria: [
          "No impact",
          "Minor inconvenience",
          "Significant impact",
          "Service blocked",
        ],
      },
    },
  });

  console.log(decision.answers);
  ```

  ```python Python SDK theme={null}
  from phaseo import Phaseo

  client = Phaseo()  # Uses PHASEO_API_KEY from the environment

  decision = client.decisions.make(
      {
          "model": "typesafe/jev-1.13.0",
          "state": {
              "customer_message": "I was charged twice and need help with a refund.",
              "account_tier": "pro",
              "days_waiting": 3,
          },
          "questions": {
              "department": {
                  "type": "choice",
                  "instructions": "Which team should handle this request?",
                  "criteria": {
                      "billing": "Payments, invoices, refunds, and duplicate charges.",
                      "support": "Product usage questions and troubleshooting.",
                      "sales": "Upgrades and new accounts.",
                  },
              },
              "is_urgent": {
                  "type": "noul",
                  "instructions": "Does this request require urgent handling?",
                  "criteria": {
                      "true": "The customer is blocked or the issue is time-sensitive.",
                      "false": "The request can follow the normal support queue.",
                  },
              },
              "customer_impact": {
                  "type": "score",
                  "instructions": "How severe is the customer impact?",
                  "criteria": [
                      "No impact",
                      "Minor inconvenience",
                      "Significant impact",
                      "Service blocked",
                  ],
              },
          },
      }
  )

  print(decision["answers"])
  ```
</CodeGroup>

### Réponse

```json theme={null}
{
  "model": "typesafe/jev-1.13.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "probabilities": { "billing": 0.91, "support": 0.06, "sales": 0.03 },
      "confidence": 0.89
    },
    "is_urgent": {
      "type": "noul",
      "noul": 0.84
    },
    "customer_impact": {
      "type": "score",
      "score": 2.4,
      "legend": {
        "0": "No impact",
        "1": "Minor inconvenience",
        "2": "Significant impact",
        "3": "Service blocked"
      },
      "probabilities": { "0": 0.02, "1": 0.12, "2": 0.61, "3": 0.25 },
      "confidence": 0.76
    }
  },
  "usage": {
    "input_tokens": 42,
    "output_tokens": 18,
    "total_tokens": 60
  }
}
```

Lisez la valeur typée de la réponse correspondant à l’identifiant de votre question, par exemple `answers.department.choice`, `answers.is_urgent.noul` ou `answers.customer_impact.score`. Utilisez `confidence` et `probabilities` pour définir un seuil dans l’application plutôt que de décider sur la seule valeur.

Consultez la [référence API Decisions](./api-reference/endpoint/decisions) pour le contrat complet des requêtes et réponses, et la [référence du modèle Jev](https://docs.typesafe.ai/models) de TypeSafe pour son comportement et ses limites amont.

***

## 4. Dépanner la première requête

* `401` : vérifiez la clé API et l’en-tête `Authorization`.
* `400` : vérifiez le corps de la requête et l’identifiant du modèle.
* `402` : choisissez un modèle `:free` ou ajoutez des crédits avant d’utiliser un modèle payant.
* `429` ou `5xx` : réessayez avec un délai exponentiel.

Consultez la [référence de gestion des erreurs](./api-reference/errors.mdx) pour identifier rapidement le problème.

***

## 5. Si vous développez une fonctionnalité vidéo

La génération vidéo est asynchrone. Créez d’abord un job, puis interrogez son état ou abonnez-vous pour recevoir le résultat.

1. Créez un job avec `POST /v1/videos`.
2. Interrogez l’état avec `GET /v1/videos/{video_id}` jusqu’à la fin.
3. Téléchargez le contenu avec `GET /v1/videos/{video_id}/content`.

```bash theme={null}
# Create
curl https://api.phaseo.app/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<video-model-id>",
    "prompt": "A cinematic sunrise over a mountain lake"
  }'

# Poll status
curl https://api.phaseo.app/v1/videos/VIDEO_ID \
  -H "Authorization: Bearer YOUR_API_KEY"
```

***

## 6. Poursuivre le développement

<Columns cols={2}>
  <Card title="Intégrer le Gateway" icon="plug" href="./developers/integrating-with-the-gateway.mdx">
    Modèles d’intégration en production et choix des endpoints.
  </Card>

  <Card title="Référence API" icon="book" href="./api-reference/introduction.mdx">
    Documentation complète des requêtes et réponses pour chaque endpoint.
  </Card>

  <Card title="Exemples" icon="code" href="./guides/examples.mdx">
    Des exemples de requêtes plus complets pour les workflows courants.
  </Card>

  <Card title="Assistance" icon="message-circle" href="https://phaseo.app/help">
    Obtenez de l’aide sur le débogage, le routage et le comportement des modèles.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.