New: 13 caption styles
Jellypod Docs

API Reference

Programmatic access to the Jellypod platform.

The Jellypod API creates and manages hosts, sources, podcast episodes, videos, shorts, and voiceovers. A host in the API is a saved Character in Studio. Start with the Video, short, and Voiceover guide for creation, file uploads, progress, retries, and downloads.

Connect

API requests require the Creator plan or higher. Create an organization API key in Developers. The API Keys tab is visible to admins and to members with permission to manage keys. Send requests to https://api.jellypod.com/v1 with this header:

Authorization: Bearer YOUR_API_KEY

Credits and usage

The API uses the same product credit rates and plan limits as Studio. Generation costs depend on the product and its settings. Check GET /account for your plan and available balance. Podcast rendering and publishing are free; status checks and downloads do not start new generation. See Understanding Credits for details.

Podcast generation and retries

For POST /episodes/generate, send an optional Idempotency-Key header. Reuse the key only with the same request. For 24 hours, Jellypod then returns the original episode and workflow IDs without starting another generation. Reusing the key with different input returns 409. Without a key, every request starts a generation.

If acceptance is uncertain, check the episode ID in the error before creating another episode. Video, short, and voiceover create and retry endpoints accept the same optional key.

Rendering

POST /episodes/generate and POST /episodes/import render audio and video as soon as generation completes, so a finished episode is ready to publish or download. Send "render": false to skip that step and leave a draft instead. The draft costs the same generation credits, and you can review, edit, and render it in the studio before publishing. POST /episodes/{episode_id}/publish needs a completed render. While generation or rendering is still running, it returns a 422 with type: "unprocessable_entity" and recovery.poll_after_seconds; poll GET /episodes/{episode_id} and retry publish once it completes. A draft that was never rendered also returns a plain unprocessable_entity, without recovery.poll_after_seconds; render it in Studio first.

Import script text

POST /episodes/import accepts script or transcript text. It maps bracketed speaker labels to hosts that already exist in your organization, or assigns Host IDs to labels explicitly with speaker_characters, and queues a new episode. A label matching no host, with no explicit assignment, is refused, rather than creating a Host for it: a 422 with reason: "unresolved_speakers" and a speakers array naming the unmatched labels. Create any host you plan to name first, with POST /hosts or in Studio, then use its exact name as the label or its ID in speaker_characters.

{
  "podcast_id": "podcast_id",
  "script": "[Host One]\nWelcome to the show. Today we're talking about how small daily habits can make a big difference.\n\n[Host Two]\nI love that topic. Let's start with the easiest habit someone can try this week."
}

Imported text can contain up to 75,000 characters. Content rejected by the speech provider also returns 422 and creates nothing. The episode renders by default. Set render: false to leave it unrendered. Poll GET /episodes/{episode_id} for progress and download URLs.

An unknown podcast_id, a speaker label matching no existing host, or text with no usable segments also return an error and create nothing. Sent with an Idempotency-Key, these input errors are rejected immediately, so fix the input and retry with the same key when recovery.idempotency_key is reuse. If cleanup failed or the rejection was stored under the older policy, recovery instead specifies new.

Generate from a prompt

Send prompt to POST /episodes/generate. You can include a duration in the prompt. Without one, the target is about 7 minutes.

You can also set the duration directly in options instead of relying on the prompt:

{
  "podcast_id": "podcast_id",
  "prompt": "An episode about the history of beekeeping.",
  "options": {
    "episode_length_minutes": 15
  }
}

episode_length_minutes accepts an integer from 1 to 75. It takes precedence over episode_length, which accepts extra_short, short, medium, long, or extra_long.

Generate from a script

Send a structured script to POST /episodes/generate to use your own chapters and segments.

Use GET /hosts to fetch the host_id values available to your organization. Every segment must reference one of those hosts. Imported script text is capped at 75,000 total characters across all segments.

{
  "podcast_id": "podcast_id",
  "script": {
    "chapters": [
      {
        "title": "Introduction",
        "segments": [
          {
            "host_id": "host_id_1",
            "text": "Welcome to the show. Today we're talking about how small daily habits can make a big difference."
          },
          {
            "host_id": "host_id_2",
            "text": "I love that topic. Let's start with the easiest habit someone can try this week."
          }
        ]
      }
    ]
  }
}

Rules for script generation:

  • Send either prompt or script, not both.
  • source_ids are only supported for prompt-based generation.
  • Script mode does not use web_search, episode_length, or episode_length_minutes.
  • Scripts can include up to 50 chapters, 200 segments per chapter, and 600 segments total. Each segment can contain up to 5,000 characters.
  • Long scripts require enough available credits before generation starts. The final charge is based on the narration audio generated, whether or not the episode is rendered.
  • Script generation creates a new episode.

Was this page helpful?