---
title: "List the clips of a project | GPT-Video API reference"
description: "Returns the clips an analysis found in a project, in the order the analysis ranked them."
url: "https://www.gpt-video.com/developers/api/list-clips"
operation: "list_clips"
method: "GET"
path: "/v1/projects/{projectId}/clips"
scope: "clips:read"
---

Do not assume endpoints have parameters other than the ones explicitly specified.

# List the clips of a project

Operation id `list_clips`. Request `GET /v1/projects/{projectId}/clips`.

Returns the clips an analysis found in a project, in the order the analysis ranked them.

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

Call this when the analysis of a project is done, to see the clips it found: where each one sits in the source video, its title and hook, and a score explained factor by factor. Filter by status to see only the clips still waiting for a decision. Analyzing the project again replaces the proposed and rejected clips with new ones, with new ids, and keeps the accepted ones; a cursor issued before that answers CONFLICT, and you start again without it. Accept a clip with accept_clip (`POST /v1/clips/{clipId}/accept`) to get a composition you can export. Works on Auto Clip projects only.

## Example use

After the analysis of a podcast episode finishes, a review tool lists the clips that still wait for a decision and shows their titles, hooks and scores to an editor, who picks the ones to publish.

## Endpoint

```text
GET https://api.gpt-video.com/v1/projects/{projectId}/clips
```

- 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](/developers/rate-limits.md).
- No `Idempotency-Key`.

## Parameters

### Path

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `projectId` | string | Required | The id of the project, as create_project (`POST /v1/projects`) returns it. Matches `^prj_[0-9a-f]{20}$`. |

### Query

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string | Optional | Only the clips with this status. Leave it out to get every clip. One of `proposed`, `accepted`, `rejected`. |
| `limit` | integer | Optional | How many items to return, from 1 to 100. Defaults to 20. From 1 to 100. Default `20`. |
| `cursor` | string | Optional | The nextCursor value from the previous page. Leave it out to get the first page. From 1 to 512 characters. |

## Request

List the clips of a project.

```bash title="curl"
curl "https://api.gpt-video.com/v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
```

```ts title="TypeScript"
const res = await fetch("https://api.gpt-video.com/v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
  },
});
const data = await res.json();
console.log(data);
```

```python title="Python"
import os

import requests

r = requests.get(
    "https://api.gpt-video.com/v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips",
    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 |
| --- | --- | --- |
| `data[].id` | string | The clip id. It starts with cnd_. |
| `data[].status` | string | proposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored. |
| `hasMore` | boolean | true when there are more items after this page. |
| `nextCursor` | string or null | Send it as cursor to get the next page. It is null on the last page. |

### Response example

```json title="HTTP 200"
{
  "data": [
    {
      "id": "cnd_9e04a6c3d12b4f78a5b9",
      "projectId": "prj_7c2e9a4f1b3d4e8096a5",
      "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "summary": "The founder explains how the first customer paid before the product existed.",
      "reason": "A clear claim in the first seconds and a result at the end.",
      "tags": [
        "startups",
        "sales"
      ],
      "createdAt": "2026-09-01T09:40:00.000Z",
      "status": "accepted",
      "rank": 0,
      "startSec": 120,
      "endSec": 150,
      "durationSec": 30,
      "title": "Paid before the product",
      "hook": "They paid us before we had a product",
      "score": 87.5,
      "scoreBreakdown": [
        {
          "factor": "hook",
          "label": "Hook (first 3 seconds)",
          "score": 9,
          "note": "Opens on a concrete claim."
        },
        {
          "factor": "payoff",
          "label": "Payoff / ending",
          "score": 8,
          "note": "Ends on the result."
        },
        {
          "factor": "clarity",
          "label": "Clarity",
          "score": 7,
          "note": "One idea, said plainly."
        },
        {
          "factor": "emotion",
          "label": "Emotion",
          "score": 9,
          "note": "The speaker sounds surprised."
        },
        {
          "factor": "novelty",
          "label": "Novelty / surprise",
          "score": 8,
          "note": "Not the usual advice."
        },
        {
          "factor": "selfContained",
          "label": "Self-contained",
          "score": 7,
          "note": "Needs no context."
        },
        {
          "factor": "quotability",
          "label": "Quotability",
          "score": 9,
          "note": "Has a line people repeat."
        },
        {
          "factor": "dialogue",
          "label": "Dialogue (back-and-forth)",
          "score": 8,
          "note": "A single speaker."
        }
      ],
      "transcriptExcerpt": "before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that",
      "social": {
        "title": "Paid before the product",
        "caption": "How a first customer paid before there was a product.",
        "hashtags": [
          "#startup",
          "#founder"
        ]
      },
      "compositionId": "cmp_4e8c2a6f09d14b73a1e5"
    },
    {
      "id": "cnd_2b7f4e91a0c84d35e6f0",
      "projectId": "prj_7c2e9a4f1b3d4e8096a5",
      "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "summary": "The founder explains how the first customer paid before the product existed.",
      "reason": "A clear claim in the first seconds and a result at the end.",
      "tags": [
        "startups",
        "sales"
      ],
      "createdAt": "2026-09-01T09:40:00.000Z",
      "status": "proposed",
      "rank": 1,
      "startSec": 300,
      "endSec": 330,
      "durationSec": 30,
      "title": "The first customer",
      "hook": "Our first customer changed everything",
      "score": 81,
      "scoreBreakdown": [
        {
          "factor": "hook",
          "label": "Hook (first 3 seconds)",
          "score": 8,
          "note": "Opens on a concrete claim."
        },
        {
          "factor": "payoff",
          "label": "Payoff / ending",
          "score": 7,
          "note": "Ends on the result."
        },
        {
          "factor": "clarity",
          "label": "Clarity",
          "score": 6,
          "note": "One idea, said plainly."
        },
        {
          "factor": "emotion",
          "label": "Emotion",
          "score": 8,
          "note": "The speaker sounds surprised."
        },
        {
          "factor": "novelty",
          "label": "Novelty / surprise",
          "score": 7,
          "note": "Not the usual advice."
        },
        {
          "factor": "selfContained",
          "label": "Self-contained",
          "score": 6,
          "note": "Needs no context."
        },
        {
          "factor": "quotability",
          "label": "Quotability",
          "score": 8,
          "note": "Has a line people repeat."
        },
        {
          "factor": "dialogue",
          "label": "Dialogue (back-and-forth)",
          "score": 7,
          "note": "A single speaker."
        }
      ],
      "transcriptExcerpt": "before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that",
      "social": {
        "title": "The first customer",
        "caption": "How a first customer paid before there was a product.",
        "hashtags": [
          "#startup",
          "#founder"
        ]
      },
      "compositionId": null
    },
    {
      "id": "cnd_6a3d1f8e0b574c29d4e3",
      "projectId": "prj_7c2e9a4f1b3d4e8096a5",
      "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "summary": "The founder explains how the first customer paid before the product existed.",
      "reason": "A clear claim in the first seconds and a result at the end.",
      "tags": [
        "startups",
        "sales"
      ],
      "createdAt": "2026-09-01T09:40:00.000Z",
      "status": "rejected",
      "rank": 2,
      "startSec": 600,
      "endSec": 640,
      "durationSec": 40,
      "title": "Team habits",
      "hook": "What our team does every morning",
      "score": 64,
      "scoreBreakdown": [
        {
          "factor": "hook",
          "label": "Hook (first 3 seconds)",
          "score": 6,
          "note": "Opens on a concrete claim."
        },
        {
          "factor": "payoff",
          "label": "Payoff / ending",
          "score": 5,
          "note": "Ends on the result."
        },
        {
          "factor": "clarity",
          "label": "Clarity",
          "score": 4,
          "note": "One idea, said plainly."
        },
        {
          "factor": "emotion",
          "label": "Emotion",
          "score": 6,
          "note": "The speaker sounds surprised."
        },
        {
          "factor": "novelty",
          "label": "Novelty / surprise",
          "score": 5,
          "note": "Not the usual advice."
        },
        {
          "factor": "selfContained",
          "label": "Self-contained",
          "score": 4,
          "note": "Needs no context."
        },
        {
          "factor": "quotability",
          "label": "Quotability",
          "score": 6,
          "note": "Has a line people repeat."
        },
        {
          "factor": "dialogue",
          "label": "Dialogue (back-and-forth)",
          "score": 5,
          "note": "A single speaker."
        }
      ],
      "transcriptExcerpt": "before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer",
      "social": {
        "title": "Team habits",
        "caption": "How a first customer paid before there was a product.",
        "hashtags": [
          "#startup",
          "#founder"
        ]
      },
      "compositionId": null
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
```

**All response fields**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `data` | array of objects | Required | The items of this page. |
| `data[]` | Clip object | Optional | Described in [Clip object](/developers/objects.md#clip). |
| `hasMore` | boolean | Required | true when there are more items after this page. |
| `nextCursor` | string or null | Required | Send it as cursor to get the next page. It is null on the last page. |

**More examples**

#### Only the clips waiting for a decision

`GET /v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips?status=proposed`

```json title="HTTP 200"
{
  "data": [
    {
      "id": "cnd_2b7f4e91a0c84d35e6f0",
      "projectId": "prj_7c2e9a4f1b3d4e8096a5",
      "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "summary": "The founder explains how the first customer paid before the product existed.",
      "reason": "A clear claim in the first seconds and a result at the end.",
      "tags": [
        "startups",
        "sales"
      ],
      "createdAt": "2026-09-01T09:40:00.000Z",
      "status": "proposed",
      "rank": 1,
      "startSec": 300,
      "endSec": 330,
      "durationSec": 30,
      "title": "The first customer",
      "hook": "Our first customer changed everything",
      "score": 81,
      "scoreBreakdown": [
        {
          "factor": "hook",
          "label": "Hook (first 3 seconds)",
          "score": 8,
          "note": "Opens on a concrete claim."
        },
        {
          "factor": "payoff",
          "label": "Payoff / ending",
          "score": 7,
          "note": "Ends on the result."
        },
        {
          "factor": "clarity",
          "label": "Clarity",
          "score": 6,
          "note": "One idea, said plainly."
        },
        {
          "factor": "emotion",
          "label": "Emotion",
          "score": 8,
          "note": "The speaker sounds surprised."
        },
        {
          "factor": "novelty",
          "label": "Novelty / surprise",
          "score": 7,
          "note": "Not the usual advice."
        },
        {
          "factor": "selfContained",
          "label": "Self-contained",
          "score": 6,
          "note": "Needs no context."
        },
        {
          "factor": "quotability",
          "label": "Quotability",
          "score": 8,
          "note": "Has a line people repeat."
        },
        {
          "factor": "dialogue",
          "label": "Dialogue (back-and-forth)",
          "score": 7,
          "note": "A single speaker."
        }
      ],
      "transcriptExcerpt": "before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that changed everything for our team the first customer paid us before we had a product and that",
      "social": {
        "title": "The first customer",
        "caption": "How a first customer paid before there was a product.",
        "hashtags": [
          "#startup",
          "#founder"
        ]
      },
      "compositionId": null
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
```

#### A cursor from before the project was analyzed again

`GET /v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips?cursor=eyJrIjp7ImlkIjoiY25kXzRjOGUwYTJmNmQxYjQ5ZTdhM2M1IiwibGlzdCI6IjF4OGtxMnYwbTdkMyIsInJhbmsiOjF9LCJ2IjoxfQ`

```json title="HTTP 409"
{
  "error": {
    "code": "CONFLICT",
    "message": "The clips of this project changed after this cursor was issued, because the project was analyzed again. Start again without a cursor.",
    "requestId": "req_5a0c2e7d9b3f41a68c1e2d04"
  }
}
```

#### A project that is not an Auto Clip project

`GET /v1/projects/prj_7c2e9a4f1b3d4e8096a5/clips`

```json title="HTTP 409"
{
  "error": {
    "code": "CONFLICT",
    "message": "This project is not an Auto Clip project. This operation works on Auto Clip projects only. Use the operations of its kind.",
    "requestId": "req_7e3b1d9a0c5f42e8b6a1d3c7"
  }
}
```

## Errors

| Code | Status | When | What to do |
| --- | --- | --- | --- |
| [`NOT_FOUND`](/developers/errors.md#NOT_FOUND) | 404 | See the error reference. | Change the request, then send it again. |
| [`CONFLICT`](/developers/errors.md#CONFLICT) | 409 | A cursor from before the project was analyzed again | Read the resource again, then decide. Do not send the same request again. |

Every call can also answer these errors. [`VALIDATION_FAILED`](/developers/errors.md#VALIDATION_FAILED), [`UNKNOWN_PARAMETER`](/developers/errors.md#UNKNOWN_PARAMETER), [`UNAUTHORIZED`](/developers/errors.md#UNAUTHORIZED), [`SCOPE_MISSING`](/developers/errors.md#SCOPE_MISSING), [`RATE_LIMITED`](/developers/errors.md#RATE_LIMITED), [`INTERNAL`](/developers/errors.md#INTERNAL), [`UNAVAILABLE`](/developers/errors.md#UNAVAILABLE).

## Cost

No credits are used.

## Related operations

- [`get_clip`](/developers/api/get-clip.md) (`GET /v1/clips/{clipId}`) Get a clip
- [`accept_clip`](/developers/api/accept-clip.md) (`POST /v1/clips/{clipId}/accept`) Accept a clip
- [`reject_clip`](/developers/api/reject-clip.md) (`POST /v1/clips/{clipId}/reject`) Reject a clip
- [`analyze_project`](/developers/api/analyze-project.md) (`POST /v1/projects/{projectId}/analyze`) Analyze a project
- [`get_project`](/developers/api/get-project.md) (`GET /v1/projects/{projectId}`) Get a project
- [`restore_clip`](/developers/api/restore-clip.md) (`POST /v1/clips/{clipId}/restore`) Restore a rejected clip

## Questions

### Why did the ids of my clips change?

The project was analyzed again. A new analysis replaces the proposed and rejected clips with new ones, with new ids, and keeps the accepted clips with their ids and compositions.

### What does the score mean?

It ranks the clips of one project against each other, from 0 to 100, and scoreBreakdown explains it factor by factor. It is not a probability that a clip goes viral.

### In what order do the clips come?

By rank, the order the analysis ranked them in. A new analysis ranks the accepted clips it keeps first, then the new ones. The order does not change between pages, and accepting, rejecting or restoring a clip between two pages keeps the cursor valid.
