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

# Obtenir le statut de la traduction

> Vérifiez le statut d'un projet de traduction et récupérez les résultats

# Obtenir le statut de la traduction

Récupérez le statut actuel d'un projet de traduction. Utilisez ce point de terminaison pour interroger la progression et obtenir l'URL de la vidéo traduite une fois le traitement terminé.

## Requête

### En-têtes

<ParamField header="x-api-key" type="string" required>
  Votre clé API VoiceCheap. Obtenez-en une sur [app.voicecheap.ai/page-api](https://app.voicecheap.ai/page-api).
</ParamField>

### Paramètres de chemin

<ParamField path="projectId" type="string" required>
  L'identifiant unique du projet de traduction renvoyé par le point de terminaison [Start Translation](/docs/fr/api-reference/translate).
</ParamField>

## Réponse

La structure de la réponse varie en fonction du statut de la traduction.

### Champs communs

<ResponseField name="projectId" type="string" required>
  L'identifiant unique du projet
</ResponseField>

<ResponseField name="projectName" type="string" required>
  Le nom du projet
</ResponseField>

<ResponseField name="originalVideoUrl" type="string" required>
  URL du fichier vidéo/audio original téléchargé
</ResponseField>

<ResponseField name="originalLanguage" type="string" required>
  La langue originale détectée ou spécifiée
</ResponseField>

<ResponseField name="targetLanguage" type="string" required>
  La langue cible pour la traduction
</ResponseField>

<ResponseField name="duration" type="number" required>
  Durée du contenu en secondes
</ResponseField>

<ResponseField name="createdAt" type="number" required>
  Horodatage Unix de création du projet
</ResponseField>

<ResponseField name="workflow" type="string" required>
  Flux de travail API ayant créé le projet : `translation` ou `transcription`.
</ResponseField>

<ResponseField name="transcriptionStatus" type="string" required>
  Statut de la transcription source : `processing`, `success` ou `failed`. Ce signal est indépendant de l'achèvement du doublage.
</ResponseField>

<ResponseField name="transcripts" type="object" required>
  Transcriptions normalisées disponibles.

  <Expandable title="propriétés des transcriptions">
    <ResponseField name="transcripts.original" type="object | null">
      Transcription en langue originale lorsqu'elle est disponible, incluant les horodatages et les locuteurs.
    </ResponseField>

    <ResponseField name="transcripts.translations" type="array">
      Transcriptions en langue cible disponibles avec leurs identifiants de langue et de travail.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="workId" type="string">
  Identifiant de travail de traduction pour la version traduite actuellement rapportée.
</ResponseField>

<ResponseField name="translatedVersionId" type="string">
  Identifiant de version traduite pour la version traduite actuellement rapportée.
</ResponseField>

<ResponseField name="actualProgressStep" type="string">
  Étape actuelle du projet. Pendant la création ou la transcription, cela reflète l'étape de création active.
  Les exemples incluent `downloading_content`, `content_validation` et `transcription_processing`.
  Une fois le doublage lancé, il peut passer à une étape de doublage active telle que `smart_sync` ou `audio_assembling`.
  `status: processing` ne s'associe pas avec `actualProgressStep: done`.
</ResponseField>

<ResponseField name="translationAndTranscriptionProgress" type="number">
  Pourcentage de progression approximatif pour la création/transcription du projet (0-100)
</ResponseField>

<ResponseField name="dubbingStep" type="string">
  Étape de doublage actuelle pour la langue cible (par ex. `smart_sync`, `audio_enhancement`, `video_upload`)
</ResponseField>

<ResponseField name="dubbingProgress" type="number">
  Pourcentage de progression approximatif pour le doublage (0-100)
</ResponseField>

<ResponseField name="status" type="string" required>
  Statut actuel de la traduction : `processing`, `success` ou `failed`
</ResponseField>

### Champs Lip Sync

Lorsque la synchronisation labiale a été demandée, la réponse inclut un objet `lipSync` supplémentaire :

<ResponseField name="lipSync" type="object">
  Statut et détails de sortie de la synchronisation labiale (présents uniquement lorsque la synchronisation labiale a été demandée)

  <Expandable title="propriétés lipSync">
    <ResponseField name="lipSync.jobId" type="string">
      Identifiant de tâche de synchronisation labiale
    </ResponseField>

    <ResponseField name="lipSync.status" type="string">
      Statut de la synchronisation labiale : `PENDING`, `PROCESSING`, `COMPLETED`, `FAILED`, `REJECTED` ou `CANCELED`
    </ResponseField>

    <ResponseField name="lipSync.videoUrl" type="string">
      URL de la vidéo avec synchronisation labiale. Utilisez cette URL pour la sortie finale avec synchronisation labiale lorsque `lipSync.status` est `COMPLETED`.
    </ResponseField>

    <ResponseField name="lipSync.errorMessage" type="string">
      Détails de l'erreur si la synchronisation labiale a échoué
    </ResponseField>

    <ResponseField name="lipSync.type" type="string">
      Mode de synchronisation labiale : `standard`, `pro` ou `studio`.
    </ResponseField>

    <ResponseField name="lipSync.createdAt" type="string">
      Horodatage ISO de création de la tentative de synchronisation labiale.
    </ResponseField>

    <ResponseField name="lipSync.requestedAt" type="string">
      Horodatage ISO de demande de la tentative de synchronisation labiale, lorsqu'il est disponible.
    </ResponseField>

    <ResponseField name="lipSync.completedAt" type="string">
      Horodatage ISO d'achèvement de la synchronisation labiale, lorsqu'il est disponible.
    </ResponseField>

    <ResponseField name="lipSync.failedAt" type="string">
      Horodatage ISO d'échec de la synchronisation labiale, lorsqu'il est disponible.
    </ResponseField>

    <ResponseField name="lipSync.timedOutAt" type="string">
      Horodatage ISO du moment où la synchronisation labiale a expiré, le cas échéant.
    </ResponseField>

    <ResponseField name="lipSync.activeSpeakerDetectionEnabled" type="boolean">
      Indique si la détection du locuteur actif était activée pour cette tentative de synchronisation labiale.
    </ResponseField>
  </Expandable>
</ResponseField>

<Info>
  Lorsqu'une synchronisation labiale est demandée, la traduction reste dans `processing` jusqu'à ce que `lipSync.status` soit `COMPLETED`. Si la synchronisation labiale échoue, le statut devient
  `failed` et `error.code` est `LIPSYNC_FAILED`. Lorsque la synchronisation labiale réussit, lisez l'élément synchronisé depuis `lipSync.videoUrl` ; `translatedVideoUrl`
  est la sortie vidéo traduite avant la superposition de la synchronisation labiale.
</Info>

<Tip>Utilisez `GET /v1/projects/{projectId}` lorsque vous avez besoin de l'historique complet des versions traduites ou de l'historique complet de la synchronisation labiale.</Tip>

### Champs de réponse en cas de succès

Pour les flux de travail de traduction, les champs suivants sont inclus lorsque `status` est `success`. Un flux de travail de transcription seule atteint `success` sans champs de média traduits.

<ResponseField name="translatedVideoUrl" type="string">
  URL pour télécharger le fichier vidéo traduit
</ResponseField>

<ResponseField name="translatedAudioUrl" type="string">
  URL pour télécharger le fichier audio traduit séparément
</ResponseField>

### Champs de réponse en cas d'échec

Lorsque `status` est `failed`, le champ supplémentaire suivant est inclus :

<ResponseField name="error" type="object">
  Détails de l'erreur

  <Expandable title="propriétés de l'erreur">
    <ResponseField name="error.code" type="string">
      Code d'erreur lisible par machine
    </ResponseField>

    <ResponseField name="error.message" type="string">
      Description de l'erreur lisible par l'homme
    </ResponseField>
  </Expandable>
</ResponseField>

## Exemples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.voicecheap.ai/v1/translate/abc123-def456-ghi789/status" \
    -H "x-api-key: vc_your-api-key"
  ```

  ```typescript TypeScript theme={null}
  type TranslationStatus = 'processing' | 'success' | 'failed';

  interface Transcript {
    source: 'original' | 'translated';
    language: string;
    text: string;
    segments: Array<{
      index: number;
      text: string;
      begin: number;
      end: number;
      speaker: number;
    }>;
  }

  interface TranslationStatusBase {
    projectId: string;
    projectName: string;
    originalVideoUrl: string;
    originalLanguage: string;
    targetLanguage: string;
    duration: number;
    createdAt: number;
    workflow: 'translation' | 'transcription';
    transcriptionStatus: TranslationStatus;
    transcripts: {
      original: Transcript | null;
      translations: Transcript[];
    };
    workId?: string;
    translatedVersionId?: string;
    actualProgressStep?: string;
    translationAndTranscriptionProgress?: number;
    dubbingStep?: string;
    dubbingProgress?: number;
    lipSync?: {
      jobId: string;
      status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED' | 'REJECTED' | 'CANCELED';
      videoUrl: string;
      errorMessage: string | null;
      type: 'standard' | 'pro' | 'studio';
      createdAt?: string;
      requestedAt?: string;
      completedAt?: string;
      failedAt?: string;
      timedOutAt?: string;
      activeSpeakerDetectionEnabled?: boolean;
    };
  }

  interface TranslationStatusProcessing extends TranslationStatusBase {
    status: 'processing';
  }

  interface TranslationStatusSuccess extends TranslationStatusBase {
    status: 'success';
    translatedVideoUrl?: string;
    translatedAudioUrl?: string;
  }

  interface TranslationStatusFailed extends TranslationStatusBase {
    status: 'failed';
    error: {
      code: string;
      message: string;
    };
  }

  type TranslationStatusResponse = TranslationStatusProcessing | TranslationStatusSuccess | TranslationStatusFailed;

  async function getTranslationStatus(projectId: string): Promise<TranslationStatusResponse> {
    const response = await fetch(`https://api.voicecheap.ai/v1/translate/${projectId}/status`, {
      method: 'GET',
      headers: {
        'x-api-key': 'vc_your-api-key',
      },
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message || 'Failed to get status');
    }

    return response.json();
  }

  // Polling function with typed response handling
  async function pollUntilComplete(projectId: string, intervalMs: number = 10000): Promise<TranslationStatusSuccess> {
    while (true) {
      const status = await getTranslationStatus(projectId);

      if (status.status === 'success') {
        return status;
      }

      if (status.status === 'failed') {
        throw new Error(`Translation failed: ${status.error.message}`);
      }

      console.log('Still processing...');
      await new Promise((resolve) => setTimeout(resolve, intervalMs));
    }
  }

  // Usage
  try {
    const result = await pollUntilComplete('abc123-def456-ghi789');
    console.log('Translated video:', result.translatedVideoUrl);
    console.log('Translated audio:', result.translatedAudioUrl);
  } catch (error) {
    console.error('Error:', error);
  }
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.voicecheap.ai/v1/translate/abc123-def456-ghi789/status', {
    method: 'GET',
    headers: {
      'x-api-key': 'vc_your-api-key',
    },
  });

  const status = await response.json();

  if (status.status === 'success') {
    console.log('Translated video:', status.translatedVideoUrl);
  } else if (status.status === 'processing') {
    console.log('Still processing...');
  } else if (status.status === 'failed') {
    console.error('Translation failed:', status.error.message);
  }
  ```

  ```python Python theme={null}
  import requests
  import time

  headers = {'x-api-key': 'vc_your-api-key'}
  project_id = 'abc123-def456-ghi789'

  # Poll until complete
  while True:
      response = requests.get(
          f'https://api.voicecheap.ai/v1/translate/{project_id}/status',
          headers=headers
      )
      status = response.json()

      if status['status'] == 'success':
          print(f"Translated video: {status['translatedVideoUrl']}")
          print(f"Translated audio: {status['translatedAudioUrl']}")
          break
      elif status['status'] == 'failed':
          print(f"Translation failed: {status['error']['message']}")
          break
      else:
          print("Still processing...")
          time.sleep(10)  # Wait 10 seconds before polling again
  ```

  ```php PHP theme={null}
  <?php
  $apiKey = 'vc_your-api-key';
  $projectId = 'abc123-def456-ghi789';

  $curl = curl_init();

  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.voicecheap.ai/v1/translate/{$projectId}/status",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          "x-api-key: {$apiKey}"
      ]
  ]);

  $response = curl_exec($curl);
  $status = json_decode($response, true);

  switch ($status['status']) {
      case 'success':
          echo "Translated video: " . $status['translatedVideoUrl'] . "\n";
          echo "Translated audio: " . $status['translatedAudioUrl'];
          break;
      case 'processing':
          echo "Still processing...";
          break;
      case 'failed':
          echo "Failed: " . $status['error']['message'];
          break;
  }
  ```
</CodeGroup>

## Exemples de réponse

### Statut de traitement

```json theme={null}
{
  "projectId": "abc123-def456-ghi789",
  "projectName": "My Spanish Translation",
  "originalVideoUrl": "https://storage.voicecheap.ai/...",
  "originalLanguage": "en",
  "targetLanguage": "spanish",
  "duration": 125.5,
  "createdAt": 1702234567890,
  "workflow": "translation",
  "transcriptionStatus": "processing",
  "transcripts": { "original": null, "translations": [] },
  "actualProgressStep": "downloading_content",
  "translationAndTranscriptionProgress": 11,
  "dubbingStep": "smart_sync",
  "dubbingProgress": 30,
  "status": "processing"
}
```

### Statut de traitement (Lip Sync demandé)

```json theme={null}
{
  "projectId": "abc123-def456-ghi789",
  "projectName": "My Spanish Translation",
  "originalVideoUrl": "https://storage.voicecheap.ai/...",
  "originalLanguage": "en",
  "targetLanguage": "spanish",
  "duration": 125.5,
  "createdAt": 1702234567890,
  "workflow": "translation",
  "transcriptionStatus": "success",
  "transcripts": { "original": null, "translations": [] },
  "actualProgressStep": "finalizing",
  "translationAndTranscriptionProgress": 95,
  "dubbingStep": "video_upload",
  "dubbingProgress": 95,
  "status": "processing",
  "lipSync": {
    "jobId": "syncjob_123",
    "status": "PROCESSING",
    "videoUrl": "",
    "errorMessage": null,
    "type": "standard"
  }
}
```

### Statut de succès

```json theme={null}
{
  "projectId": "abc123-def456-ghi789",
  "projectName": "My Spanish Translation",
  "originalVideoUrl": "https://storage.voicecheap.ai/...",
  "originalLanguage": "en",
  "targetLanguage": "spanish",
  "duration": 125.5,
  "createdAt": 1702234567890,
  "workflow": "translation",
  "transcriptionStatus": "success",
  "transcripts": { "original": null, "translations": [] },
  "status": "success",
  "translatedVideoUrl": "https://storage.voicecheap.ai/translated/...",
  "translatedAudioUrl": "https://storage.voicecheap.ai/audio/..."
}
```

### Statut de succès (Lip Sync terminé)

```json theme={null}
{
  "projectId": "abc123-def456-ghi789",
  "projectName": "My Spanish Translation",
  "originalVideoUrl": "https://storage.voicecheap.ai/...",
  "originalLanguage": "en",
  "targetLanguage": "spanish",
  "duration": 125.5,
  "createdAt": 1702234567890,
  "workflow": "translation",
  "transcriptionStatus": "success",
  "transcripts": { "original": null, "translations": [] },
  "actualProgressStep": "done",
  "dubbingStep": "done",
  "dubbingProgress": 100,
  "status": "success",
  "translatedVideoUrl": "https://storage.voicecheap.ai/translated/...",
  "translatedAudioUrl": "https://storage.voicecheap.ai/audio/...",
  "lipSync": {
    "jobId": "syncjob_123",
    "status": "COMPLETED",
    "videoUrl": "https://storage.voicecheap.ai/lipsync/...",
    "errorMessage": null,
    "type": "pro"
  }
}
```

### Statut d'échec

```json theme={null}
{
  "projectId": "abc123-def456-ghi789",
  "projectName": "My Spanish Translation",
  "originalVideoUrl": "https://storage.voicecheap.ai/...",
  "originalLanguage": "en",
  "targetLanguage": "spanish",
  "duration": 125.5,
  "createdAt": 1702234567890,
  "workflow": "translation",
  "transcriptionStatus": "failed",
  "transcripts": { "original": null, "translations": [] },
  "status": "failed",
  "error": {
    "code": "TRANSCRIPTION_FAILED",
    "message": "Could not transcribe the audio. Please ensure the audio quality is sufficient."
  }
}
```

## Bonnes pratiques d'interrogation

<Info>
  **Intervalle d'interrogation recommandé :** 10-30 secondes

  Le temps de traduction varie en fonction de la durée et de la complexité de la vidéo. Pour une vidéo typique de 2 minutes, prévoyez 2 à 5 minutes de temps de traitement.
</Info>

<Warning>
  **Limite de débit :** 30 requêtes par minute

  Évitez d'interroger plus d'une fois toutes les 2 secondes pour rester dans les limites de débit.
</Warning>

## Erreurs

| Statut | Code                  | Description                                        |
| ------ | --------------------- | -------------------------------------------------- |
| 401    | `INVALID_API_KEY`     | La clé API fournie est invalide                    |
| 403    | `FORBIDDEN`           | Vous n'avez pas accès à ce projet                  |
| 404    | `PROJECT_NOT_FOUND`   | Le projet spécifié n'existe pas                    |
| 429    | `RATE_LIMIT_EXCEEDED` | Trop de requêtes (limite : 30 requêtes par minute) |
