Owl3D Cloud API

この API は 2D 動画をサイドバイサイド 3D に変換します。コードで見積もりを取得し、ファイルをアップロードし、ジョブの完了を待ち、結果をダウンロードします。変換処理は Owl3D Cloud と同じです。

AI コーディングエージェントは、このページを /llms.txt でプレーンテキストとして読めます。

更新日:

始める前に

  1. app.owl3d.com にサインインし、メールアドレスを確認します。
  2. プランに加入するか、クレジットを購入します。ジョブはまずプランの月間クレジットを使い、次に購入したクレジットを使います。トライアルのクレジットも使えます。
  3. API キーのページを開き、キーを作成します。キーが表示されるのは 1 回だけです。

キーは環境変数 OWL3D_API_KEY に入れます。このページの例はすべて、そこからキーを読みます。

API の利用には Owl3D Cloud API Terms(英語)が適用されます。

Shell
export OWL3D_API_KEY="o3d_live_..."

認証

項目 値
Base URL https://api.owl3d.com
キーの形式 o3d_live_<keyId>_<secret>
認証ヘッダー Authorization: Bearer <key>

Bearer は先頭を大文字にし、後ろに半角スペースを 1 つ置きます。それ以外の書き方は 401 になります。

各ルートにはスコープが必要です:jobs:read または jobs:write。各ルートのスコープはルートの表にあります。

キーは秘密にしてください。キーを使うとクレジットを消費できます。キーが漏れたら、API キーのページで失効させます。失効したキーは 60 秒以内に使えなくなります。

GET /v1/jobs/{id}

curl
curl https://api.owl3d.com/v1/jobs/job_... \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス200
{"id": "job_...", "status": "converting"}

動画を 1 本変換する

スクリプトを 1 つダウンロードし、手元の動画で実行します。どのスクリプトも、下の手順をすべて行います。

スクリプト 必要なもの 実行
convert.sh bash, curl, jq, ffprobe bash convert.sh my-video.mp4
convert.py Python 3.9+, requests, ffprobe python3 convert.py my-video.mp4
convert.mjs Node.js 20+, ffprobe node convert.mjs my-video.mp4

convert.sh · convert.py · convert.mjs

curl
curl -O https://www.owl3d.com/docs/api/convert.sh
bash convert.sh my-video.mp4

スクリプトは任意です。独自のコードはどの言語でも書けます。必要なのは HTTPS 呼び出し、SHA-256、ファイル情報 です。先にアップロード する場合、必要なのは HTTPS 呼び出しだけです。

流れは 6 ステップです。

  1. ファイルの情報を読み取り、フィンガープリントを作ります。
  2. POST /v1/estimates:見積もりを取得します。課金はされません。
  3. POST /v1/jobs:見積もりを承認します。クレジットが確保されます。
  4. 各パートを アップロード URL に PUT し、続けて POST /v1/jobs/{id}/upload-complete を呼びます。
  5. GET /v1/jobs/{id} を 15 秒ごとにポーリングします。
  6. GET /v1/jobs/{id}/result:ダウンロードリンクを取得します。リンクは 15 分間有効で、GET のみ使えます。

先にアップロード する場合は、手順 1 と 2 を省きます。コードはファイル名とサイズを POST /v1/jobs に送ります。アップロード後、サーバーがファイルを読み取って料金を決めます。

エラー

ほとんどのエラーレスポンスは JSON のボディを持ち、error に短いコードが入ります。

ステータス 意味
400 不正なリクエスト。例:bad_fingerprint
401 トークンがない、トークンが誤っている、またはキーが失効しています
402 short_of_credits:プラン、トライアル、購入したクレジットを合わせても価格に足りません
403 insufficient_scope、またはルートが公開されていません
404 no_job。Cloud アプリで作ったジョブは API から見えません
409 状態の競合。例:not_uploading、endpoint_exists
410 出力の期限が切れました。または insufficient_credits_expired:ジョブがクレジットを 24 時間待ちました
429 上限に達しました。制限を参照してください

リトライのルール:

  1. 429 の場合は、Retry-After の秒数だけ待ち、同じリクエストを送ります。
  2. 5xx またはネットワークエラーの場合は、1 秒から 60 秒までバックオフします。
  3. それ以外の 4xx の場合は、リクエストを修正します。
curl
curl -i https://api.owl3d.com/v1/jobs/job_unknown \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス404
{"error": "no_job"}

制限

制限 値 レスポンス
進行中のジョブ アカウントのすべての API キーで合計 10 件。全チャネル合わせてアカウントで 15 件。キーごとの上限は任意 429 concurrency_limit、Retry-After: 15
リクエスト キーごとに 1 分間 120 回 429、Retry-After: 60
バースト ルートごとに 1 秒 10 回、バースト 20 回(全呼び出し元の合計) 429 throttled、Retry-After: 1
1 日のクレジット上限 キーごとに任意 429 daily_credit_cap(00:00 UTC まで)
有効なキー アカウントごとに 10 個 作成が拒否されます
入力 100 GB、3 時間、4096 x 2160、60 fps 見積もりが拒否されます
コンテナ MP4, MOV, MKV, M4V 見積もりが拒否されます

429 concurrency_limit の本文は、上限に達した範囲を示します。scope は api(アカウントのすべての API キー)、account(アカウントのすべてのジョブ)、key(このキー)のいずれかです。ジョブが 1 件終わってから、次のジョブを始めます。

レスポンス429
{
  "error": "concurrency_limit",
  "scope": "api",
  "limit": 10,
  "inProgress": 10
}

料金

支払う前に、POST /v1/estimates でファイルの正確な料金を確認できます。

どちらの方法でも、サーバーがアップロードされたファイルを読み取り、そのファイルから最終的な料金を決めます。先にアップロード する場合、料金はアップロード後にわかります。残高が料金に足りないとき、ジョブは待機します。クレジット不足 を参照してください。

ルート

メソッドとパス スコープ 内容
POST /v1/estimates jobs:write 料金と所要時間。課金されません。有効期間は 1 時間で、1 つのジョブ専用です
POST /v1/jobs jobs:write クレジットを確保し、アップロード計画を返します。estimateId を付けるか、filename と sizeBytes を付けます(先にアップロード)
GET /v1/jobs/{id}/upload jobs:read アップロードの状態:done、missing、新しい parts URL
POST /v1/jobs/{id}/upload-complete jobs:write ETag を送信し、ジョブをキューに入れます
GET /v1/jobs/{id} jobs:read ステータス、進捗、残り時間
POST /v1/jobs/{id}/cancel jobs:write ジョブをキャンセルします
POST /v1/jobs/{id}/resume jobs:write クレジットを追加した後、insufficient_credits のジョブを再開します。再アップロードは不要です
GET /v1/jobs/{id}/result jobs:read ダウンロードリンク(15 分間)

見積もり

POST /v1/estimates は、1 つのファイルの料金と所要時間を返します。課金はされません。見積もりの有効期間は 1 時間で、1 つのジョブ専用です。

フィールド 値
name、size ファイル名と、バイト単位のサイズ
durationSeconds、width、height、fps ffprobe や MediaInfo など、任意のツールでファイルから読み取ります
codec H.264、HEVC、AV1、VP9 のいずれか
bitDepth、chroma ファイルから読み取ります。chroma は 4:2:0 です
fingerprint {size, headSha256, tailSha256, edgeBytes}
  • edgeBytes は 4194304 です。ファイルがそれより小さい場合は、ファイルサイズです。
  • headSha256 と tailSha256 は、ファイルの先頭 edgeBytes バイトと末尾 edgeBytes バイトのハッシュです。

レスポンスの "ok": false は、見積もりが拒否されたことを示します。reason を読んでください。credits.shortBy が 0 より大きい場合、アカウントのクレジットが足りません。credits.fromPlan、credits.fromTrial、credits.fromPurchased は、どのクレジットで支払うかを示します。

POST /v1/estimates

curl
curl https://api.owl3d.com/v1/estimates \
  -H "Authorization: Bearer $OWL3D_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-video.mp4",
    "size": 104857600,
    "durationSeconds": 120,
    "width": 1920, "height": 1080, "fps": 24,
    "codec": "H.264", "bitDepth": 8, "chroma": "4:2:0",
    "fingerprint": {
      "size": 104857600,
      "headSha256": "<SHA-256 of the first 4194304 bytes>",
      "tailSha256": "<SHA-256 of the last 4194304 bytes>",
      "edgeBytes": 4194304
    }
  }'
レスポンス200
{
  "ok": true,
  "id": "est_...",
  "credits": {
    "total": 60,
    "fromPlan": 60,
    "fromTrial": 0,
    "fromPurchased": 0,
    "shortBy": 0
  },
  "etaMinutes": 6,
  "hdr": {"detected": false},
  "output": {"format": "FULL_SBS", "width": 3840, "height": 1080}
}

ジョブ

{"estimateId": "est_..."} を付けて POST /v1/jobs を呼ぶと、見積もりを承認します。クレジットが確保されます。レスポンスには、ジョブの id とアップロード計画(upload.partSize と upload.parts の URL)が入ります。

出力オプション

POST /v1/jobs は output: {layout, max_height} も受け付けます。

  • layout:full_sbs(デフォルト)。
  • max_height:"source"(デフォルト)、2160、1080。

POST /v1/jobs

curl
curl https://api.owl3d.com/v1/jobs \
  -H "Authorization: Bearer $OWL3D_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"estimateId": "est_...", "output": {"layout": "full_sbs", "max_height": "source"}}'
レスポンス201
{
  "id": "job_...",
  "status": "uploading",
  "upload": {
    "partSize": 67108864,
    "parts": ["https://...", "https://..."],
    "completeUrl": "/v1/jobs/job_.../upload-complete"
  }
}

先にアップロード

estimateId を付けずに POST /v1/jobs を送ります。コードはファイルを読み取らず、フィンガープリントも作りません。

フィールド 値
filename ファイル名、最大 255 文字。末尾は .mp4、.mov、.mkv、.m4v のいずれか
sizeBytes ファイルサイズ(バイト)
output 任意。出力オプション を参照してください
  1. 残高は最低料金に足りている必要があります。足りない場合、応答は 402 short_of_credits で、ジョブは作られません。
  2. 201 の応答には reservedCredits と "priceAfterUpload": true も入ります。
  3. アップロード後、サーバーがファイルを読み取って料金を決めます。
  4. サーバーがファイルを変換できない場合、ジョブは failed になります。課金はされず、ファイルは削除されます。

HDR10 の動画には見積もりが必要です。見積もりがない場合、応答は 400 hdr_needs_estimate です。

POST /v1/jobs (upload first)

curl
curl https://api.owl3d.com/v1/jobs \
  -H "Authorization: Bearer $OWL3D_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"filename\": \"my-video.mp4\", \"sizeBytes\": $(wc -c < my-video.mp4)}"
レスポンス201
{
  "id": "job_...",
  "status": "uploading",
  "upload": {
    "partSize": 67108864,
    "parts": ["https://...", "https://..."],
    "completeUrl": "/v1/jobs/job_.../upload-complete"
  },
  "reservedCredits": 15,
  "priceAfterUpload": true
}

クレジット不足

料金が残高を超えると、ジョブは insufficient_credits になります。課金はされません。見積もりがあってもなくても同じです。

  1. GET /v1/jobs/{id} に shortBy(追加が必要なクレジット)、neededCredits、deleteAt、resumeUrl が表示されます。
  2. クレジットを追加してから、POST /v1/jobs/{id}/resume を送ります。ファイルを再アップロードしないでください。
  3. 残高がまだ足りない場合、resume は shortBy 付きの 402 short_of_credits を返します。
  4. deleteAt(24 時間)までに resume しないと、ジョブは insufficient_credits_expired で failed になります。ファイルは削除されます。

POST /v1/jobs/{id}/resume

curl
curl -X POST https://api.owl3d.com/v1/jobs/job_.../resume \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス200
{
  "id": "job_...",
  "status": "queued"
}
レスポンス402
{
  "error": "short_of_credits",
  "shortBy": 120,
  "neededCredits": 450,
  "deleteAt": "2026-11-04T09:00:00.000Z"
}

アップロード

  1. ファイルを upload.partSize バイトずつのパートに分けます。パート 1 はバイト 0 から始まります。
  2. 各パートを upload.parts の対応する URL に PUT します。各レスポンスの ETag ヘッダーを、引用符も含めて保存します。
  3. パートの順に並べた {"etags": [...]} を付けて POST /v1/jobs/{id}/upload-complete を呼びます。

各 URL は、決まった長さ 1 つだけに署名されています。パートは partSize バイトにし、最後のパートに残りを入れます。それ以外の長さや chunked ボディでは、ストレージは 403 を返します。Content-Length を送ってください。

アップロードが止まっても、最初からやり直さないでください。

  1. GET /v1/jobs/{id}/upload を呼びます。
  2. done を読みます。各項目に partNumber、etag、size が入っています。
  3. missing を読みます。パート番号の一覧です。
  4. 足りない各パートを parts[partNumber - 1] にアップロードします。これらの URL は 1 時間有効です。
  5. すべての ETag をパートの順に付けて完了します。同じファイルを使ってください。

アップロードは 24 時間以内に完了してください。それを過ぎると、ストレージは完了していないアップロードのパートを削除します。

PUT upload.parts[n] · POST /v1/jobs/{id}/upload-complete

curl
split -b 67108864 my-video.mp4 part_
curl -sS -D - -o /dev/null -X PUT --upload-file part_aa "<upload.parts[0]>" | grep -i '^etag'
curl -sS -D - -o /dev/null -X PUT --upload-file part_ab "<upload.parts[1]>" | grep -i '^etag'

curl https://api.owl3d.com/v1/jobs/job_.../upload-complete \
  -H "Authorization: Bearer $OWL3D_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"etags": ["\"<etag of part 1>\"", "\"<etag of part 2>\""]}'
レスポンス200
{"id": "job_...", "status": "queued"}

GET /v1/jobs/{id}/upload

curl
curl https://api.owl3d.com/v1/jobs/job_.../upload \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス200
{
  "id": "job_...",
  "partSize": 67108864,
  "parts": ["https://...", "https://..."],
  "completeUrl": "/v1/jobs/job_.../upload-complete",
  "done": [{"partNumber": 1, "etag": "\"...\"", "size": 67108864}],
  "missing": [2]
}

ジョブのステータス

GET /v1/jobs/{id} は、ステータス、進捗、残り時間を返します。15 秒ごとにポーリングします。

status 意味
uploading ジョブはファイルを待っています
queued ジョブは GPU を待っています。ジョブが converting から一時的に queued に戻ることがあります
converting progress が 0 から 1 に進みます
delayed こちら側で保留中です。クレジットは確保されたままです
insufficient_credits 料金が残高を超えています。shortBy クレジットを追加してから resume します。クレジット不足 を参照してください
done 完了です。result に名前、サイズ、リンクのパスが入ります
failed error に code が入ります。クレジットは戻ります
cancelled 呼び出し側がキャンセルしました

GET /v1/jobs/{id}

curl
curl https://api.owl3d.com/v1/jobs/job_... \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス200
{
  "id": "job_...",
  "status": "converting",
  "progress": 0.42,
  "etaSeconds": 310
}

結果

GET /v1/jobs/{id}/result は、done のジョブのダウンロードリンクを返します。リンクは 15 分間有効で、GET のみ使えます。新しいリンクが要るときは、このルートをもう一度呼びます。出力の期限が切れている場合、レスポンスは 410 です。

GET /v1/jobs/{id}/result

curl
curl https://api.owl3d.com/v1/jobs/job_.../result \
  -H "Authorization: Bearer $OWL3D_API_KEY"
curl -o output.mp4 "<url>"
レスポンス200
{
  "url": "https://...",
  "filename": "...",
  "sizeBytes": 209715200,
  "expiresInS": 900
}

キャンセル

POST /v1/jobs/{id}/cancel はジョブをキャンセルします。変換が始まる前にキャンセルしたジョブは無料です。始まった後は、料金 x progress を切り上げた額で、最低 1 クレジットです。

POST /v1/jobs/{id}/cancel

curl
curl -X POST https://api.owl3d.com/v1/jobs/job_.../cancel \
  -H "Authorization: Bearer $OWL3D_API_KEY"
レスポンス200
{"id": "job_...", "status": "cancelled"}

最新情報をお届けします!

Owl3D
© 2026 Owl3D. All rights reserved.