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
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
writecall. 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}$. |
Body
The body is optional. Send only the fields you want to change.
| Name | Type | Required | Description |
|---|---|---|---|
title | string | Optional | The new name of the project. From 1 to 120 characters. Matches \S. |
postTitle | string | Optional | The title of the post, shown on the title card and read first. From 1 to 300 characters. From 1 to 300 characters. Matches \S. |
postBody | string | Optional | The text of the post, read by the voice. From 1 to 8000 characters. From 1 to 8000 characters. Matches \S. |
author | string | Optional | The author shown on the title card, such as u/thrown_away. From 1 to 40 characters. From 1 to 40 characters. |
subreddit | string | Optional | The community shown on the title card, such as r/stories. From 1 to 40 characters. From 1 to 40 characters. |
voice | string | Optional | The 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. |
language | string | Optional | The language of the story and of its voice. Send the voice of the new language in the same request. One of en, it. |
captionStyle | string | Optional | The 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. |
backgroundAssetId | string or null | Optional | The new background video, as complete_upload (POST /v1/uploads/{uploadId}/complete) returned it; null removes the background. Matches ^ast_n?[0-9a-f]{20}$. |
vocabulary | string or null | Optional | Names, 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.
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
| 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. |
Response example
{
"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
| Name | Type | Required | Description |
|---|---|---|---|
project | Project object | Required | Described in Project object. |
More examples
A new language without its voice
PATCH /v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story
{
"language": "it"
}{
"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
{
"subreddit": "r/stories"
}{
"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
| Code | Status | When | What to do |
|---|---|---|---|
NOT_FOUND | 404 | See the error reference. | Change the request, then send it again. |
CONFLICT | 409 | A project of another kind | Read 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).
Related operations
create_reddit_story_project(POST /v1/projects/reddit-story) Create a Reddit story projectbuild_reddit_story_video(POST /v1/projects/{projectId}/reddit-story/build) Build a Reddit story videoget_project(GET /v1/projects/{projectId}) Get a projectlist_voices(GET /v1/reference/voices) List the voices
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.