The API base URL is https://app.turbocast.io/api/v1. Requests use JSON, except the direct PUT to the upload URL and artwork file uploads, which use multipart/form-data. Every ID in the API is a short string (a hashid), such as r2xupj.
1. Create a token
Sign in and create an API token at API tokens. Copy it when it appears: the app shows a newly created token only once. The token can publish to podcasts in accounts where its owner is an admin.
export TURBOCAST_TOKEN="paste-your-token-here"
export TURBOCAST_API="https://app.turbocast.io/api/v1"
Keep the token on your server or in your automation tool’s secret store. Do not put it in client-side JavaScript or a public repository.
2. Find your podcast and channels
curl "$TURBOCAST_API/podcasts" \
-H "Authorization: Bearer $TURBOCAST_TOKEN"
curl "$TURBOCAST_API/podcasts/PODCAST_HASHID/channels" \
-H "Authorization: Bearer $TURBOCAST_TOKEN"
The first response lists podcasts you administer. Use a podcast’s id in the following paths. The channels response lists active channels and their IDs. Legacy podcasts return an empty channel list and publish without a channels field.
3. Request an upload URL and send the audio
curl -X POST "$TURBOCAST_API/podcasts/PODCAST_HASHID/uploads" \
-H "Authorization: Bearer $TURBOCAST_TOKEN" \
-H "Content-Type: application/json" \
-d '{"filename":"episode.mp3","content_type":"audio/mpeg"}'
The response contains upload_url, upload_id, method: "PUT", headers, and expires_in. Send the file to upload_url with the exact headers returned by the API. For example, if headers contains Content-Type: audio/mpeg:
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: audio/mpeg" \
--upload-file episode.mp3
MP3, M4A, AAC, and WAV files are accepted; send the matching content_type. Files that aren’t MP3 are converted to MP3 after you attach them. The upload URL expires after 15 minutes. The signed upload_id can be attached to an episode for 24 hours and works only with the podcast that issued it. See Audio and artwork for URL imports and validation rules.
4. Create a draft and wait for audio
curl -X POST "$TURBOCAST_API/podcasts/PODCAST_HASHID/episodes" \
-H "Authorization: Bearer $TURBOCAST_TOKEN" \
-H "Idempotency-Key: editor-job-123" \
-H "Content-Type: application/json" \
-d '{"episode":{"title":"Field notes","summary":"A new update","audio_upload_id":"SIGNED_UPLOAD_ID"}}'
Create always makes a draft. Save the episode id from the response. Poll until audio.status becomes ready:
curl "$TURBOCAST_API/podcasts/PODCAST_HASHID/episodes/EPISODE_HASHID" \
-H "Authorization: Bearer $TURBOCAST_TOKEN"
processing means the audio is still being prepared or converted. failed includes an audio.error message. Publishing before ready returns audio_not_ready.
5. Schedule a release
curl -X POST "$TURBOCAST_API/podcasts/PODCAST_HASHID/episodes/EPISODE_HASHID/publish" \
-H "Authorization: Bearer $TURBOCAST_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"published_at":"2026-11-01T09:00:00-04:00",
"channels":[
{"id":"OnDt15"},
{"id":"kZr4Pa","timing_mode":"delay","delay_seconds":86400}
]
}'
Replace OnDt15 and kZr4Pa with IDs from your channels response. This complete list includes the first channel at its default time and the second one day after the episode’s publish time. Any active channel not listed is excluded. Omit channels to apply each channel’s normal default. Omit published_at to publish now.
The returned status is scheduled when published_at is in the future. A channel can release later than the episode’s publish time; inspect channels[].released_at to see each channel’s schedule.
Continue with Publishing for exact release times, local time, retiming, and unpublishing.