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.

List projects

list_projectsGET/v1/projectsBeta

Returns the projects of the account, the most recently created first, one page at a time.

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 find a project you created before, or to see what is already in the account. Each project carries its status, its source video and its settings, so you can tell which ones are ready and which still need settings. Projects made in the GPT-Video app are listed too. To read one project with its running analysis, call get_project (GET /v1/projects/{projectId}).

Example use

A dashboard for an agency lists the projects of the account when it opens, marks the ones that are ready, and lets a person pick up a project that was started in the GPT-Video app.

Endpoint

Code
GET https://api.gpt-video.com/v1/projects
  • 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

Query

NameTypeRequiredDescription
limitintegerOptionalHow many items to return, from 1 to 100. Defaults to 20. From 1 to 100. Default 20.
cursorstringOptionalThe nextCursor value from the previous page. Leave it out to get the first page. From 1 to 512 characters.

Request

List the projects.

Request example
curl "https://api.gpt-video.com/v1/projects" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
const res = await fetch("https://api.gpt-video.com/v1/projects", {
  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",
    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

NameTypeDescription
data[].idstringThe project id. It starts with prj_.
data[].statusstringdraft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why.
hasMorebooleantrue when there are more items after this page.
nextCursorstring or nullSend it as cursor to get the next page. It is null on the last page.

Response example

HTTP 200
{
  "data": [
    {
      "id": "prj_1d8b6e0c47a24f93b1c2",
      "kind": "autoclip",
      "title": "Weekly podcast",
      "status": "draft",
      "sourceAssetId": null,
      "compositionId": null,
      "settings": {
        "language": null,
        "clipCount": 5,
        "minDurationSec": null,
        "maxDurationSec": null,
        "objective": "educational",
        "captionStyle": null,
        "reframe": null,
        "instructions": null,
        "vocabulary": null
      },
      "missingSettings": [
        "language",
        "minDurationSec",
        "maxDurationSec",
        "captionStyle",
        "reframe"
      ],
      "splitScreen": null,
      "streamer": null,
      "redditStory": null,
      "fakeText": null,
      "vibeEdit": null,
      "errorMessage": null,
      "createdAt": "2026-09-01T09:50:00.000Z",
      "updatedAt": "2026-09-01T09:50:00.000Z"
    },
    {
      "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"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
All response fields
NameTypeRequiredDescription
dataarray of objectsRequiredThe items of this page.
data[]Project objectOptionalDescribed in Project object.
hasMorebooleanRequiredtrue when there are more items after this page.
nextCursorstring or nullRequiredSend it as cursor to get the next page. It is null on the last page.
More examples

Ask for one project per page

GET /v1/projects?limit=1

HTTP 200
{
  "data": [
    {
      "id": "prj_1d8b6e0c47a24f93b1c2",
      "kind": "autoclip",
      "title": "Weekly podcast",
      "status": "draft",
      "sourceAssetId": null,
      "compositionId": null,
      "settings": {
        "language": null,
        "clipCount": 5,
        "minDurationSec": null,
        "maxDurationSec": null,
        "objective": "educational",
        "captionStyle": null,
        "reframe": null,
        "instructions": null,
        "vocabulary": null
      },
      "missingSettings": [
        "language",
        "minDurationSec",
        "maxDurationSec",
        "captionStyle",
        "reframe"
      ],
      "splitScreen": null,
      "streamer": null,
      "redditStory": null,
      "fakeText": null,
      "vibeEdit": null,
      "errorMessage": null,
      "createdAt": "2026-09-01T09:50:00.000Z",
      "updatedAt": "2026-09-01T09:50:00.000Z"
    }
  ],
  "hasMore": true,
  "nextCursor": "eyJrIjp7ImNyZWF0ZWRBdCI6IjIwMjYtMDktMDFUMDk6NTA6MDAuMDAwWiIsImlkIjoicHJqXzFkOGI2ZTBjNDdhMjRmOTNiMWMyIn0sInYiOjF9"
}

Read the next page

GET /v1/projects?limit=1&cursor=eyJrIjp7ImNyZWF0ZWRBdCI6IjIwMjYtMDktMDFUMDk6NTA6MDAuMDAwWiIsImlkIjoicHJqXzFkOGI2ZTBjNDdhMjRmOTNiMWMyIn0sInYiOjF9

HTTP 200
{
  "data": [
    {
      "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"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

A cursor written by hand

GET /v1/projects?cursor=page-2

HTTP 400
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The cursor is not valid. Send the nextCursor of the previous page unchanged, or leave it out.",
    "hint": "Fix the request as the message says, then send it again.",
    "requestId": "req_05e9c4a50265af20e2cd064b"
  }
}

Errors

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

Cost

No credits are used.

Questions

Why do I see projects I did not create through the API?

The API works on the same account as the GPT-Video app, so projects made in the app are listed too. Each kind of project is changed through its own operations, and kind says which kind it is.

Can a project appear twice while I page through the list?

No. The cursor marks the last project of the page, so a project created while you read starts a new first page and never shifts the ones after the cursor.

View as Markdown