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.

Update a Reddit story project

update_reddit_story_projectPATCH/v1/projects/{projectId}/reddit-storyBeta

Changes the post, the voice, the language, the captions or the background video of a Reddit story project.

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

Only the fields you send change. A new language needs a voice of that language in the same request, because each voice reads one language. The background video can be changed, or removed with null. The changes are used by the next build, which is charged; a change saved while a build waits in the queue is read by that build.

Example use

A script fixes a typo in an English post and switches to another English voice from list_voices (GET /v1/reference/voices). It sends only postBody and voice, then builds the video again with build_reddit_story_video (POST /v1/projects/{projectId}/reddit-story/build).

Endpoint

Code
PATCH https://api.gpt-video.com/v1/projects/{projectId}/reddit-story
  • 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.
  • No Idempotency-Key.

Parameters

Path

NameTypeRequiredDescription
projectIdstringRequiredThe project id. It starts with prj_. Matches ^prj_[0-9a-f]{20}$.

Body

The body is optional. Send only the fields you want to change.

NameTypeRequiredDescription
titlestringOptionalThe new name of the project. From 1 to 120 characters. Matches \S.
postTitlestringOptionalThe title of the post, shown on the title card and read first. From 1 to 300 characters. From 1 to 300 characters. Matches \S.
postBodystringOptionalThe text of the post, read by the voice. From 1 to 8000 characters. From 1 to 8000 characters. Matches \S.
authorstringOptionalThe author shown on the title card, such as u/thrown_away. From 1 to 40 characters. From 1 to 40 characters.
subredditstringOptionalThe community shown on the title card, such as r/stories. From 1 to 40 characters. From 1 to 40 characters.
voicestringOptionalThe voice that reads the story, as list_voices (GET /v1/reference/voices) names it. It must be a voice of the story's language. One of en-aria, en-jenny, en-guy, en-christopher, it-elsa, it-isabella, it-diego, it-giuseppe.
languagestringOptionalThe language of the story and of its voice. Send the voice of the new language in the same request. One of en, it.
captionStylestringOptionalThe caption style. get_setting_options (GET /v1/reference/setting-options) lists every style with what it looks like. One of bold-karaoke, word-pop, boxed, outline.
backgroundAssetIdstring or nullOptionalThe new background video, as complete_upload (POST /v1/uploads/{uploadId}/complete) returned it; null removes the background. Matches ^ast_n?[0-9a-f]{20}$.
vocabularystring or nullOptionalNames, brands and jargon the transcription should spell right, separated by commas. At most 311 characters; null removes it. At most 311 characters.

Send only the fields listed here. Any other field is refused with UNKNOWN_PARAMETER.

Request

Change the post and the background video.

Request example
curl -X PATCH "https://api.gpt-video.com/v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Leaving my own party",
    "postTitle": "Was I wrong to leave my own party early?",
    "subreddit": "r/TrueOffMyChest",
    "backgroundAssetId": "ast_2a2215a18805ec31c629"
  }'
const res = await fetch("https://api.gpt-video.com/v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story", {
  method: "PATCH",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "title": "Leaving my own party",
    "postTitle": "Was I wrong to leave my own party early?",
    "subreddit": "r/TrueOffMyChest",
    "backgroundAssetId": "ast_2a2215a18805ec31c629"
  }),
});
const data = await res.json();
console.log(data);
import os

import requests

r = requests.patch(
    "https://api.gpt-video.com/v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
    json={
        "title": "Leaving my own party",
        "postTitle": "Was I wrong to leave my own party early?",
        "subreddit": "r/TrueOffMyChest",
        "backgroundAssetId": "ast_2a2215a18805ec31c629"
    },
)
data = r.json()
print(data)
{
  "method": "tools/call",
  "params": {
    "name": "update_reddit_story_project",
    "arguments": {
      "projectId": "prj_b71ffef7c27c5ea1cc87",
      "title": "Leaving my own party",
      "postTitle": "Was I wrong to leave my own party early?",
      "subreddit": "r/TrueOffMyChest",
      "backgroundAssetId": "ast_2a2215a18805ec31c629"
    }
  }
}

Response

A successful call answers HTTP 200. Returns a Project object in project.

Fields to check

NameTypeDescription
project.idstringThe project id. It starts with prj_.
project.statusstringdraft has not been analyzed yet, processing is being analyzed, ready has clips, failed means the last analysis failed and errorMessage says why.

Response example

HTTP 200
{
  "project": {
    "id": "prj_b71ffef7c27c5ea1cc87",
    "kind": "redditstory",
    "title": "Leaving my own party",
    "status": "ready",
    "sourceAssetId": null,
    "compositionId": "cmp_926433093fafcd62c9cb",
    "settings": null,
    "missingSettings": [],
    "errorMessage": null,
    "splitScreen": null,
    "streamer": null,
    "redditStory": {
      "postBody": "I left my own birthday party after an hour and my sister says I ruined it",
      "author": "u/thrown_away_42",
      "voice": "en-aria",
      "language": "en",
      "captionStyle": "bold-karaoke",
      "vocabulary": null,
      "postTitle": "Was I wrong to leave my own party early?",
      "subreddit": "r/TrueOffMyChest",
      "backgroundAssetId": "ast_2a2215a18805ec31c629"
    },
    "fakeText": null,
    "vibeEdit": null,
    "createdAt": "2026-08-31T22:00:00.000Z",
    "updatedAt": "2026-09-01T11:05:00.000Z"
  }
}
All response fields
NameTypeRequiredDescription
projectProject objectRequiredDescribed in Project object.
More examples

A new language without its voice

PATCH /v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story

Request body
{
  "language": "it"
}
HTTP 400
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Send the voice together with the new language: voices belong to one language.",
    "hint": "Fix the request as the message says, then send it again.",
    "requestId": "req_e3a0c7f4b1d8256e9a3c0f71"
  }
}

A project of another kind

PATCH /v1/projects/prj_7c2e9a4f1b3d4e8096a5/reddit-story

Request body
{
  "subreddit": "r/stories"
}
HTTP 409
{
  "error": {
    "code": "CONFLICT",
    "message": "This project is not a Reddit story project. Use the operations of its kind, or analyze_project for an Auto Clip project.",
    "requestId": "req_2b9d6a3f0c7e14b85d2a9f60"
  }
}

Errors

CodeStatusWhenWhat to do
NOT_FOUND404See the error reference.Change the request, then send it again.
CONFLICT409A project of another kindRead 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, PAYLOAD_TOO_LARGE, RATE_LIMITED, INTERNAL, UNAVAILABLE.

Cost

No credits are used. The next build is charged when you call build_reddit_story_video (POST /v1/projects/{projectId}/reddit-story/build).

Questions

How do I change the language of a story?

Send the new language and a voice of that language in the same request. list_voices (GET /v1/reference/voices) names the voices of each language.

Does a new background change the price?

No. A Reddit story build costs one credit whatever the background, so the background can be changed at any time.

View as Markdown