認証
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/ | 10 秒に 2 回まで | 429 エラー |
| その他のエンドポイント | 10 秒に 5 回まで(2 秒に 1 回) | 429 エラー |
同時実行制限
- 動画生成: 1 ユーザーアカウントあたり最大 2 つまで並列生成可能。超過時は 503 エラー。
- 注意: API キー単位ではなく、ユーザーアカウント単位での制限です。複数の API キーを発行しても、同時生成数は増えません。
エラーハンドリング
エラーレスポンス形式
{ "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 /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 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}")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 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}`);
} catch (error) { console.error('Error:', error.message); }})();トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 401 Unauthorized | API キーが無効 | API キーを確認、再生成 |
| 429 Too Many Requests | レート制限超過 | レート制限解除まで待機して再試行 |
| 動画生成が遅い | 高負荷時間帯 | オフピーク時間に実行 |
| ファイルアップロードエラー | ファイルサイズ超過 | ファイルサイズを小さくする |