---
title: "Update a Reddit story project | GPT-Video API reference"
description: "Changes the post, the voice, the language, the captions or the background video of a Reddit story project."
url: "https://www.gpt-video.com/developers/api/update-reddit-story-project"
operation: "update_reddit_story_project"
method: "PATCH"
path: "/v1/projects/{projectId}/reddit-story"
scope: "clips:write"
---

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

# Update a Reddit story project

Operation id `update_reddit_story_project`. Request `PATCH /v1/projects/{projectId}/reddit-story`.

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

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

```bash title="curl"
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"
  }'
```

```ts title="TypeScript"
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);
```

```python title="Python"
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)
```

```json title="MCP (Full)"
{
  "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](/developers/objects.md#project) 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

```json title="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**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `project` | Project object | Required | Described in [Project object](/developers/objects.md#project). |

**More examples**

#### A new language without its voice

`PATCH /v1/projects/prj_b71ffef7c27c5ea1cc87/reddit-story`

```json title="Request body"
{
  "language": "it"
}
```

```json title="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`

```json title="Request body"
{
  "subreddit": "r/stories"
}
```

```json title="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

| 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 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`](/developers/errors.md#VALIDATION_FAILED), [`UNKNOWN_PARAMETER`](/developers/errors.md#UNKNOWN_PARAMETER), [`UNAUTHORIZED`](/developers/errors.md#UNAUTHORIZED), [`SCOPE_MISSING`](/developers/errors.md#SCOPE_MISSING), [`PAYLOAD_TOO_LARGE`](/developers/errors.md#PAYLOAD_TOO_LARGE), [`RATE_LIMITED`](/developers/errors.md#RATE_LIMITED), [`INTERNAL`](/developers/errors.md#INTERNAL), [`UNAVAILABLE`](/developers/errors.md#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`](/developers/api/create-reddit-story-project.md) (`POST /v1/projects/reddit-story`) Create a Reddit story project
- [`build_reddit_story_video`](/developers/api/build-reddit-story-video.md) (`POST /v1/projects/{projectId}/reddit-story/build`) Build a Reddit story video
- [`get_project`](/developers/api/get-project.md) (`GET /v1/projects/{projectId}`) Get a project
- [`list_voices`](/developers/api/list-voices.md) (`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.
