---
title: "Create a fake text project | GPT-Video API reference"
description: "Creates a fake text project, a chat story shown as a vertical video, with its look, language, voices and background chosen now."
url: "https://www.gpt-video.com/developers/api/create-fake-text-project"
operation: "create_fake_text_project"
method: "POST"
path: "/v1/projects/fake-text"
scope: "clips:write"
---

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

# Create a fake text project

Operation id `create_fake_text_project`. Request `POST /v1/projects/fake-text`.

Creates a fake text project, a chat story shown as a vertical video, with its look, language, voices and background chosen now.

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 start a fake text video. Choose the look of the chat, the language of the story, whether the lines get voices and the background video now; you can change them later with update_fake_text_project (`PATCH /v1/projects/{projectId}/fake-text`). The project starts without a story: write one with update_fake_text_story (`PUT /v1/projects/{projectId}/story`), or let GPT-Video write one with generate_fake_text_story (`POST /v1/projects/{projectId}/story/generate`). Then make the voices with create_fake_text_voices (`POST /v1/projects/{projectId}/story/voices`) and export the video with create_export (`POST /v1/compositions/{compositionId}/exports`), using the compositionId of the project.

## Example use

A script that makes one chat story video a day creates the project with the iMessage look and a background video, then writes the story with generate_fake_text_story (`POST /v1/projects/{projectId}/story/generate`).

## Endpoint

```text
POST https://api.gpt-video.com/v1/projects/fake-text
```

- 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).
- `Idempotency-Key` is optional.

## Parameters

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | Optional | Send the same key on every retry of this request. From 1 to 255 visible characters, such as a UUID. See [idempotency](/developers/pagination-and-idempotency.md). |

### Body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `theme` | string | Required | How the chat looks: imessage or whatsapp. One of `imessage`, `whatsapp`. |
| `language` | string | Required | The language of the story and of its voices: en or it. A story GPT-Video writes is written in it. One of `en`, `it`. |
| `voiceover` | boolean | Required | true to give each line a voice when you call create_fake_text_voices (`POST /v1/projects/{projectId}/story/voices`); false for a silent chat. |
| `backgroundAssetId` | string or null | Required | The video shown behind the chat: the asset id of a video you uploaded or imported. null for no background. Matches `^ast_n?[0-9a-f]{20}$`. |
| `title` | string | Optional | The name of the project. Without it the project is called Fake text story until GPT-Video writes a story for it, which names it. From 1 to 120 characters. Matches `\S`. |

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

## Request

Create a fake text project.

```bash title="curl"
curl -X POST "https://api.gpt-video.com/v1/projects/fake-text" \
  -H "Authorization: Bearer $GPT_VIDEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "theme": "imessage",
    "language": "en",
    "voiceover": true,
    "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
    "title": "Group chat drama"
  }'
```

```ts title="TypeScript"
const res = await fetch("https://api.gpt-video.com/v1/projects/fake-text", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "theme": "imessage",
    "language": "en",
    "voiceover": true,
    "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
    "title": "Group chat drama"
  }),
});
const data = await res.json();
console.log(data);
```

```python title="Python"
import os

import requests

r = requests.post(
    "https://api.gpt-video.com/v1/projects/fake-text",
    headers={
        "Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
    },
    json={
        "theme": "imessage",
        "language": "en",
        "voiceover": True,
        "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
        "title": "Group chat drama"
    },
)
data = r.json()
print(data)
```

```json title="MCP (Full)"
{
  "method": "tools/call",
  "params": {
    "name": "create_fake_text_project",
    "arguments": {
      "theme": "imessage",
      "language": "en",
      "voiceover": true,
      "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
      "title": "Group chat drama"
    }
  }
}
```

## Response

A successful call answers HTTP 201. 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

- `Location: https://api.gpt-video.com/v1/projects/prj_3c0f8e1d5a9b4e2786d1`

```json title="HTTP 201"
{
  "project": {
    "id": "prj_3c0f8e1d5a9b4e2786d1",
    "kind": "faketext",
    "title": "Group chat drama",
    "status": "draft",
    "sourceAssetId": null,
    "compositionId": null,
    "settings": null,
    "missingSettings": [],
    "splitScreen": null,
    "streamer": null,
    "redditStory": null,
    "fakeText": {
      "theme": "imessage",
      "language": "en",
      "voiceover": true,
      "backgroundAssetId": "ast_8ac5d8b97546145cdbf6",
      "storyId": null
    },
    "vibeEdit": null,
    "errorMessage": null,
    "createdAt": "2026-09-01T11:00:00.000Z",
    "updatedAt": "2026-09-01T11:00:00.000Z"
  }
}
```

**All response fields**

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

**More examples**

#### A silent chat with no background

`POST /v1/projects/fake-text`

```json title="Request body"
{
  "theme": "whatsapp",
  "language": "it",
  "voiceover": false,
  "backgroundAssetId": null
}
```

```json title="HTTP 201"
{
  "project": {
    "id": "prj_3c0f8e1d5a9b4e2786d1",
    "kind": "faketext",
    "title": "Fake text story",
    "status": "draft",
    "sourceAssetId": null,
    "compositionId": null,
    "settings": null,
    "missingSettings": [],
    "splitScreen": null,
    "streamer": null,
    "redditStory": null,
    "fakeText": {
      "theme": "whatsapp",
      "language": "it",
      "voiceover": false,
      "backgroundAssetId": null,
      "storyId": null
    },
    "vibeEdit": null,
    "errorMessage": null,
    "createdAt": "2026-09-01T11:00:00.000Z",
    "updatedAt": "2026-09-01T11:00:00.000Z"
  }
}
```

#### A background that is not a video

`POST /v1/projects/fake-text`

```json title="Request body"
{
  "theme": "imessage",
  "language": "en",
  "voiceover": true,
  "backgroundAssetId": "ast_e8a35ed674148f27b585"
}
```

```json title="HTTP 409"
{
  "error": {
    "code": "CONFLICT",
    "message": "The background must be a video.",
    "requestId": "req_51a7c3e09d2b4f6e8a1c0b3d"
  }
}
```

#### A background that does not exist

`POST /v1/projects/fake-text`

```json title="Request body"
{
  "theme": "imessage",
  "language": "en",
  "voiceover": true,
  "backgroundAssetId": "ast_0b1e5c9d3a7f40628e2d"
}
```

```json title="HTTP 404"
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Asset ast_0b1e5c9d3a7f40628e2d not found",
    "hint": "Check the id. An id that belongs to another account is not found either.",
    "requestId": "req_2e8b6d4a0c1f4793b5e7a9d2"
  }
}
```

## Errors

| Code | Status | When | What to do |
| --- | --- | --- | --- |
| [`NOT_FOUND`](/developers/errors.md#NOT_FOUND) | 404 | A background that does not exist | Change the request, then send it again. |
| [`CONFLICT`](/developers/errors.md#CONFLICT) | 409 | A background that is not a video | 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), [`IDEMPOTENCY_IN_PROGRESS`](/developers/errors.md#IDEMPOTENCY_IN_PROGRESS), [`PAYLOAD_TOO_LARGE`](/developers/errors.md#PAYLOAD_TOO_LARGE), [`IDEMPOTENCY_KEY_REUSED`](/developers/errors.md#IDEMPOTENCY_KEY_REUSED), [`RATE_LIMITED`](/developers/errors.md#RATE_LIMITED), [`INTERNAL`](/developers/errors.md#INTERNAL), [`UNAVAILABLE`](/developers/errors.md#UNAVAILABLE).

## Cost

No credits are used.

## Related operations

- [`update_fake_text_project`](/developers/api/update-fake-text-project.md) (`PATCH /v1/projects/{projectId}/fake-text`) Update a fake text project
- [`update_fake_text_story`](/developers/api/update-fake-text-story.md) (`PUT /v1/projects/{projectId}/story`) Write the story of a fake text project
- [`generate_fake_text_story`](/developers/api/generate-fake-text-story.md) (`POST /v1/projects/{projectId}/story/generate`) Write a fake text story with GPT-Video
- [`get_project`](/developers/api/get-project.md) (`GET /v1/projects/{projectId}`) Get a project

## Questions

### Which videos can be the background?

Any video you uploaded with create_upload (`POST /v1/uploads`) or imported. The background plays behind the chat for as long as the story lasts.

### Can I change the language after the story is written?

Yes, with update_fake_text_project (`PATCH /v1/projects/{projectId}/fake-text`). The words of the story stay as they are; a side whose voice is of the other language goes back to the default voice of the new language.
