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.

Restore a rejected clip

restore_clipPOST/v1/clips/{clipId}/restoreBeta

Brings a rejected clip back among the proposed clips, with the same id.

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 undo reject_clip (POST /v1/clips/{clipId}/reject): the clip goes back to status proposed, waiting for a decision. Restoring a clip that is already proposed changes nothing and answers the clip. An accepted clip cannot be restored, and the answer is CONFLICT. Works on clips of Auto Clip projects only.

Example use

An editor who rejected a clip by mistake clicks undo in the review tool. The tool calls this, and the clip returns to the list of clips to review with the same id it had before.

Endpoint

Code
POST https://api.gpt-video.com/v1/clips/{clipId}/restore
  • Scope clips:write.
  • Rate limit 60 requests a minute for each key and 120 for each account, shared by every write call. See rate limits.
  • Idempotency-Key is optional.

Parameters

Path

NameTypeRequiredDescription
clipIdstringRequiredThe id of the clip, as list_clips (GET /v1/projects/{projectId}/clips) returns it. Matches ^cnd_[0-9a-f]{20}$.

Headers

NameTypeRequiredDescription
Idempotency-KeystringOptionalSend the same key on every retry of this request. From 1 to 255 visible characters, such as a UUID. See idempotency.

Request

Restore a rejected clip.

Request example
curl -X POST "https://api.gpt-video.com/v1/clips/cnd_6a3d1f8e0b574c29d4e3/restore" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY"
const res = await fetch("https://api.gpt-video.com/v1/clips/cnd_6a3d1f8e0b574c29d4e3/restore", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
  },
});
const data = await res.json();
console.log(data);
import os

import requests

r = requests.post(
    "https://api.gpt-video.com/v1/clips/cnd_6a3d1f8e0b574c29d4e3/restore",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
)
data = r.json()
print(data)
{
  "method": "tools/call",
  "params": {
    "name": "restore_clip",
    "arguments": {
      "clipId": "cnd_6a3d1f8e0b574c29d4e3"
    }
  }
}

Response

A successful call answers HTTP 200. Returns a Clip object in clip.

Fields to check

NameTypeDescription
clip.idstringThe clip id. It starts with cnd_.
clip.statusstringproposed is waiting for a decision, accepted has a composition, rejected was set aside and can be restored.

Response example

HTTP 200
{
  "clip": {
    "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": "proposed",
    "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
  }
}
All response fields
NameTypeRequiredDescription
clipClip objectRequiredDescribed in Clip object.
More examples

Restore a clip that was accepted

POST /v1/clips/cnd_9e04a6c3d12b4f78a5b9/restore

HTTP 409
{
  "error": {
    "code": "CONFLICT",
    "message": "Only a rejected clip can be restored, and this clip is accepted.",
    "requestId": "req_0b4e8c2a6d1f47e3b9a5c7d2"
  }
}

Errors

CodeStatusWhenWhat to do
NOT_FOUND404See the error reference.Change the request, then send it again.
CONFLICT409Restore a clip that was acceptedRead 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, IDEMPOTENCY_IN_PROGRESS, PAYLOAD_TOO_LARGE, IDEMPOTENCY_KEY_REUSED, RATE_LIMITED, INTERNAL, UNAVAILABLE.

Cost

No credits are used.

  • reject_clip (POST /v1/clips/{clipId}/reject) Reject a clip
  • list_clips (GET /v1/projects/{projectId}/clips) List the clips of a project

Questions

Does a restored clip keep its id?

Yes. Restoring only changes the status back to proposed; the id, the score and everything else stay the same.

Can I restore a clip after the project was analyzed again?

No. A new analysis removes the rejected clips, and their ids answer NOT_FOUND. The new analysis proposes its own clips.

View as Markdown