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

# 翻訳ステータスの取得

> 翻訳プロジェクトのステータスを確認し、結果を取得します

# 翻訳ステータスの取得

翻訳プロジェクトの現在のステータスを取得します。このエンドポイントを使用して進捗状況をポーリングし、処理完了時に翻訳済み動画のURLを取得します。

## リクエスト

### ヘッダー

<ParamField header="x-api-key" type="string" required>
  VoiceCheap APIキー。[app.voicecheap.ai/page-api](https://app.voicecheap.ai/page-api)から取得してください。
</ParamField>

### パスパラメータ

<ParamField path="projectId" type="string" required>
  [Start Translation](/docs/ja/api-reference/translate)エンドポイントから返される翻訳プロジェクトの一意の識別子。
</ParamField>

## レスポンス

レスポンス構造は翻訳ステータスによって異なります。

### 共通フィールド

<ResponseField name="projectId" type="string" required>
  プロジェクトの一意の識別子
</ResponseField>

<ResponseField name="projectName" type="string" required>
  プロジェクト名
</ResponseField>

<ResponseField name="originalVideoUrl" type="string" required>
  アップロードされた元の動画/音声ファイルのURL
</ResponseField>

<ResponseField name="originalLanguage" type="string" required>
  検出または指定された元の言語
</ResponseField>

<ResponseField name="targetLanguage" type="string" required>
  翻訳先の言語
</ResponseField>

<ResponseField name="duration" type="number" required>
  コンテンツの長さ（秒単位）
</ResponseField>

<ResponseField name="createdAt" type="number" required>
  プロジェクトが作成されたUnixタイムスタンプ
</ResponseField>

<ResponseField name="workflow" type="string" required>
  プロジェクトを作成したAPIワークフロー：`translation`または`transcription`。
</ResponseField>

<ResponseField name="transcriptionStatus" type="string" required>
  ソース文字起こしステータス：`processing`、`success`、または`failed`。このシグナルは吹き替えの完了とは独立しています。
</ResponseField>

<ResponseField name="transcripts" type="object" required>
  利用可能な正規化された文字起こし。

  <Expandable title="transcriptsプロパティ">
    <ResponseField name="transcripts.original" type="object | null">
      利用可能な場合の、タイムスタンプと話者を含む元の言語の文字起こし。
    </ResponseField>

    <ResponseField name="transcripts.translations" type="array">
      言語および作業識別子を含む、利用可能な翻訳先言語の文字起こし。
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="workId" type="string">
  現在報告されている翻訳バージョンの翻訳作業識別子。
</ResponseField>

<ResponseField name="translatedVersionId" type="string">
  現在報告されている翻訳バージョンの翻訳済みバージョン識別子。
</ResponseField>

<ResponseField name="actualProgressStep" type="string">
  現在のプロジェクトステップ。作成中または文字起こし中は、アクティブな作成ステップを反映します。
  例として、`downloading_content`、`content_validation`、`transcription_processing`などがあります。
  吹き替えが開始されると、`smart_sync`や`audio_assembling`などのアクティブな吹き替えステップに切り替わることがあります。
  `status: processing`は`actualProgressStep: done`とペアになりません。
</ResponseField>

<ResponseField name="translationAndTranscriptionProgress" type="number">
  プロジェクト作成/文字起こしの概算進捗率（0-100）
</ResponseField>

<ResponseField name="dubbingStep" type="string">
  翻訳先言語の現在の吹き替えステップ（例：`smart_sync`、`audio_enhancement`、`video_upload`）
</ResponseField>

<ResponseField name="dubbingProgress" type="number">
  吹き替えの概算進捗率（0-100）
</ResponseField>

<ResponseField name="status" type="string" required>
  翻訳の現在のステータス：`processing`、`success`、または`failed`
</ResponseField>

### Lip Syncフィールド

リップシンクがリクエストされた場合、レスポンスには追加の`lipSync`オブジェクトが含まれます：

<ResponseField name="lipSync" type="object">
  リップシンクのステータスと出力詳細（リップシンクがリクエストされた場合にのみ存在）

  <Expandable title="lipSyncプロパティ">
    <ResponseField name="lipSync.jobId" type="string">
      リップシンクジョブ識別子
    </ResponseField>

    <ResponseField name="lipSync.status" type="string">
      リップシンクステータス：`PENDING`、`PROCESSING`、`COMPLETED`、`FAILED`、`REJECTED`、または`CANCELED`
    </ResponseField>

    <ResponseField name="lipSync.videoUrl" type="string">
      リップシンクされた動画のURL。`lipSync.status`が`COMPLETED`の場合、このURLを最終的なリップシンク出力として使用してください。
    </ResponseField>

    <ResponseField name="lipSync.errorMessage" type="string">
      リップシンクが失敗した場合のエラー詳細
    </ResponseField>

    <ResponseField name="lipSync.type" type="string">
      リップシンクモード：`standard`、`pro`、または`studio`。
    </ResponseField>

    <ResponseField name="lipSync.createdAt" type="string">
      リップシンク試行が作成されたISOタイムスタンプ。
    </ResponseField>

    <ResponseField name="lipSync.requestedAt" type="string">
      利用可能な場合の、リップシンク試行がリクエストされたISOタイムスタンプ。
    </ResponseField>

    <ResponseField name="lipSync.completedAt" type="string">
      利用可能な場合の、リップシンクが完了したISOタイムスタンプ。
    </ResponseField>

    <ResponseField name="lipSync.failedAt" type="string">
      利用可能な場合の、リップシンクが失敗したISOタイムスタンプ。
    </ResponseField>

    <ResponseField name="lipSync.timedOutAt" type="string">
      リップシンクがタイムアウトした際のISOタイムスタンプ（利用可能な場合）。
    </ResponseField>

    <ResponseField name="lipSync.activeSpeakerDetectionEnabled" type="boolean">
      このリップシンクの試行において、アクティブスピーカー検出が有効であったかどうか。
    </ResponseField>
  </Expandable>
</ResponseField>

<Info>
  リップシンクがリクエストされると、翻訳は`lipSync.status`が`COMPLETED`になるまで`processing`の状態を維持します。リップシンクが失敗した場合、ステータスは
  `failed`となり、`error.code`は`LIPSYNC_FAILED`となります。リップシンクが成功した場合は、`lipSync.videoUrl`からリップシンク済みのアセットを読み取ってください。`translatedVideoUrl`
  は、リップシンクオーバーレイ適用前の翻訳済みビデオ出力です。
</Info>

<Tip>完全な翻訳バージョン履歴または完全なリップシンク履歴が必要な場合は、`GET /v1/projects/{projectId}`を使用してください。</Tip>

### 成功時のレスポンスフィールド

翻訳ワークフローの場合、`status`が`success`のときに以下のフィールドが含まれます。文字起こしのみのワークフローでは、翻訳済みメディアフィールドを含まずに`success`に到達します。

<ResponseField name="translatedVideoUrl" type="string">
  翻訳済みビデオファイルをダウンロードするためのURL
</ResponseField>

<ResponseField name="translatedAudioUrl" type="string">
  翻訳済みオーディオファイルを個別にダウンロードするためのURL
</ResponseField>

### 失敗時のレスポンスフィールド

`status`が`failed`のとき、以下の追加フィールドが含まれます：

<ResponseField name="error" type="object">
  エラーの詳細

  <Expandable title="エラープロパティ">
    <ResponseField name="error.code" type="string">
      マシン可読なエラーコード
    </ResponseField>

    <ResponseField name="error.message" type="string">
      人間が読める形式のエラー説明
    </ResponseField>
  </Expandable>
</ResponseField>

## 例

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

## レスポンスの例

### 処理ステータス

```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"
}
```

### 処理ステータス（Lip Syncリクエスト済み）

```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"
  }
}
```

### 成功ステータス

```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/..."
}
```

### 成功ステータス（Lip Sync完了）

```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"
  }
}
```

### 失敗ステータス

```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."
  }
}
```

## ポーリングのベストプラクティス

<Info>
  **推奨ポーリング間隔：** 10〜30秒

  翻訳時間はビデオの長さと複雑さによって異なります。一般的な2分間のビデオの場合、2〜5分の処理時間を見込んでください。
</Info>

<Warning>
  **レート制限：** 1分間に30リクエスト

  レート制限内に収めるため、2秒に1回を超える頻度でのポーリングは避けてください。
</Warning>

## エラー

| ステータス | コード                   | 説明                          |
| ----- | --------------------- | --------------------------- |
| 401   | `INVALID_API_KEY`     | 提供されたAPIキーが無効です             |
| 403   | `FORBIDDEN`           | このプロジェクトへのアクセス権がありません       |
| 404   | `PROJECT_NOT_FOUND`   | 指定されたプロジェクトは存在しません          |
| 429   | `RATE_LIMIT_EXCEEDED` | リクエストが多すぎます（制限：1分間に30リクエスト） |
