Quickstart
Every public API endpoint goes through the tools registry — one consistent URL pattern that every tool follows:
POST /api/v1/tools/{tool-name}/executeAuthorization: Bearer pk_live_...Content-Type: application/json
{ ...tool input }This is the same surface the MCP server uses, so anything you build with the API translates directly to MCP and vice versa. Browse the full tool list in the live Swagger UI.
-
Get an API key
Open app.playcut.ai/settings/api → Create API key. Copy the key — it’s shown once only.
Terminal window export PLAYCUT_API_KEY="pk_live_..." -
Create a session
Sessions group related generations together. Every generation tool needs a
workerId.Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/create-session/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"title": "My first API session"}'{"data": { "sessionId": "65f3a1b2c3d4e5f600000001", "title": "My first API session" }} -
Submit a generation task
Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/generate-image-from-text/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"workerId": "65f3a1b2c3d4e5f600000001","prompt": "A golden retriever surfing at sunset, photorealistic","aspectRatio": "16:9","imageSize": "1K"}'Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/generate-video-from-text/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"workerId": "65f3a1b2c3d4e5f600000001","prompt": "A golden retriever surfing at sunset, cinematic slow motion","aspectRatio": "16:9","resolution": "720p","durationSeconds": 8}'Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/generate-tts/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"text": "Welcome to Playcut. Generated entirely from a single API call.","voiceId": "<voice-id-from-list-voices>"}'Every generation tool returns the same async-task acknowledgement:
{"data": {"taskId": "65f3a1b2c3d4e5f600000002","status": "PENDING","estimatedCredits": 80}} -
Wait for the result
Two options — pick whichever fits your client:
Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/get-task-status/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"taskId": "65f3a1b2c3d4e5f600000002"}'Repeat until
statusisCOMPLETEDorFAILED. Typical latency:- Images: 5–15 seconds
- Videos: 60–120 seconds
- TTS: 3–10 seconds
Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/wait-for-task/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"taskId": "65f3a1b2c3d4e5f600000002"}'Blocks until the task hits a terminal state. Server-side long-poll — no client polling loop needed.
Configure a
webhookUrlwhen creating the API key and Playcut POSTs a signed event to your endpoint on completion. See the Webhooks guide.Completed response:
{"data": {"taskId": "65f3a1b2c3d4e5f600000002","status": "COMPLETED","output": { "assetIds": ["65f3a1b2c3d4e5f600000003"] }}} -
Download the asset
Terminal window curl -X POST https://api.playcut.ai/api/v1/tools/download-asset/execute \-H "Authorization: Bearer $PLAYCUT_API_KEY" \-H "Content-Type: application/json" \-d '{"assetId": "65f3a1b2c3d4e5f600000003"}'Returns a short-lived signed URL you can
curl -L -o file.pngor open in a browser.
Node.js end-to-end
Section titled “Node.js end-to-end”const API_KEY = process.env.PLAYCUT_API_KEY!const BASE = "https://api.playcut.ai/api/v1/tools"
async function tool<T = any>(name: string, input: Record<string, unknown>): Promise<T> { const res = await fetch(`${BASE}/${name}/execute`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify(input), }) if (!res.ok) throw new Error(`${name} failed: ${res.status} ${await res.text()}`) const json = await res.json() return json.data}
// 1. Create sessionconst { sessionId } = await tool<{ sessionId: string }>("create-session", { title: "API session",})
// 2. Submit taskconst { taskId } = await tool<{ taskId: string }>("generate-image-from-text", { workerId: sessionId, prompt: "A cat in space, photorealistic", aspectRatio: "1:1",})
// 3. Block until done (server-side long-poll)const result = await tool<{ status: string; output?: { assetIds: string[] } }>( "wait-for-task", { taskId },)
// 4. Get a signed download URLconst { url } = await tool<{ url: string }>("download-asset", { assetId: result.output!.assetIds[0],})
console.log("Result:", url)Next steps
Section titled “Next steps”- Authentication — how API keys work
- MCP Install — use Playcut from Claude Desktop / Claude Code
- Webhooks — get notified when tasks finish instead of polling
- API Reference — full tool list + Swagger