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
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
readcall. See rate limits. - No
Idempotency-Key.
Parameters
Path
| Name | Type | Required | Description |
|---|---|---|---|
compositionId | string | Required | The 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
| Name | Type | Required | Description |
|---|---|---|---|
format | string | Optional | srt for SubRip, vtt for WebVTT. Defaults to srt. One of srt, vtt. Default srt. |
Request
Get the captions as SRT.
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
{
"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
| Name | Type | Required | Description |
|---|---|---|---|
captions | object | Required | |
captions.format | string | Required | The format of text. One of srt, vtt. |
captions.mimeType | string | Required | The media type to save text with, character set included. |
captions.compositionRevision | integer | Required | The revision of the composition the text was written from. |
captions.text | string | Required | The whole subtitle file, ready to save. |
More examples
Get the captions as WebVTT
GET /v1/compositions/cmp_4e8c2a6f09d14b73a1e5/captions?format=vtt
{
"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
{
"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
{
"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
| Code | Status | When | What to do |
|---|---|---|---|
NOT_FOUND | 404 | Captions of a composition that does not exist | Change the request, then send it again. |
CONFLICT | 409 | A composition with no words to caption | Read 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.
Related operations
get_composition(GET /v1/compositions/{compositionId}) Get a compositioncreate_export(POST /v1/compositions/{compositionId}/exports) Export a compositionget_export(GET /v1/exports/{exportId}) Get an exportreplace_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.