Get a project
get_projectGET/v1/projects/{projectId}Beta
Returns one project with its status, settings, missing settings and the analysis running on it.
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 check whether a project is ready to analyze (missingSettings is empty), whether an analysis is running (analysisJobId), and why the last analysis failed (errorMessage). To wait for an analysis, follow its job with get_job (GET /v1/jobs/{jobId}).
Example use
A script reads a project before it starts the analysis and checks that missingSettings is empty. After a failed analysis it reads errorMessage to tell the person what to change.
Endpoint
GET https://api.gpt-video.com/v1/projects/{projectId}- 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 |
|---|---|---|---|
projectId | string | Required | The project id. It starts with prj_. Matches ^prj_[0-9a-f]{20}$. |
Request
Read a project.
curl "https://api.gpt-video.com/v1/projects/prj_7c2e9a4f1b3d4e8096a5" \
-H "Authorization: Bearer $GPT_VIDEO_API_KEY"const res = await fetch("https://api.gpt-video.com/v1/projects/prj_7c2e9a4f1b3d4e8096a5", {
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/projects/prj_7c2e9a4f1b3d4e8096a5",
headers={
"Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
},
)
data = r.json()
print(data)Response
A successful call answers HTTP 200.
Fields to check
| Name | Type | Description |
|---|---|---|
project.id | string | The project id. It starts with prj_. |
project.status | string | draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why. |
project.analysisJobId | string or null | The job of the analysis running on the project now, to follow with get_job (GET /v1/jobs/{jobId}); null when none is running. |
Response example
{
"project": {
"id": "prj_7c2e9a4f1b3d4e8096a5",
"kind": "autoclip",
"title": "Founder interview",
"status": "ready",
"sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
"compositionId": null,
"settings": {
"language": "en",
"clipCount": 3,
"minDurationSec": 15,
"maxDurationSec": 60,
"objective": "viral",
"captionStyle": "word-pop",
"reframe": "face",
"instructions": null,
"vocabulary": null
},
"missingSettings": [],
"splitScreen": null,
"streamer": null,
"redditStory": null,
"fakeText": null,
"vibeEdit": null,
"errorMessage": null,
"createdAt": "2026-09-01T09:10:00.000Z",
"updatedAt": "2026-09-01T09:40:00.000Z",
"analysisJobId": null
}
}All response fields
| Name | Type | Required | Description |
|---|---|---|---|
project | object | Required | |
project.id | string | Required | The project id. It starts with prj_. |
project.kind | string | Required | The kind of project: autoclip finds clips in a long video, splitscreen, streamer and redditstory build one video, faketext shows a chat story, vibeedit is an edit of a video. Each kind has its own operations; projects made in the GPT-Video app are listed too. One of autoclip, splitscreen, faketext, redditstory, streamer, vibeedit. |
project.title | string | Required | The name of the project. |
project.status | string | Required | draft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why. One of draft, processing, ready, failed. |
project.sourceAssetId | string or null | Required | The video the project is made from: the source of an Auto Clip, streamer or Vibe Editing project, the main video of a split screen project. null for Reddit story and fake text projects, whose background video is in their block, until an Auto Clip project has a source, and when the file no longer exists or cannot be used through the API. |
project.compositionId | string or null | Required | The composition of a split screen, streamer, Reddit story, fake text or Vibe Editing project, to export with create_export (POST /v1/compositions/{compositionId}/exports). null for an Auto Clip project, whose compositions belong to its accepted clips, and for a project that has no composition yet. |
project.settings | object or null | Required | The settings of an Auto Clip project; null for every other kind. |
project.missingSettings | array of strings | Required | The settings still to choose before the project can be analyzed. Empty when nothing is missing, and for every kind other than autoclip. |
project.splitScreen | object or null | Required | The choices of a split screen project; null for every other kind. |
project.streamer | object or null | Required | The choices of a streamer project; null for every other kind. |
project.redditStory | object or null | Required | The post, the voice and the choices of a Reddit story project; null for every other kind. |
project.fakeText | object or null | Required | The choices of a fake text project; null for every other kind. |
project.vibeEdit | object or null | Required | The choices of a Vibe Editing project; null for every other kind. |
project.errorMessage | string or null | Required | Why the last analysis failed, in one sentence; null unless the status is failed. |
project.createdAt | string | Required | An ISO 8601 time in UTC. |
project.updatedAt | string | Required | An ISO 8601 time in UTC. |
project.analysisJobId | string or null | Required | The job of the analysis running on the project now, to follow with get_job (GET /v1/jobs/{jobId}); null when none is running. |
Fields of project.settings
| Name | Type | Required | Description |
|---|---|---|---|
project.settings.language | string or null | Required | The language spoken in the video: en, it, or auto to detect it. null until it is chosen. One of auto, it, en. |
project.settings.clipCount | integer or null | Required | How many clips the analysis proposes. null until it is chosen. |
project.settings.minDurationSec | number or null | Required | The shortest clip the analysis may propose, in seconds. null until it is chosen. |
project.settings.maxDurationSec | number or null | Required | The longest clip the analysis may propose, in seconds. null until it is chosen. |
project.settings.objective | string or null | Required | What the clips should be good at. get_setting_options (GET /v1/reference/setting-options) lists every objective with what it means. null until it is chosen. One of viral, educational, entertaining, emotional, controversial, howto, business. |
project.settings.captionStyle | string or null | Required | The caption style of the clips. get_setting_options (GET /v1/reference/setting-options) lists every style with what it looks like. null until it is chosen. One of bold-karaoke, word-pop, boxed, outline. |
project.settings.reframe | string or null | Required | How a clip follows the speaker: face follows the face of the speaker, center keeps the middle of the frame. null until it is chosen. One of face, center. |
project.settings.instructions | string or null | Required | Free text that tells the analysis what to look for, such as only the moments where a given person speaks. null when there are none. |
project.settings.vocabulary | string or null | Required | Names, brands and jargon the transcription should spell right, separated by commas. It is used when the video is transcribed, so set it before the first analysis. null when there is none. |
Fields of project.splitScreen
| Name | Type | Required | Description |
|---|---|---|---|
project.splitScreen.mainAssetId | string or null | Required | The main video, shown on top and transcribed for the captions. null when the file no longer exists or cannot be used through the API. |
project.splitScreen.backgroundAssetId | string or null | Required | The background video, shown under the main video. null when the file no longer exists or cannot be used through the API. |
project.splitScreen.layout | string | Required | How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more. One of 50-50, 60-40. |
project.splitScreen.captionStyle | string or null | Required | The caption style; null when the video has no captions. One of bold-karaoke, word-pop, boxed, outline. |
project.splitScreen.language | string | Required | The language spoken in the main video: en, it, or auto to detect it. One of auto, it, en. |
project.splitScreen.backgroundStartSec | number or null | Required | Where the background video starts, in seconds; null until the first build chooses a random start, which is then kept. |
project.splitScreen.vocabulary | string or null | Required | Names, brands and jargon the transcription should spell right, separated by commas; null when there are none. |
Fields of project.streamer
| Name | Type | Required | Description |
|---|---|---|---|
project.streamer.sourceAssetId | string or null | Required | The clip the project is made from. null when the file no longer exists or cannot be used through the API. |
project.streamer.headline | string | Required | The line shown over the clip; empty for none. |
project.streamer.language | string | Required | The language spoken in the clip: en, it, or auto to detect it. One of auto, it, en. |
project.streamer.captionStyle | string | Required | The caption style. One of bold-karaoke, word-pop, boxed, outline. |
project.streamer.reframe | string | Required | How the video follows the speaker: face follows the face, center keeps the middle of the frame. One of face, center. |
project.streamer.vocabulary | string or null | Required | Names, brands and jargon the transcription should spell right, separated by commas; null when there are none. |
Fields of project.redditStory
| Name | Type | Required | Description |
|---|---|---|---|
project.redditStory.postTitle | string | Required | The title of the post, shown on the title card. |
project.redditStory.postBody | string | Required | The text of the post, read by the voice. |
project.redditStory.author | string | Required | The author shown on the title card. |
project.redditStory.subreddit | string | Required | The community shown on the title card. |
project.redditStory.voice | string or null | Required | The voice that reads the story, as list_voices (GET /v1/reference/voices) names it; null when the project uses a voice that is not available through the API. |
project.redditStory.language | string | Required | The language of the story and of its voice. One of en, it. |
project.redditStory.backgroundAssetId | string or null | Required | The background video. null when the file no longer exists or cannot be used through the API. |
project.redditStory.captionStyle | string | Required | The caption style. One of bold-karaoke, word-pop, boxed, outline. |
project.redditStory.vocabulary | string or null | Required | Names, brands and jargon the transcription should spell right, separated by commas; null when there are none. |
Fields of project.fakeText
| Name | Type | Required | Description |
|---|---|---|---|
project.fakeText.theme | string | Required | How the chat looks: imessage or whatsapp. One of imessage, whatsapp. |
project.fakeText.language | string | Required | The language of the story and of its voices. One of en, it. |
project.fakeText.voiceover | boolean | Required | true when create_fake_text_voices (POST /v1/projects/{projectId}/story/voices) makes voices for the lines. |
project.fakeText.backgroundAssetId | string or null | Required | The background video behind the chat. null when the file no longer exists or cannot be used through the API. |
project.fakeText.storyId | string or null | Required | The story of the project, read with get_fake_text_story (GET /v1/projects/{projectId}/story); null until the project has one. |
Fields of project.vibeEdit
| Name | Type | Required | Description |
|---|---|---|---|
project.vibeEdit.sourceAssetId | string or null | Required | The video the edit starts from. null when the file no longer exists or cannot be used through the API. |
project.vibeEdit.language | string | Required | The language spoken in the video: en, it, or auto to detect it. One of auto, it, en. |
project.vibeEdit.captionStyle | string | Required | The caption style the edit starts with. One of bold-karaoke, word-pop, boxed, outline. |
project.vibeEdit.aspect | string | Required | The shape the edit starts with: source keeps the shape of the video. One of source, 9:16, 1:1, 16:9. |
project.vibeEdit.vocabulary | string or null | Required | Names, brands and jargon the transcription should spell right, separated by commas; null when there are none. |
project.vibeEdit.prepared | boolean | Required | true once prepare_timeline (POST /v1/projects/{projectId}/timeline/prepare) has prepared the edit; an edit is never prepared or charged again. |
More examples
A project that does not exist
GET /v1/projects/prj_9f0d3b7e1c5a4d28b6f3
{
"error": {
"code": "NOT_FOUND",
"message": "Project prj_9f0d3b7e1c5a4d28b6f3 not found",
"hint": "Check the id. An id that belongs to another account is not found either.",
"requestId": "req_33121f31bec52069f18c83ed"
}
}Errors
| Code | Status | When | What to do |
|---|---|---|---|
NOT_FOUND | 404 | A project 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
update_project(PATCH /v1/projects/{projectId}) Update a projectanalyze_project(POST /v1/projects/{projectId}/analyze) Analyze a projectget_job(GET /v1/jobs/{jobId}) Get a joblist_clips(GET /v1/projects/{projectId}/clips) List the clips of a projectlist_projects(GET /v1/projects) List projectsestimate_analysis(POST /v1/projects/{projectId}/analyze/estimate) Estimate the credits of an analysis or a build
Questions
How do I know when a project is ready to analyze?
When missingSettings is empty and the project has a sourceAssetId. estimate_analysis (POST /v1/projects/{projectId}/analyze/estimate) also tells you the price and whether the account has enough credits.
Why does a project of another kind have no settings?
settings and missingSettings are the settings of an Auto Clip analysis, so they are filled for autoclip only. The choices of every other kind are in the block named after it, such as splitScreen or vibeEdit.