---
search:
  tags:
    - Episodes
    - POST
seo:
  description: >-
    Generates a new episode from finished script text, asynchronously. Poll its
    status… Reference for the POST /v1/episodes/import endpoint in the Jellypod
    API.
sidebar:
  label: Import a script as a new episode
  badge: POST
title: Import a script as a new episode
type: openapi-operation
---
Generates a new episode from finished script text, asynchronously. Poll its status for progress.

`POST /v1/episodes/import`

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

- `podcast_id` (string<uuid>, required) — Podcast that will own the imported 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.
- `script` (string, required) — Script or transcript text. Bracketed speaker labels match saved Characters unless speaker\_characters explicitly assigns their Character IDs.
- `speaker_characters` (object[]) — Optional explicit assignments for a finished script: label as written in \[brackets\], and character\_id from list\_characters. Assignments override name matching; unmapped labels still match saved Character names.

Request body example:

```json
{
  "podcast_id": "4c1cb0f8-818b-4f7a-9ddb-0d1ea990b35a",
  "outputs": [
    "audio"
  ],
  "render": true,
  "script": "[Host One]\nWelcome to the show. Today we are talking about one small habit that can make the week easier.\n\n[Host Two]\nI like that. Let us start with something simple someone can try tomorrow morning.",
  "speaker_characters": [
    {
      "character_id": "string",
      "label": "string"
    }
  ]
}
```

**Responses**

- `202` — Imported 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.
- `422` — Request was well-formed but the resource is in a state that does not allow this operation (e.g. publishing an episode that has not finished rendering).
- `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"
  }
}
```
