Skip to content
Create a key

Paste a key to use it in the examples on these pages. The key stays in this browser tab. These pages never send it anywhere.

Get a tool run

get_tool_runGET/v1/tool-runs/{toolRunId}Beta

Returns a tool run: its status and, once it is done, its audio file with a fresh download link, or its ideas.

Beta. This endpoint is supported and can gain new fields. If a change would break your code, we tell you before it takes effect and list it in the changelog.

About

Call this to follow a voiceover, an audio separation or a brainstorm. While the run is queued or running, add ?wait= with up to 25 seconds to hold the request until it ends, then call again if it is still working. Once the status is done, a voiceover or a separation has its file, whose downloadUrl downloads the MP3 with no API key: the link is short-lived and every read gives a new one. A brainstorm has its ideas. A failed run says what happened in errorMessage: start it again with a new Idempotency-Key.

Example use

A script that started a voiceover reads the run with ?wait= until it is done. Then it downloads the MP3 from the download link, which changes on every read.

Endpoint

Code
GET https://api.gpt-video.com/v1/tool-runs/{toolRunId}
  • Scope clips:read.
  • Rate limit 120 requests a minute for each key and 240 for each account, shared by every read call. See rate limits.
  • No Idempotency-Key.

Parameters

Path

NameTypeRequiredDescription
toolRunIdstringRequiredThe id of the tool run, as create_voiceover (POST /v1/voiceovers), separate_audio (POST /v1/audio-separations), brainstorm_ideas (POST /v1/brainstorms) or list_tool_runs (GET /v1/tool-runs) returned it. It starts with run_. Matches ^run_[0-9a-f]{20}$.

Query

NameTypeRequiredDescription
waitintegerOptionalSeconds to hold the request while the work is still running, up to 25. Leave it out to answer at once. If many requests of the account are already waiting, it answers at once; wait a few seconds before you read again. From 0 to 25.

Request

Get a finished voiceover.

Request example
curl "https://api.gpt-video.com/v1/tool-runs/run_b014441ea91a51965c46" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
const res = await fetch("https://api.gpt-video.com/v1/tool-runs/run_b014441ea91a51965c46", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
  },
});
const data = await res.json();
console.log(data);
import os

import requests

r = requests.get(
    "https://api.gpt-video.com/v1/tool-runs/run_b014441ea91a51965c46",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
)
data = r.json()
print(data)
{
  "method": "tools/call",
  "params": {
    "name": "get_tool_run",
    "arguments": {
      "toolRunId": "run_b014441ea91a51965c46"
    }
  }
}

Response

A successful call answers HTTP 200. Returns a Tool run object in toolRun.

Fields to check

NameTypeDescription
toolRun.idstringThe tool run id. It starts with run_.
toolRun.statusstringqueued and running are still working; done and failed are final.
toolRun.file.downloadUrlstring or nullA link to download the file, on a read of a finished run; null otherwise.
toolRun.file.downloadUrlExpiresAtstring or nullAn ISO 8601 time in UTC.
toolRun.jobIdstring or nullThe job that carries out the run, to follow with get_job (GET /v1/jobs/{jobId}); null once it is gone.

Response example

HTTP 200
{
  "toolRun": {
    "id": "run_b014441ea91a51965c46",
    "tool": "voiceover",
    "status": "done",
    "progress": 1,
    "errorMessage": null,
    "voiceover": {
      "title": "Launch voiceover",
      "script": "Meet the editor that turns one long video into ten short clips.",
      "voice": "en-aria",
      "language": "en"
    },
    "separation": null,
    "brainstorm": null,
    "file": {
      "assetId": "ast_e8a35ed674148f27b585",
      "mimeType": "audio/mpeg",
      "durationSec": 14,
      "sizeBytes": 224000,
      "downloadUrl": "https://www.gpt-video.com/media/ast_e8a35ed674148f27b585?exp=1788258600&sig=4c1e9a7f2b5d8e03a6c9f1b4d7e2a5c8",
      "downloadUrlExpiresAt": "2026-09-01T10:30:00.000Z"
    },
    "ideas": null,
    "jobId": "job_bd92cb70ed9c45575464",
    "createdAt": "2026-08-31T21:30:00.000Z",
    "finishedAt": "2026-08-31T21:32:00.000Z"
  }
}
All response fields
NameTypeRequiredDescription
toolRunTool run objectRequiredDescribed in Tool run object.
More examples

Wait for a run to finish

GET /v1/tool-runs/run_b014441ea91a51965c46?wait=25

HTTP 200
{
  "toolRun": {
    "id": "run_b014441ea91a51965c46",
    "tool": "voiceover",
    "status": "done",
    "progress": 1,
    "errorMessage": null,
    "voiceover": {
      "title": "Launch voiceover",
      "script": "Meet the editor that turns one long video into ten short clips.",
      "voice": "en-aria",
      "language": "en"
    },
    "separation": null,
    "brainstorm": null,
    "file": {
      "assetId": "ast_e8a35ed674148f27b585",
      "mimeType": "audio/mpeg",
      "durationSec": 14,
      "sizeBytes": 224000,
      "downloadUrl": "https://www.gpt-video.com/media/ast_e8a35ed674148f27b585?exp=1788258600&sig=4c1e9a7f2b5d8e03a6c9f1b4d7e2a5c8",
      "downloadUrlExpiresAt": "2026-09-01T10:30:00.000Z"
    },
    "ideas": null,
    "jobId": "job_bd92cb70ed9c45575464",
    "createdAt": "2026-08-31T21:30:00.000Z",
    "finishedAt": "2026-08-31T21:32:00.000Z"
  }
}

A tool run that does not exist

GET /v1/tool-runs/run_774e9c335fb2d153918a

HTTP 404
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Tool run run_774e9c335fb2d153918a not found",
    "hint": "Check the id. An id that belongs to another account is not found either.",
    "requestId": "req_0e4a8c2f6b1d5e9a3c7f0b28"
  }
}

Errors

CodeStatusWhenWhat to do
NOT_FOUND404A tool run that does not existChange the request, then send it again.

Every call can also answer these errors. VALIDATION_FAILED, UNKNOWN_PARAMETER, UNAUTHORIZED, SCOPE_MISSING, RATE_LIMITED, INTERNAL, UNAVAILABLE.

Cost

No credits are used.

Questions

How long does the download link work?

For 15 minutes; downloadUrlExpiresAt says until when. It downloads this file only. Read the run again for a new link.

How do I wait for a run without polling in a tight loop?

Send ?wait=25. The request is held until the run ends or 25 seconds pass, whichever comes first, and then answers the run as it is. If many requests of the account are already waiting, it answers at once instead; wait a few seconds before you read again.

View as Markdown