認証
API Key 認証フロー
NoLang API は API Key 形式の認証を使用します。すべてのリクエストに以下のヘッダーを含めてください。
Authorization: Bearer YOUR_API_KEYAPIキーの管理
- 生成 サイドバー: NoLang API > APIキーから API キーを生成
- 権限 API キーはユーザーアカウントと同じ権限を持ちます
- 削除 使用しなくなったキーは速やかに削除してください
セキュリティベストプラクティス
- 環境変数で管理 ハードコーディングを避ける
- HTTPS 通信のみ すべての API 通信は HTTPS 経由
- 定期的に鍵をローテーションする
# キーを非表示で入力read -rsp "NoLang APIキーを入力してください: " NOLANG_API_KEY && echo
# そのまま API を呼び出すcurl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer $NOLANG_API_KEY" \ -F "video_setting_id=$VIDEO_SETTING_ID" \ -F "text=こんにちは、NoLang APIのテストです。"
# 使い終わったら念のため変数を消去unset NOLANG_API_KEY共通仕様
ベースURL・バージョン
- Production:
https://api.no-lang.com/v1 - バージョニング: URL パスにバージョンを含む(現在は v1)
リクエスト形式
Headers
Authorization: Bearer YOUR_API_KEYContent-Type: multipart/form-data # ファイルアップロード時Content-Type: application/json # JSONリクエスト時Pagination
リスト系エンドポイントでは以下のクエリパラメータを使用します。
-
pageページ番号(1 から開始) - 1 ページあたり 50 件固定
curl "https://api.no-lang.com/v1/videos/?page=2" \ -H "Authorization: Bearer YOUR_API_KEY"Rate Limit・同時実行制限
Rate Limit
| エンドポイント | 制限 | 超過時 |
|---|---|---|
POST /videos/generate/POST /videos/{video_id}/conversions/ | 10 秒に 2 回まで | 429 エラー |
| その他のエンドポイント | 10 秒に 5 回まで(2 秒に 1 回) | 429 エラー |
同時実行制限
- 動画生成: 1 ユーザーアカウントあたり最大 2 つまで並列生成可能。超過時は 503 エラー。
- 動画変換も動画生成と共通の同時実行制限の対象です。超過時は 503 エラー。
- 注意: API キー単位ではなく、ユーザーアカウント単位での制限です。複数の API キーを発行しても、同時生成数は増えません。
エラーハンドリング
エラーレスポンス形式
{ "error_code": "ERROR_CODE", "error": "エラーの詳細説明"}リトライ戦略
- 5xx 系エラー: 指数バックオフで最大 3 回リトライ
- 503 エラー: サーバー負荷が下がるまで待機(推奨: 30 秒〜1 分後)
- 429 エラー: レート制限解除まで待機
- その他: リトライ不要
エンドポイント
POST /videos/generate/
新しい動画の生成をリクエストします。
パラメータ
| 名前 | 型 | 個人プラン | 法人プラン | 必須 | 説明 | ||
|---|---|---|---|---|---|---|---|
| 対応形式 | サイズ | 対応形式 | サイズ | ||||
video_setting_id | string (UUID) | 必須 | 使用する動画設定の ID | ||||
text | string | 条件付き | 動画生成用テキスト(質問/指示から作るモード時必須) | ||||
pdf_file | file | 100MB | 180MB | 条件付き | PDF ファイル(資料から作るモード時必須) | ||
pptx_file | file | .pptx | 100MB | .pptx | 180MB | 条件付き | PPTX ファイル(資料から作るモード時必須) |
audio_file | file | .mp3, .wav, .m4a, .aac | 50MB | .mp3, .wav, .m4a, .aac | 180MB | 条件付き | 音声ファイル(音声から作るモード時必須) |
video_file | file | .mp4 | 50MB | .mp4, .mov, .webm | 180MB | 条件付き | 動画ファイル(動画から作るモード時必須) |
image_files | list of file | .png, .jpg, .jpeg, .webp | 10MB x 10 | .png, .jpg, .jpeg, .webp | 10MB x 10 | 任意 | 画像ファイルのリスト(質問/指示から作るモード時に指定可能) |
レスポンス例
{ "video_id": "550e8400-e29b-41d4-a716-446655440000"}動画モード別リクエスト例
curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "text=機械学習とは何ですか?簡潔に説明してください"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "text=NoLangとは、Mavericks 社によって開発されたリアルタイムで動画を生成するサービスです。"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "pdf_file=@company_presentation.pdf"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "pptx_file=@annual_report.pptx"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "text=競合他社と比較しながら、この企業の強みと弱みを分析してください" \ -F "pdf_file=@company_report_2024.pdf"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "audio_file=@lecture_recording.mp3"curl -X POST https://api.no-lang.com/v1/videos/generate/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "video_setting_id=YOUR_VIDEO_SETTING_ID" \ -F "video_file=@original_video.mp4" GET /videos/
生成した動画のリストを取得します。
クエリパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
page | integer | 任意 | ページ番号(デフォルト: 1) |
レスポンス例
{ "results": [ { "video_id": "550e8400-e29b-41d4-a716-446655440000", "created_at": "2024-01-15T09:30:00Z", "prompt": "AIの進化について5分で解説します。" }, { "video_id": "660e8400-e29b-41d4-a716-446655440001", "created_at": "2024-01-15T08:20:00Z", "prompt": "マーケティング戦略の基礎" } ], "has_next": false, "total_count": 5, "page": 1, "items_per_page": 50} GET /videos/{video_id}/
特定の動画の生成ステータスとダウンロード URL を取得します。
パスパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
video_id | string (UUID) | 必須 | 動画 ID |
ステータス値
running— 生成処理中-
completed— 生成完了(ダウンロード可能) failed— 生成失敗expired— 有効期限切れ
レスポンス例
{ "video_id": "550e8400-e29b-41d4-a716-446655440000", "status": "running", "download_url": "", "copyright": []}{ "video_id": "550e8400-e29b-41d4-a716-446655440000", "status": "completed", "download_url": "https://s3.no-lang.com/asset/example.mp4?X-Amz-Algorithm=...", "copyright": [...]}-
completed状態の動画のみダウンロード可能 -
download_urlは一時的なプリサインド URL です(有効期限あり)
GET /videos/{video_id}/conversions/
特定の動画が言語・アスペクト比変換に対応しているかと、変換先として指定できる値の一覧を取得します。
パスパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
video_id | string (UUID) | 必須 | 変換元動画の ID。自分が所有する動画のみ指定可能 |
レスポンスフィールド
-
is_convertible— この動画が変換に対応しているか。生成済みの動画データが無い場合やリアルアバターを含む場合は false -
current_language— 変換元動画の現在の言語 -
available_languages— 変換先に指定できる言語コードの一覧(動画ごとに異なる) -
current_aspect_ratio— 変換元動画の現在のアスペクト比 -
available_aspect_ratios— 変換先に指定できるアスペクト比の一覧(変換可能な動画では常に全 7 種)
レスポンス例
{ "is_convertible": true, "current_language": "ja", "available_languages": ["ja", "en"], "current_aspect_ratio": "16:9", "available_aspect_ratios": ["16:9", "9:16", "4:3", "1:1", "4:5", "2:3", "21:9"]} POST /videos/{video_id}/conversions/
既存の動画を別の言語・アスペクト比に変換した新しい動画を非同期で生成します。変換元の動画は変更されません。レスポンスで返る新しい
video_id
を
GET /videos/{video_id}/
でポーリングして、動画生成と同じ流れで完了を確認してください。
パラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
language | string | 条件付き | 変換後の言語コード。aspect_ratio と少なくともどちらか一方の指定が必須。変換元動画と同じ値は指定不可 |
aspect_ratio | string | 条件付き | 変換後のアスペクト比。language と少なくともどちらか一方の指定が必須。変換元動画と同じ値は指定不可 |
aspect_ratio に指定できる値
16:9 9:16 4:3 1:1 4:5 2:3 21:9
language に指定できる値(全 34 言語)
- 日本語
ja - 英語
en - 中国語(簡体)
zh-Hans - 中国語(繁体)
zh-Hant - 韓国語
ko - スペイン語
es - フランス語
fr - ドイツ語
de - イタリア語
it - ポルトガル語
pt - ロシア語
ru - ヒンディー語
hi - ベンガル語
bn - インドネシア語
id - タイ語
th - ベトナム語
vi - タガログ語
tl - マレー語
ms - ミャンマー語
my - ネパール語
ne - モンゴル語
mn - トルコ語
tr - スウェーデン語
sv - デンマーク語
da - フィンランド語
fi - ポーランド語
pl - チェコ語
cs - スロバキア語
sk - オランダ語
nl - ルーマニア語
ro - クロアチア語
hr - ブルガリア語
bg - ウクライナ語
uk - ギリシャ語
el
レスポンス例
{ "video_id": "550e8400-e29b-41d4-a716-446655440000"}-
video_idは変換後の動画として新規作成される動画の ID です(変換元の ID とは別)
エラーコード
| error_code | HTTP | 条件 |
|---|---|---|
CONVERT_TARGET_REQUIRED | 400 | language / aspect_ratio の両方が未指定 |
INVALID_LANGUAGE | 400 | language が対応言語コード以外の値 |
INVALID_ASPECT_RATIO | 400 | aspect_ratio が対応値以外の値 |
LANGUAGE_NOT_SUPPORTED_BY_VOICES | 400 | 指定した language が変換元動画の available_languages に含まれない |
CONVERT_NO_CHANGE | 400 | 指定値がすべて変換元動画と同一(変化がない) |
SOURCE_VIDEO_NOT_CONVERTIBLE | 400 | 変換元動画が変換に対応していない(is_convertible が false) |
UNSUPPORTED_HEAVY_AVATAR | 400 | 変換元動画がリアルアバターを含む |
NOT_FOUND | 404 | video_id が存在しない、または自分が所有する動画でない |
INSUFFICIENT_CREDIT | 429 / 403 | クレジット残高不足(429)、またはスタンダード / プレミアムプラン未満(403) |
SIMULTANEOUS_GENERATE_LIMIT | 503 | 動画生成と共通の同時実行上限を超過 |
UNKNOWN_ERROR | 500 | サーバー内部エラー |
- 認証に失敗した場合は上記とは別に 401 / 403 エラーが返ります
リクエスト例
curl https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \ -H "Authorization: Bearer YOUR_API_KEY"curl -X POST https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"language": "en"}'curl -X POST https://api.no-lang.com/v1/videos/YOUR_VIDEO_ID/conversions/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"aspect_ratio": "9:16"}' GET /video-settings/
利用可能な動画設定のリストを取得します。
レスポンス例
{ "results": [ { "video_setting_id": "123e4567-e89b-12d3-a456-426614174000", "updated_at": "2024-01-15T10:00:00Z", "created_at": "2024-01-10T10:00:00Z", "title": "教育コンテンツ用設定", "request_fields": ["text"] }, { "video_setting_id": "223e4567-e89b-12d3-a456-426614174001", "updated_at": "2024-01-14T09:00:00Z", "created_at": "2024-01-09T09:00:00Z", "title": "プレゼンテーション変換用", "request_fields": ["pdf_file"] } ], "has_next": false, "total_count": 5, "page": 1, "items_per_page": 50}サンプルコード
import osimport timeimport requestsfrom typing import Optional
class NoLangAPI: def __init__(self, api_key: str): self.api_key = api_key self.base_url = "https://api.no-lang.com/v1" self.headers = {"Authorization": f"Bearer {api_key}"}
def generate_video_from_text(self, video_setting_id: str, text: str) -> dict: """テキストから動画を生成""" url = f"{self.base_url}/videos/generate/" data = { "video_setting_id": video_setting_id, "text": text } response = requests.post(url, headers=self.headers, data=data) response.raise_for_status() return response.json()
def generate_video_from_pdf(self, video_setting_id: str, pdf_path: str) -> dict: """PDFから動画を生成""" url = f"{self.base_url}/videos/generate/" data = {"video_setting_id": video_setting_id} files = {"pdf_file": open(pdf_path, "rb")} response = requests.post(url, headers=self.headers, data=data, files=files) response.raise_for_status() return response.json()
def get_video_status(self, video_id: str) -> dict: """動画のステータスを取得""" url = f"{self.base_url}/videos/{video_id}/" response = requests.get(url, headers=self.headers) response.raise_for_status() return response.json()
def get_convert_options(self, video_id: str) -> dict: """動画の変換可能性と変換先に指定できる値を取得""" url = f"{self.base_url}/videos/{video_id}/conversions/" response = requests.get(url, headers=self.headers) response.raise_for_status() return response.json()
def convert_video( self, video_id: str, language: Optional[str] = None, aspect_ratio: Optional[str] = None, ) -> dict: """動画を別の言語・アスペクト比に変換した新しい動画を生成""" url = f"{self.base_url}/videos/{video_id}/conversions/" payload = {} if language: payload["language"] = language if aspect_ratio: payload["aspect_ratio"] = aspect_ratio response = requests.post(url, headers=self.headers, json=payload) response.raise_for_status() return response.json()
def wait_for_completion(self, video_id: str, timeout: int = 600) -> Optional[str]: """動画生成の完了を待機し、ダウンロードURLを返す""" start_time = time.time() while time.time() - start_time < timeout: status_data = self.get_video_status(video_id) if status_data["status"] == "completed": return status_data["download_url"] elif status_data["status"] == "failed": raise Exception("Video generation failed") time.sleep(10) # 10秒ごとにポーリング raise TimeoutError("Video generation timed out")
# 使用例api = NoLangAPI(os.environ["NOLANG_API_KEY"])
# テキストから動画生成result = api.generate_video_from_text( video_setting_id="123e4567-e89b-12d3-a456-426614174000", text="Pythonプログラミングの基礎を学びましょう")print(f"Video ID: {result['video_id']}")
# 完了を待機してダウンロードdownload_url = api.wait_for_completion(result['video_id'])print(f"Download URL: {download_url}")
# 生成した動画を英語 + 縦型 (9:16) に変換options = api.get_convert_options(result['video_id'])if options["is_convertible"] and "en" in options["available_languages"]: converted = api.convert_video(result['video_id'], language="en", aspect_ratio="9:16") converted_url = api.wait_for_completion(converted['video_id']) print(f"Converted URL: {converted_url}")const axios = require('axios');const FormData = require('form-data');const fs = require('fs');
class NoLangAPI { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://api.no-lang.com/v1'; this.headers = { 'Authorization': `Bearer ${apiKey}` }; }
async generateVideoFromText(videoSettingId, text) { const formData = new FormData(); formData.append('video_setting_id', videoSettingId); formData.append('text', text);
const response = await axios.post( `${this.baseUrl}/videos/generate/`, formData, { headers: { ...this.headers, ...formData.getHeaders() } } ); return response.data; }
async generateVideoFromPDF(videoSettingId, pdfPath) { const formData = new FormData(); formData.append('video_setting_id', videoSettingId); formData.append('pdf_file', fs.createReadStream(pdfPath));
const response = await axios.post( `${this.baseUrl}/videos/generate/`, formData, { headers: { ...this.headers, ...formData.getHeaders() } } ); return response.data; }
async getVideoStatus(videoId) { const response = await axios.get( `${this.baseUrl}/videos/${videoId}/`, { headers: this.headers } ); return response.data; }
async getConvertOptions(videoId) { const response = await axios.get( `${this.baseUrl}/videos/${videoId}/conversions/`, { headers: this.headers } ); return response.data; }
async convertVideo(videoId, { language, aspectRatio } = {}) { const payload = {}; if (language) payload.language = language; if (aspectRatio) payload.aspect_ratio = aspectRatio;
const response = await axios.post( `${this.baseUrl}/videos/${videoId}/conversions/`, payload, { headers: { ...this.headers, 'Content-Type': 'application/json' } } ); return response.data; }
async waitForCompletion(videoId, timeout = 600000) { const startTime = Date.now();
while (Date.now() - startTime < timeout) { const status = await this.getVideoStatus(videoId);
if (status.status === 'completed') { return status.download_url; } else if (status.status === 'failed') { throw new Error('Video generation failed'); }
// 10秒待機 await new Promise(resolve => setTimeout(resolve, 10000)); }
throw new Error('Video generation timed out'); }}
// 使用例(async () => { const api = new NoLangAPI(process.env.NOLANG_API_KEY);
try { // テキストから動画生成 const result = await api.generateVideoFromText( '123e4567-e89b-12d3-a456-426614174000', 'JavaScriptの非同期処理について解説します' );
console.log(`Video ID: ${result.video_id}`);
// 完了を待機 const downloadUrl = await api.waitForCompletion(result.video_id); console.log(`Download URL: ${downloadUrl}`);
// 生成した動画を英語 + 縦型 (9:16) に変換 const options = await api.getConvertOptions(result.video_id); if (options.is_convertible && options.available_languages.includes('en')) { const converted = await api.convertVideo(result.video_id, { language: 'en', aspectRatio: '9:16' }); const convertedUrl = await api.waitForCompletion(converted.video_id); console.log(`Converted URL: ${convertedUrl}`); }
} catch (error) { console.error('Error:', error.message); }})();トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 401 Unauthorized | API キーが無効 | API キーを確認、再生成 |
| 429 Too Many Requests | レート制限超過 | レート制限解除まで待機して再試行 |
| 動画生成が遅い | 高負荷時間帯 | オフピーク時間に実行 |
| ファイルアップロードエラー | ファイルサイズ超過 | ファイルサイズを小さくする |
| 動画変換で 403 エラー | フリープランでは動画変換 API を利用できない | スタンダード / プレミアムプランへアップグレード |
| LANGUAGE_NOT_SUPPORTED_BY_VOICES エラー | 変換元動画の話者が指定言語に対応していない | GET /videos/{video_id}/conversions/ の available_languages から選ぶ |
| CONVERT_NO_CHANGE エラー | 変換元動画と同じ言語・アスペクト比を指定している | 変換元と異なる値を指定する |