Get a composition
get_compositionGET/v1/compositions/{compositionId}Beta
Returns a composition: the vertical video made from a clip, with its size, captions, hook and framing.
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 after accept_clip (POST /v1/clips/{clipId}/accept) to follow the framing: while framing.status is tracking, the face is still being followed by the job in framing.jobId, and create_export (POST /v1/compositions/{compositionId}/exports) answers NOT_READY until it is done. Every change to the composition adds one to revision, the finished framing included, and an export renders the composition as it is when its render starts, and a finished export says which revision it rendered. Compositions of other kinds of project are shown too: source is filled for Auto Clip and streamer compositions, hook for Auto Clip compositions only.
Example use
After accepting a clip, a script reads the composition every few seconds until framing.status is no longer tracking. It then starts the export and stores the revision it saw, to compare it with the finished export.
Endpoint
GET https://api.gpt-video.com/v1/compositions/{compositionId}- 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}$. |
Request
Get a composition.
curl "https://api.gpt-video.com/v1/compositions/cmp_4e8c2a6f09d14b73a1e5" \
-H "Authorization: Bearer $GPT_VIDEO_API_KEY"const res = await fetch("https://api.gpt-video.com/v1/compositions/cmp_4e8c2a6f09d14b73a1e5", {
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",
headers={
"Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
},
)
data = r.json()
print(data){
"method": "tools/call",
"params": {
"name": "get_composition",
"arguments": {
"compositionId": "cmp_4e8c2a6f09d14b73a1e5"
}
}
}Response
A successful call answers HTTP 200. Returns a Composition object in composition.
Fields to check
| Name | Type | Description |
|---|---|---|
composition.id | string | The composition id. It starts with cmp_. |
composition.framing.status | string | |
composition.framing.jobId | string or null |
Response example
{
"composition": {
"id": "cmp_4e8c2a6f09d14b73a1e5",
"projectId": "prj_7c2e9a4f1b3d4e8096a5",
"clipId": "cnd_9e04a6c3d12b4f78a5b9",
"kind": "autoclip",
"title": "Paid before the product",
"revision": 0,
"durationSec": 30,
"width": 1080,
"height": 1920,
"fps": 30,
"source": {
"assetId": "ast_3f9a1c7e5b2d4086a1c4",
"startSec": 120,
"endSec": 150
},
"hook": "They paid us before we had a product",
"captions": {
"style": "word-pop",
"wordCount": 75
},
"framing": {
"status": "centered",
"jobId": null
},
"createdAt": "2026-09-01T10:00:00.000Z",
"updatedAt": "2026-09-01T10:00:00.000Z"
}
}All response fields
| Name | Type | Required | Description |
|---|---|---|---|
composition | Composition object | Required | Described in Composition object. |
More examples
A composition that does not exist
GET /v1/compositions/cmp_7a1f5d3c9e0b42d8f6a2
{
"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 | A composition that does not exist | Change 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.
Related operations
get_composition_captions(GET /v1/compositions/{compositionId}/captions) Get the captions of a compositionaccept_clip(POST /v1/clips/{clipId}/accept) Accept a clipcreate_export(POST /v1/compositions/{compositionId}/exports) Export a compositionget_job(GET /v1/jobs/{jobId}) Get a joblist_compositions(GET /v1/projects/{projectId}/compositions) List the compositions of a projectedit_composition(POST /v1/compositions/{compositionId}/edit) Edit a composition
Questions
When is a composition ready to export?
When framing.status is no longer tracking. Right after accept_clip (POST /v1/clips/{clipId}/accept) the framing is still being computed, and an export answers NOT_READY until it is done.
Why are source and hook null?
source is filled for Auto Clip and streamer compositions, and hook for Auto Clip compositions only: a composition of another kind has no single source window to show. source is also null when its video no longer exists or cannot be used through the API.