Tools API
Generate AI outputs like podcasts from text or PDFs.
Generate Podcast (API Key)
POST
/api/tools/podcastGenerate a podcast with full audio + transcript timing output.
Authentication: Authorization: Bearer wk_live_xxx... or X-API-Key with tools:write scope.
Request Body / Multipart Fields
| Parameter | Type | Description |
|---|---|---|
text | string | Source text to convert into a podcast (alternative to pdf/pdfBase64). |
pdf | file | Multipart PDF file upload (alternative to text/pdfBase64). |
pdfBase64 | string | Raw base64 or data URL encoded PDF (alternative to text/pdf). |
pdfUploadKey | string | Uploaded PDF key (from /api/podcast/upload-url), alternative to text/pdf/pdfBase64. |
title | string | Optional episode title. |
style | "tea" | "bro" | "intellectual" | Podcast style. Legacy alias true-crime maps to tea. Default: tea |
tone | "casual" | "formal" | Delivery tone. Default: style-dependent |
length | "extra_short" | "short" | "medium" | "long" | Target runtime profile. Default: medium |
deep | boolean | Deep mode for fuller source coverage and context carryover. Default: false |
segmentCount | number | Optional segment target. Standard mode is clamped to 4..24. |
hostCount | number | Number of hosts to use (1..4). Default: 2 |
hostVoiceIds | string[] | Ordered host voice IDs [host, cohost, host3, host4]. Supports preset and caller-owned cloned voice IDs. |
hostVoiceId | string | Legacy primary host voice override (backward-compatible). |
cohostVoiceId | string | Legacy cohost voice override (backward-compatible). |
extraPrompt | string | Additional host interaction/style instructions (max 2000 chars). |
includeSegmentAudio | boolean | Include base64 WAV for each segment in response. Default: false |
JSON request
curl -X POST "https://api.webkasa.app/api/tools/podcast" \
-H "Authorization: Bearer wk_live_xxx..." \
-H "Content-Type: application/json" \
-d '{
"text": "Lecture transcript text...",
"style": "tea",
"tone": "casual",
"length": "long",
"hostCount": 4,
"hostVoiceIds": ["alloy", "echo", "fable", "onyx"],
"extraPrompt": "Use playful transitions and recap key points."
}'Multipart PDF request
curl -X POST "https://api.webkasa.app/api/tools/podcast" \
-H "X-API-Key: wk_live_xxx..." \
-F "pdf=@/absolute/path/lecture.pdf" \
-F "style=tea" \
-F "tone=casual" \
-F "length=medium"Response
200 OK
{
"data": {
"title": "Episode title",
"description": "Episode summary",
"scriptText": "Full script text...",
"voices": {
"host": "alloy",
"cohost": "echo",
"host3": "fable",
"host4": "onyx",
"all": ["alloy", "echo", "fable", "onyx"]
},
"segments": [
{
"index": 0,
"speaker": "host",
"voiceId": "alloy",
"text": "Opening segment text...",
"wordTimings": [],
"startTime": 0,
"endTime": 8.7
}
],
"wordTimings": [],
"audio": {
"format": "wav",
"sampleRate": 24000,
"base64": "UklGR...",
"durationSeconds": 604.1
}
}
}400 INVALID_INPUT
{
"error": "Invalid voice ID: clone_other_tenant",
"code": "INVALID_INPUT"
}Prepare Large PDF Upload
POST
/api/podcast/upload-urlCreate a presigned upload URL for direct PDF upload to storage.
Use this first for larger PDFs, then call /api/podcast/generate with pdfUploadKey.
Request Body
| Parameter | Type | Description |
|---|---|---|
filename required | string | Original PDF filename (must end with .pdf). |
size required | number | File size in bytes (max 15MB). |
contentType | string | PDF MIME type (application/pdf). |
Request
curl -X POST "https://app.webkasa.app/api/podcast/upload-url" \
-H "Content-Type: application/json" \
-d '{
"filename": "lecture.pdf",
"size": 8132642,
"contentType": "application/pdf"
}'Response
200 OK
{
"data": {
"uploadUrl": "https://...signed-put-url...",
"key": "podcast-uploads/1713800000000-uuid-lecture.pdf",
"maxBytes": 15728640,
"expiresInSeconds": 900
}
}Public Generation Flow
POST
/api/podcast/generatePublic generation endpoint used by the /podcast landing flow.
This endpoint returns a lightweight result reference for dashboard retrieval.
Request Inputs
| Parameter | Type | Description |
|---|---|---|
text / pdf / pdfBase64 / pdfUploadKey required | mixed | Provide one source input. Same payload model as /api/tools/podcast for generation controls. |
style, tone, length, deep, hostCount, hostVoiceIds, extraPrompt | mixed | Same generation controls accepted by /api/tools/podcast. |
Request
curl -X POST "https://app.webkasa.app/api/podcast/generate" \
-F "pdfUploadKey=podcast-uploads/1713800000000-uuid-lecture.pdf" \
-F "style=tea" \
-F "tone=casual" \
-F "length=medium"Response
200 OK
{
"data": {
"resultId": "40b6698b-4b10-45e7-88f6-8f927d081ca2",
"title": "Episode title",
"description": "Episode summary",
"durationSeconds": 603.2,
"segments": 20
}
}Fetch Generated Result
GET
/api/podcast/results/{resultId}Fetch a stored generated result by ID for authenticated dashboard users.
Authentication: session cookie (dashboard user). Not API-key based.
Request
curl -X GET "https://app.webkasa.app/api/podcast/results/40b6698b-4b10-45e7-88f6-8f927d081ca2" \
-H "Cookie: sb-access-token=...;"Response
200 OK
{
"data": {
"resultId": "40b6698b-4b10-45e7-88f6-8f927d081ca2",
"createdAt": "2026-04-22T15:35:12.003Z",
"result": {
"title": "Episode title",
"audio": {
"format": "wav",
"durationSeconds": 603.2
}
}
}
}404 Not Found
{
"error": "Result not found or expired"
}