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 the captions of a composition

get_composition_captionsGET/v1/compositions/{compositionId}/captionsBeta

Returns the captions of a composition as an SRT or WebVTT file, inside a JSON answer.

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

Use it to post the captions as a separate file next to the exported video. The text follows the composition as it is now, and an export made earlier can differ: compare compositionRevision with the revision of a finished export (status done) to know they match. Lines break where they break on screen, and words keep the case they were typed in. A composition with no words to caption answers CONFLICT. Works on compositions of every kind of project.

Example use

A channel that also posts its clips to YouTube downloads the SRT file of each composition and uploads it next to the video, so viewers can turn the captions on and off.

Endpoint

Code
GET https://api.gpt-video.com/v1/compositions/{compositionId}/captions
  • 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
compositionIdstringRequiredThe id of the composition: accept_clip (POST /v1/clips/{clipId}/accept) returns it for a clip, and list_compositions (GET /v1/projects/{projectId}/compositions) or the project's compositionId give it for the other kinds of project. Matches ^cmp_[0-9a-f]{20}$.

Query

NameTypeRequiredDescription
formatstringOptionalsrt for SubRip, vtt for WebVTT. Defaults to srt. One of srt, vtt. Default srt.

Request

Get the captions as SRT.

Request example
curl "https://api.gpt-video.com/v1/compositions/cmp_4e8c2a6f09d14b73a1e5/captions" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
const res = await fetch("https://api.gpt-video.com/v1/compositions/cmp_4e8c2a6f09d14b73a1e5/captions", {
  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/compositions/cmp_4e8c2a6f09d14b73a1e5/captions",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
)
data = r.json()
print(data)
{
  "method": "tools/call",
  "params": {
    "name": "get_composition_captions",
    "arguments": {
      "compositionId": "cmp_4e8c2a6f09d14b73a1e5"
    }
  }
}

Response

A successful call answers HTTP 200.

Response example

HTTP 200
{
  "captions": {
    "format": "srt",
    "mimeType": "text/plain; charset=utf-8",
    "compositionRevision": 0,
    "text": "1\n00:00:00,000 --> 00:00:01,600\nbefore we had a\n\n2\n00:00:01,600 --> 00:00:02,800\nproduct and that\n\n3\n00:00:02,800 --> 00:00:04,000\nchanged everything for\n\n4\n00:00:04,000 --> 00:00:05,600\nour team the first\n\n5\n00:00:05,600 --> 00:00:06,800\ncustomer paid us\n\n6\n00:00:06,800 --> 00:00:08,400\nbefore we had a\n\n7\n00:00:08,400 --> 00:00:09,600\nproduct and that\n\n8\n00:00:09,600 --> 00:00:10,800\nchanged everything for\n\n9\n00:00:10,800 --> 00:00:12,400\nour team the first\n\n10\n00:00:12,400 --> 00:00:13,600\ncustomer paid us\n\n11\n00:00:13,600 --> 00:00:15,200\nbefore we had a\n\n12\n00:00:15,200 --> 00:00:16,400\nproduct and that\n\n13\n00:00:16,400 --> 00:00:17,600\nchanged everything for\n\n14\n00:00:17,600 --> 00:00:19,200\nour team the first\n\n15\n00:00:19,200 --> 00:00:20,400\ncustomer paid us\n\n16\n00:00:20,400 --> 00:00:22,000\nbefore we had a\n\n17\n00:00:22,000 --> 00:00:23,200\nproduct and that\n\n18\n00:00:23,200 --> 00:00:24,400\nchanged everything for\n\n19\n00:00:24,400 --> 00:00:26,000\nour team the first\n\n20\n00:00:26,000 --> 00:00:27,200\ncustomer paid us\n\n21\n00:00:27,200 --> 00:00:28,800\nbefore we had a\n\n22\n00:00:28,800 --> 00:00:30,000\nproduct and that\n"
  }
}
All response fields
NameTypeRequiredDescription
captionsobjectRequired
captions.formatstringRequiredThe format of text. One of srt, vtt.
captions.mimeTypestringRequiredThe media type to save text with, character set included.
captions.compositionRevisionintegerRequiredThe revision of the composition the text was written from.
captions.textstringRequiredThe whole subtitle file, ready to save.
More examples

Get the captions as WebVTT

GET /v1/compositions/cmp_4e8c2a6f09d14b73a1e5/captions?format=vtt

HTTP 200
{
  "captions": {
    "format": "vtt",
    "mimeType": "text/vtt; charset=utf-8",
    "compositionRevision": 0,
    "text": "WEBVTT\n\n00:00:00.000 --> 00:00:01.600\nbefore we had a\n\n00:00:01.600 --> 00:00:02.800\nproduct and that\n\n00:00:02.800 --> 00:00:04.000\nchanged everything for\n\n00:00:04.000 --> 00:00:05.600\nour team the first\n\n00:00:05.600 --> 00:00:06.800\ncustomer paid us\n\n00:00:06.800 --> 00:00:08.400\nbefore we had a\n\n00:00:08.400 --> 00:00:09.600\nproduct and that\n\n00:00:09.600 --> 00:00:10.800\nchanged everything for\n\n00:00:10.800 --> 00:00:12.400\nour team the first\n\n00:00:12.400 --> 00:00:13.600\ncustomer paid us\n\n00:00:13.600 --> 00:00:15.200\nbefore we had a\n\n00:00:15.200 --> 00:00:16.400\nproduct and that\n\n00:00:16.400 --> 00:00:17.600\nchanged everything for\n\n00:00:17.600 --> 00:00:19.200\nour team the first\n\n00:00:19.200 --> 00:00:20.400\ncustomer paid us\n\n00:00:20.400 --> 00:00:22.000\nbefore we had a\n\n00:00:22.000 --> 00:00:23.200\nproduct and that\n\n00:00:23.200 --> 00:00:24.400\nchanged everything for\n\n00:00:24.400 --> 00:00:26.000\nour team the first\n\n00:00:26.000 --> 00:00:27.200\ncustomer paid us\n\n00:00:27.200 --> 00:00:28.800\nbefore we had a\n\n00:00:28.800 --> 00:00:30.000\nproduct and that\n"
  }
}

A composition with no words to caption

GET /v1/compositions/cmp_4e8c2a6f09d14b73a1e5/captions

HTTP 409
{
  "error": {
    "code": "CONFLICT",
    "message": "This edit has no subtitles to export.",
    "requestId": "req_3e7a1c9d5b0f42e6a4c8d1b3"
  }
}

Captions of a composition that does not exist

GET /v1/compositions/cmp_7a1f5d3c9e0b42d8f6a2/captions

HTTP 404
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Composition cmp_7a1f5d3c9e0b42d8f6a2 not found",
    "hint": "Check the id. An id that belongs to another account is not found either.",
    "requestId": "req_6b2d9f0e4a7c41b3d8e5a2f9"
  }
}

Errors

CodeStatusWhenWhat to do
NOT_FOUND404Captions of a composition that does not existChange the request, then send it again.
CONFLICT409A composition with no words to captionRead the resource again, then decide. Do not send the same request again.

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

Cost

No credits are used.

  • get_composition (GET /v1/compositions/{compositionId}) Get a composition
  • create_export (POST /v1/compositions/{compositionId}/exports) Export a composition
  • get_export (GET /v1/exports/{exportId}) Get an export
  • replace_caption_words (POST /v1/compositions/{compositionId}/captions/replace) Correct words in the captions

Questions

Do the captions match a video I exported before?

Only if the composition has not changed since. The text follows the composition as it is now; compare compositionRevision with the revision of a finished export (status done).

Why is the text not in capitals when the video shows the captions in capitals?

The file keeps the words as they were typed. Capitals on screen are a style of the video, and a subtitle file that keeps the case works better for uploads, screen readers and translation.

View as Markdown