> ## 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.

> ## Agent Instructions
> Phaseo Gateway base URL: https://api.phaseo.app/v1. Send `Authorization: Bearer $PHASEO_API_KEY` with every request.
> Model IDs look like `provider/model`, for example `openai/gpt-6-astra`. Do not guess IDs: list them with `GET /v1/models` or check https://phaseo.app/models. `phaseo/free` routes to an available free model and needs no wallet balance.
> For new text integrations prefer `POST /v1/responses`. `POST /v1/chat/completions` (OpenAI format) and `POST /v1/messages` (Anthropic format) suit existing code.
> The full API contract is https://phaseo.app/docs/openapi/v1/openapi.yaml. Official SDKs: `@phaseo/sdk` (TypeScript) and `phaseo` (Python), plus Go, C#, PHP, Ruby and Rust.
> Search these docs over MCP at https://phaseo.app/docs/mcp, and install Phaseo skills with `npx skills add https://phaseo.app/docs`. If a page is wrong or out of date, report it with the MCP `submit_feedback` tool.
> Manage Phaseo accounts with the `phaseo` CLI (`npm install -g @phaseo/cli`, then `phaseo login` or `phaseo login --device-code`), the `/v1` Management API or the MCP server at `https://mcp.phaseo.app/mcp?access=manage`. Do not send users to the dashboard for account tasks. A person is still needed for sign-up, approving a sign-in, paying the first top-up on the checkout link that `phaseo credits add` returns when no card is saved, confirming each saved-card top-up from the emailed link, and account security (password, MFA, passkeys). Create API keys with `phaseo keys create --name <name> --json`; never guess one. Credit top-ups need `phaseo login --scopes billing:write` first. Task map: https://phaseo.app/docs/v1/developers/manage-from-an-agent.md.

# STT (reconnaissance vocale)

> Transcrivez de l’audio avec POST /v1/audio/transcriptions depuis n’importe quel SDK Phaseo.

Envoyez l’audio à `POST /v1/audio/transcriptions` sous forme de formulaire multipart avec un champ `file`. Un corps JSON contenant une chaîne base64 échoue à la validation. Seul le SDK TypeScript sait envoyer ce formulaire ; dans tous les autres langages, envoyez-le avec le client HTTP standard, comme ci-dessous, ou envoyez plutôt une URL (voir [Transcrire de l’audio depuis une URL](#transcribe-audio-from-a-url)).

## Envoyer un fichier audio

```typescript TypeScript theme={null}
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("model", "openai/gpt-4o-transcribe");
form.append("language", "en");
form.append("file", new Blob([await readFile("call.mp3")], { type: "audio/mpeg" }), "call.mp3");

const transcript = await client.generateTranscription(form as unknown as Record<string, unknown>);
console.log(transcript.text);
```

```python Python theme={null}
# generate_transcription() ne sait pas encore envoyer de multipart : envoyez le formulaire avec HTTPX.
import os
import httpx

with open("call.mp3", "rb") as audio:
    response = httpx.post(
        "https://api.phaseo.app/v1/audio/transcriptions",
        headers={"Authorization": f"Bearer {os.environ['PHASEO_API_KEY']}"},
        data={"model": "openai/gpt-4o-transcribe", "language": "en"},
        files={"file": ("call.mp3", audio, "audio/mpeg")},
        timeout=120,
    )
response.raise_for_status()
print(response.json()["text"])
```

```go Go theme={null}
// CreateTranscription() envoie du JSON : envoyez le formulaire avec net/http et mime/multipart.
var body bytes.Buffer
form := multipart.NewWriter(&body)
_ = form.WriteField("model", "openai/gpt-4o-transcribe")
_ = form.WriteField("language", "en")
part, _ := form.CreateFormFile("file", "call.mp3")
audio, _ := os.ReadFile("call.mp3")
_, _ = part.Write(audio)
_ = form.Close()

req, _ := http.NewRequest("POST", "https://api.phaseo.app/v1/audio/transcriptions", &body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("PHASEO_API_KEY"))
req.Header.Set("Content-Type", form.FormDataContentType())

resp, err := http.DefaultClient.Do(req)
```

```csharp C# theme={null}
// CreateTranscription() envoie du JSON : envoyez le formulaire avec HttpClient.
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
    new("Bearer", Environment.GetEnvironmentVariable("PHASEO_API_KEY"));

using var form = new MultipartFormDataContent
{
    { new StringContent("openai/gpt-4o-transcribe"), "model" },
    { new StringContent("en"), "language" },
    { new ByteArrayContent(await File.ReadAllBytesAsync("call.mp3")), "file", "call.mp3" },
};

var response = await http.PostAsync("https://api.phaseo.app/v1/audio/transcriptions", form);
Console.WriteLine(await response.Content.ReadAsStringAsync());
```

```php PHP theme={null}
<?php
// generateTranscription() envoie du JSON : envoyez le formulaire avec Guzzle, que Composer a installé avec le SDK.
require 'vendor/autoload.php';

$http = new GuzzleHttp\Client();

$response = $http->post('https://api.phaseo.app/v1/audio/transcriptions', [
    'headers' => ['Authorization' => 'Bearer ' . getenv('PHASEO_API_KEY')],
    'multipart' => [
        ['name' => 'model', 'contents' => 'openai/gpt-4o-transcribe'],
        ['name' => 'language', 'contents' => 'en'],
        ['name' => 'file', 'contents' => fopen('call.mp3', 'r'), 'filename' => 'call.mp3'],
    ],
]);

echo $response->getBody();
```

```ruby Ruby theme={null}
# generate_transcription envoie du JSON : envoyez le formulaire avec Net::HTTP.
require 'net/http'

uri = URI('https://api.phaseo.app/v1/audio/transcriptions')
request = Net::HTTP::Post.new(uri)
request['Authorization'] = "Bearer #{ENV.fetch('PHASEO_API_KEY')}"
request.set_form(
  [['model', 'openai/gpt-4o-transcribe'], ['language', 'en'], ['file', File.open('call.mp3')]],
  'multipart/form-data'
)

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
puts response.body
```

```java Java theme={null}
// Les assistants JSON du SDK n’encodent pas le multipart : envoyez le formulaire avec java.net.http.
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.file.Path;
import java.time.Duration;
import java.util.UUID;

String baseUrl = System.getenv().getOrDefault("PHASEO_BASE_URL", "https://api.phaseo.app/v1")
    .replaceAll("/+$", "");
String apiKey = System.getenv("PHASEO_API_KEY");
String boundary = "phaseo-" + UUID.randomUUID();
var body = BodyPublishers.concat(
    BodyPublishers.ofString("--" + boundary + "\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nopenai/gpt-4o-transcribe\r\n"),
    BodyPublishers.ofString("--" + boundary + "\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n"),
    BodyPublishers.ofString("--" + boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"call.mp3\"\r\nContent-Type: audio/mpeg\r\n\r\n"),
    BodyPublishers.ofFile(Path.of("call.mp3")),
    BodyPublishers.ofString("\r\n--" + boundary + "--\r\n")
);
var request = HttpRequest.newBuilder(URI.create(baseUrl + "/audio/transcriptions"))
    .header("Authorization", "Bearer " + apiKey)
    .header("Content-Type", "multipart/form-data; boundary=" + boundary)
    .timeout(Duration.ofSeconds(60))
    .POST(body)
    .build();
var response = HttpClient.newHttpClient().send(request, BodyHandlers.ofString());
if (response.statusCode() < 200 || response.statusCode() >= 300) {
    throw new IOException("HTTP " + response.statusCode() + ": " + response.body());
}
System.out.println(response.body());
```

| Langage | Méthode du SDK | Peut-elle envoyer un fichier ? |
| - | - | - |
| TypeScript | `client.generateTranscription(form)` | Oui. Passez un corps `FormData` et le SDK l’envoie tel quel en multipart. Le cast est nécessaire, car le type de la méthode décrit un corps JSON. |
| Python | `client.generate_transcription(request)` | Non. Elle envoie toujours du JSON : envoyez donc le formulaire avec HTTPX, comme ci-dessus. |
| Go | `client.CreateTranscription(ctx, req)` | Non. Elle envoie du JSON ; utilisez `net/http` et `mime/multipart`. |
| C# | `client.CreateTranscription(request)` | Non. Elle envoie du JSON ; utilisez `HttpClient` et `MultipartFormDataContent`. |
| PHP | `$client->generateTranscription($request)`, alias `createTranscription()` | Non. Elle envoie du JSON ; utilisez l’option `multipart` de Guzzle. |
| Ruby | `client.generate_transcription(...)`, alias `create_transcription` | Non. Elle envoie du JSON ; utilisez `Net::HTTP` et `set_form`. |
| Java | Aucune | Non. Utilisez `java.net.http.HttpClient` avec un corps multipart. |
| Rust | Aucune | Non. `client.post()` n’envoie que du JSON : elle ne fonctionne donc que pour les [sources URL](#transcribe-audio-from-a-url). |

## Transcrire de l’audio depuis une URL

Les modèles Mistral, ElevenLabs et Morpheus peuvent lire l’audio depuis une URL au lieu d’un fichier envoyé. Comme cette requête est en JSON, les méthodes des SDK qui ne savent pas envoyer de fichier la prennent en charge :

```python Python theme={null}
result = client.generate_transcription({
    "model": "mistral/voxtral-mini-transcribe-2",
    "file_url": "https://example.com/call.mp3",
    "language": "en",
})

print(result["text"])
```

```go Go theme={null}
resp, err := client.CreateTranscription(context.Background(), map[string]interface{}{
  "model":    "mistral/voxtral-mini-transcribe-2",
  "file_url": "https://example.com/call.mp3",
  "language": "en",
})
if err != nil {
  panic(err)
}
fmt.Println(resp["text"])
```

```csharp C# theme={null}
var response = await client.CreateTranscription(new Dictionary<string, object>
{
    ["model"] = "mistral/voxtral-mini-transcribe-2",
    ["file_url"] = "https://example.com/call.mp3",
    ["language"] = "en",
});
```

```php PHP theme={null}
$response = $client->generateTranscription([
    'model' => 'mistral/voxtral-mini-transcribe-2',
    'file_url' => 'https://example.com/call.mp3',
    'language' => 'en',
]);

echo $response['text'];
```

```ruby Ruby theme={null}
response = client.generate_transcription(
  model: 'mistral/voxtral-mini-transcribe-2',
  file_url: 'https://example.com/call.mp3',
  language: 'en'
)
```

```rust Rust theme={null}
let response = client.post("/audio/transcriptions", &json!({
    "model": "mistral/voxtral-mini-transcribe-2",
    "file_url": "https://example.com/call.mp3",
    "language": "en"
}))?;

println!("{}", response.body["text"]);
```

## Paramètres

Les noms de champs sont ceux du formulaire (ou du JSON pour une source URL), dans tous les langages.

| Champ | Remarques |
| - | - |
| `model` | Obligatoire. Un identifiant de modèle de transcription. |
| `file` | Le fichier audio envoyé : `aac`, `flac`, `mp3`, `mp4`, `mpeg`, `mpga`, `m4a`, `ogg`, `opus`, `wav` ou `webm`. Obligatoire, sauf avec les options URL ci-dessous. Jusqu’à 25 MB pour la plupart des modèles. |
| `file_url`, `file_id`, `s3_presigned_url` | Les modèles Mistral, ElevenLabs et Morpheus acceptent exactement une source audio : ils peuvent donc utiliser une URL au lieu de `file`. |
| `language` | Indication de langue, comme `en`. |
| `prompt` | Contexte pour améliorer la précision. |
| `temperature` | De `0` à `1` (de `0` à `2` pour ElevenLabs). |
| `response_format` | `json`, `text`, `srt`, `verbose_json`, `vtt` ou `diarized_json`. |
| `timestamp_granularities` | `word` et/ou `segment`. |
| `stream` | Diffuse la transcription au fur et à mesure de sa production, si le modèle le permet. |

Le schéma complet se trouve dans la [référence de l’API Transcriptions](https://phaseo.app/docs/fr/v1/api-reference/endpoint/audio-transcriptions.md).

## Réponse

`AudioTranscriptionResponse`, renvoyé dans le type map de chaque SDK (`map[string]interface{}` en Go, `Dictionary<string, object>?` en C#, un tableau en PHP, un Hash en Ruby) :

```json theme={null}
{
  "text": "Hello world"
}
```


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