---
title: "Update a split screen project | GPT-Video API reference"
description: "Changes the name, the layout, the captions, the start of the background or the vocabulary of a split screen project."
url: "https://www.gpt-video.com/developers/api/update-split-screen-project"
operation: "update_split_screen_project"
method: "PATCH"
path: "/v1/projects/{projectId}/split-screen"
scope: "clips:write"
---

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

# Update a split screen project

Operation id `update_split_screen_project`. Request `PATCH /v1/projects/{projectId}/split-screen`.

Changes the name, the layout, the captions, the start of the background or the vocabulary of a split screen 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. 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. The two videos and the language cannot be changed: sending them is refused, and to use other videos you create another project.

## Example use

A script changes the layout and the captions of a project after a first build looked crowded. It builds the video again with build_split_screen_video (`POST /v1/projects/{projectId}/split-screen/build`) once the settings are right.

## Endpoint

```text
PATCH https://api.gpt-video.com/v1/projects/{projectId}/split-screen
```

- 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`. |
| `layout` | string | Optional | How the screen is split: 50-50 gives each video half the screen, 60-40 gives the main video more. One of `50-50`, `60-40`. |
| `captionStyle` | string or null | Optional | The caption style, or null for a video with no captions. get_setting_options (`GET /v1/reference/setting-options`) lists every style with what it looks like. One of `bold-karaoke`, `word-pop`, `boxed`, `outline`. |
| `backgroundStartSec` | number or null | Optional | Where the background video starts, in seconds; null lets the next build choose a random start, which is then kept. At least 0. |
| `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 layout and the start of the background.

```bash title="curl"
curl -X PATCH "https://api.gpt-video.com/v1/projects/prj_9cf6ba9cd17fd89cf513/split-screen" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "layout": "50-50",
    "backgroundStartSec": 12
  }'
```

```ts title="TypeScript"
const res = await fetch("https://api.gpt-video.com/v1/projects/prj_9cf6ba9cd17fd89cf513/split-screen", {
  method: "PATCH",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "layout": "50-50",
    "backgroundStartSec": 12
  }),
});
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_9cf6ba9cd17fd89cf513/split-screen",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
    json={
        "layout": "50-50",
        "backgroundStartSec": 12
    },
)
data = r.json()
print(data)
```

```json title="MCP (Full)"
{
  "method": "tools/call",
  "params": {
    "name": "update_split_screen_project",
    "arguments": {
      "projectId": "prj_9cf6ba9cd17fd89cf513",
      "layout": "50-50",
      "backgroundStartSec": 12
    }
  }
}
```

## 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_9cf6ba9cd17fd89cf513",
    "kind": "splitscreen",
    "title": "Founder interview, split",
    "status": "ready",
    "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
    "compositionId": "cmp_cc26cb47fd6004aa5fba",
    "settings": null,
    "missingSettings": [],
    "errorMessage": null,
    "splitScreen": {
      "mainAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
      "layout": "50-50",
      "captionStyle": "bold-karaoke",
      "language": "en",
      "backgroundStartSec": 12,
      "vocabulary": null
    },
    "streamer": null,
    "redditStory": null,
    "fakeText": null,
    "vibeEdit": null,
    "createdAt": "2026-08-31T21:40: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**

#### Remove the captions

`PATCH /v1/projects/prj_9cf6ba9cd17fd89cf513/split-screen`

```json title="Request body"
{
  "captionStyle": null
}
```

```json title="HTTP 200"
{
  "project": {
    "id": "prj_9cf6ba9cd17fd89cf513",
    "kind": "splitscreen",
    "title": "Founder interview, split",
    "status": "ready",
    "sourceAssetId": "ast_3f9a1c7e5b2d4086a1c4",
    "compositionId": "cmp_cc26cb47fd6004aa5fba",
    "settings": null,
    "missingSettings": [],
    "errorMessage": null,
    "splitScreen": {
      "mainAssetId": "ast_3f9a1c7e5b2d4086a1c4",
      "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
      "layout": "60-40",
      "captionStyle": null,
      "language": "en",
      "backgroundStartSec": null,
      "vocabulary": null
    },
    "streamer": null,
    "redditStory": null,
    "fakeText": null,
    "vibeEdit": null,
    "createdAt": "2026-08-31T21:40:00.000Z",
    "updatedAt": "2026-09-01T11:05:00.000Z"
  }
}
```

#### A project of another kind

`PATCH /v1/projects/prj_7c2e9a4f1b3d4e8096a5/split-screen`

```json title="Request body"
{
  "layout": "50-50"
}
```

```json title="HTTP 409"
{
  "error": {
    "code": "CONFLICT",
    "message": "This project is not a split screen project. Use the operations of its kind, or analyze_project for an Auto Clip project.",
    "requestId": "req_4a0d7e2b9c1f63e85b2a0d14"
  }
}
```

## 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_split_screen_video (`POST /v1/projects/{projectId}/split-screen/build`).

## Related operations

- [`create_split_screen_project`](/developers/api/create-split-screen-project.md) (`POST /v1/projects/split-screen`) Create a split screen project
- [`build_split_screen_video`](/developers/api/build-split-screen-video.md) (`POST /v1/projects/{projectId}/split-screen/build`) Build a split screen video
- [`get_project`](/developers/api/get-project.md) (`GET /v1/projects/{projectId}`) Get a project

## Questions

### Why is mainAssetId refused here?

The videos of a split screen project are chosen when it is created and never change, because the price depends on them. Create another project to use other videos.

### When do my changes show in the video?

At the next build. build_split_screen_video (`POST /v1/projects/{projectId}/split-screen/build`) makes the video again with the settings saved at the moment the build starts.
