---
search:
  tags:
    - Episodes
    - POST
seo:
  description: >-
    Generate a new episode (asynchronous). Reference for the POST
    /v1/episodes/generate endpoint in the Jellypod API.
sidebar:
  label: Generate a new episode (asynchronous)
  badge: POST
title: Generate a new episode (asynchronous)
type: openapi-operation
---
`POST /v1/episodes/generate`

**Request body** (`application/json`, required)

- `host_ids` (string[]) — Hosts to use for generation. In script mode, every segment host\_id must be included here, or omit host\_ids to infer them from the script.
- `language` (string)
- `options` (object) — Prompt-mode generation options. These are not used when \`script\` is provided.
- `prompt` (string) — Prompt used to write the episode script. Omit it to write the episode from \`source\_ids\` alone. Provide \`prompt\`, \`source\_ids\`, or both, or \`script\` instead.
- `script` (ImportedEpisodeScript) — Structured script input for episode generation. Script mode skips prompt-based script writing. Limits: 75000 total text characters, 50 chapters, 200 segments per chapter, 600 total segments, and 5000 characters per segment.
- `source_ids` (string<uuid>[]) — Source documents for prompt-based generation. Not supported when \`script\` is provided.
- `podcast_id` (string<uuid>, required) — Podcast that will own the generated episode.
- `outputs` (string[]) — Files to produce: audio (MP3), video (MP4 with sound), both, or \[\] for an editable draft. Each requested file becomes downloadable independently. Do not combine with render. Omission preserves legacy render behavior.
- `render` (boolean) — Deprecated: use outputs. True produces audio and video; false or omission leaves an editable draft. Do not combine with outputs.

Request body example:

```json
{
  "host_ids": [
    "2e6939fe",
    "a91c4d22"
  ],
  "language": "en",
  "options": {},
  "prompt": "Create a friendly two-host episode about simple habits for a calmer workweek.",
  "script": {
    "chapters": [
      {
        "segments": [
          {
            "host_id": "2e6939fe",
            "text": "Welcome to the show. Today we are talking about one small habit that can make the week easier."
          },
          {
            "host_id": "a91c4d22",
            "text": "I like that. Let us start with something simple someone can try tomorrow morning."
          }
        ],
        "title": "Opening"
      }
    ]
  },
  "source_ids": [
    "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  ],
  "podcast_id": "4c1cb0f8-818b-4f7a-9ddb-0d1ea990b35a",
  "outputs": [
    "audio"
  ],
  "render": true
}
```

**Responses**

- `202` — Episode queued for generation
- `400` — Validation failed or malformed request.
- `401` — Missing or invalid API key.
- `403` — Authenticated, but this API key does not have access to this resource.
- `404` — Resource not found.
- `415` — Request \`Content-Type\` is not supported for this endpoint.
- `429` — Rate limit exceeded. Wait \`Retry-After\` seconds before retrying; \`RateLimit-Limit\`, \`RateLimit-Remaining\`, and \`RateLimit-Reset\` describe the window.
- `500` — Internal server error.
- `502` — The API could not enqueue the downstream asynchronous workflow.

Response example, 202:

```json
{
  "data": {
    "created_at": "string",
    "host_ids": [
      "string"
    ],
    "id": "string",
    "podcast_id": "string",
    "status": "generating",
    "updated_at": "string",
    "workflow_run_id": "string"
  }
}
```
