{"openapi":"3.1.0","info":{"title":"Brainrot Shorts REST API","version":"1.0.0","description":"Create and render short-form videos (AI brainrot, Reddit stories, AI voice-overs) programmatically.\n\nAuthenticate with an API key in the `X-API-Key` header (create one in the dashboard; REST access is included in Creator and Pro plans).\nSend an `Idempotency-Key` header on POST requests so retries never double-create projects or renders.\n\nRate-limit and tracing headers on every response: X-Request-Id, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Window, X-API-Tier, X-Idempotent-Replay, Retry-After.\n\nHuman-readable documentation: https://www.brainrotshorts.com/api-docs"},"servers":[{"url":"https://www.brainrotshorts.com/api/v1"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Discovery"},{"name":"Account & catalog","description":"Read your account context and the catalogs of voices, backgrounds, and caption styles you can reference by ID."},{"name":"Projects & renders","description":"Shared lifecycle endpoints. Only brainrot, reddit-story, and ai-voice-over-video projects are visible over the REST API."},{"name":"AI Brainrot","description":"Gameplay-background dialogue videos with AI voiceover and word-by-word captions."},{"name":"Reddit Videos","description":"Narrated Reddit story videos from a Reddit URL, a raw prompt, or an explicit script/blocks payload."},{"name":"AI Voice Over","description":"Scenes of text narrated over any background video, with tunable captions and playback."}],"paths":{"/":{"get":{"operationId":"get-api-index","tags":["Discovery"],"summary":"Public API index: version, docs, OpenAPI, auth instructions, and endpoint list. No API key required.","security":[],"responses":{"200":{"description":"The API index."}}}},"/openapi.json":{"get":{"operationId":"get-openapi-document","tags":["Discovery"],"summary":"This OpenAPI 3.1 document (also served at the site root as /openapi.json). No API key required.","security":[],"responses":{"200":{"description":"The OpenAPI document."}}}},"/me":{"get":{"operationId":"get-me","tags":["Account & catalog"],"summary":"Get the authenticated account.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/catalog/characters":{"get":{"operationId":"catalog-characters","tags":["Account & catalog"],"summary":"List the characters and voices available to your plan.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/catalog/backgrounds":{"get":{"operationId":"catalog-backgrounds","tags":["Account & catalog"],"summary":"List gameplay/background videos you can attach by ID.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/catalog/caption-styles":{"get":{"operationId":"catalog-caption-styles","tags":["Account & catalog"],"summary":"List the built-in caption style presets.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/projects":{"get":{"operationId":"list-projects","tags":["Projects & renders"],"summary":"List your API-visible projects with their latest render.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/projects/{projectId}":{"get":{"operationId":"get-project","tags":["Projects & renders"],"summary":"Get a single project by ID.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}]},"delete":{"operationId":"delete-project","tags":["Projects & renders"],"summary":"Delete a project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}]}},"/projects/{projectId}/render":{"post":{"operationId":"start-render","tags":["Projects & renders"],"summary":"Approve and start a render.","description":"Renders consume credits. Send an Idempotency-Key so retries don't start duplicate renders.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"approved":{"type":"boolean","description":"Must be true to start the render. Defaults to false."}},"additionalProperties":true}}}}},"get":{"operationId":"get-render","tags":["Projects & renders"],"summary":"Get the latest render status for a project (poll this).","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}]}},"/renders/{renderId}":{"get":{"operationId":"get-render-by-id","tags":["Projects & renders"],"summary":"Get a specific render by its ID.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"renderId","in":"path","required":true,"description":"The render ID.","schema":{"type":"string"}}]}},"/projects/{projectId}/output":{"get":{"operationId":"get-project-output","tags":["Projects & renders"],"summary":"Get the latest finished output URL for a project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}]}},"/audio/jobs/{jobId}":{"get":{"operationId":"get-audio-job","tags":["Projects & renders"],"summary":"Get the status of a narration audio generation job.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"jobId","in":"path","required":true,"description":"The audio job ID returned by a scene audio call.","schema":{"type":"string"}}]}},"/brainrot/projects":{"post":{"operationId":"brainrot-create","tags":["AI Brainrot"],"summary":"Create a brainrot project.","description":"Provide simple settings to start a draft, or pass a full promptJson scene config to create a ready-to-render project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Project title (max 120 chars)."},"backgroundVideoId":{"type":"string","description":"ID from GET /catalog/backgrounds."},"characterId":{"type":"string","description":"ID from GET /catalog/characters."},"captionStyle":{"type":"object","description":"Caption styling object. List valid presets via GET /catalog/caption-styles."},"captionGrouping":{"type":"object","description":"Controls how words are grouped into caption chunks."},"promptJson":{"type":"object","description":"Full project config (backgroundColor, scenes[]). When present, creates a complete project."}},"additionalProperties":true}}}}}},"/brainrot/projects/{projectId}":{"patch":{"operationId":"brainrot-update","tags":["AI Brainrot"],"summary":"Update a brainrot project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"New title (max 120 chars)."},"captionStyle":{"type":"object","description":"Caption styling object. List valid presets via GET /catalog/caption-styles."},"captionGrouping":{"type":"object","description":"Controls how words are grouped into caption chunks."},"backgroundColor":{"type":"string","description":"Background color for the project."},"watermarkEnabled":{"type":"boolean","description":"Toggle the watermark."},"promptJson":{"type":"object","description":"Replace the full scene config."}},"additionalProperties":true}}}}}},"/brainrot/projects/{projectId}/scenes/{sceneId}":{"patch":{"operationId":"brainrot-scene-update","tags":["AI Brainrot"],"summary":"Update a single scene.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"sceneId","in":"path","required":true,"description":"The scene ID.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"characterId":{"type":"string","description":"Character for the scene."},"backgroundVideoId":{"type":"string","description":"Background by catalog ID."},"backgroundVideoUrl":{"type":"string","description":"Background by direct URL."},"characterEntranceEnabled":{"type":"boolean","description":"Toggle the character entrance animation."},"characterEntrancePreset":{"type":"string","description":"Entrance animation preset."},"characterEntranceSoundEnabled":{"type":"boolean","description":"Toggle the entrance sound."},"characterPosition":{"type":"object","description":"Character position."},"characterScale":{"type":"number","description":"Character scale (> 0)."},"captionPositionY":{"type":"number","description":"Vertical caption position, 0–1."},"voiceEnabled":{"type":"boolean","description":"Toggle voiceover for the scene."}},"additionalProperties":true}}}}}},"/brainrot/scripts/ideas":{"post":{"operationId":"brainrot-ideas","tags":["AI Brainrot"],"summary":"Generate script ideas for a niche.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"niche":{"type":"string","description":"The niche to ideate around (max 200 chars)."}},"required":["niche"],"additionalProperties":true}}}}}},"/brainrot/projects/{projectId}/scripts/generate":{"post":{"operationId":"brainrot-script-generate","tags":["AI Brainrot"],"summary":"Generate a full script for a project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"niche":{"type":"string","description":"Niche (max 200 chars)."},"idea":{"type":"string","description":"The specific idea to script (max 500 chars)."},"characters":{"type":"array","items":{},"description":"1–4 characters to cast in the dialogue."}},"required":["niche","idea"],"additionalProperties":true}}}}}},"/brainrot/projects/{projectId}/scripts/apply":{"post":{"operationId":"brainrot-script-apply","tags":["AI Brainrot"],"summary":"Apply a script to a project as scenes.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Optional title (max 120 chars)."},"script":{"type":"array","items":{},"description":"1–40 script lines to turn into scenes."}},"required":["script"],"additionalProperties":true}}}}}},"/brainrot/projects/{projectId}/scenes/{sceneId}/audio":{"post":{"operationId":"brainrot-scene-audio","tags":["AI Brainrot"],"summary":"Generate narration audio for a scene.","description":"Consumes credits. Returns an audio job — poll GET /audio/jobs/{jobId}.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"sceneId","in":"path","required":true,"description":"The scene ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}]}},"/reddit/posts/fetch":{"post":{"operationId":"reddit-fetch","tags":["Reddit Videos"],"summary":"Fetch a Reddit post for use in a story video.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"A valid Reddit post URL."}},"required":["url"],"additionalProperties":true}}}}}},"/reddit/scripts/generate":{"post":{"operationId":"reddit-script-generate","tags":["Reddit Videos"],"summary":"Generate a Reddit story script from a description.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","description":"What the story is about (max 2000 chars)."},"style":{"type":"string","description":"Optional style hint (max 100 chars)."},"durationSeconds":{"type":"number","description":"Target length 10–120. Defaults to 90."}},"required":["description"],"additionalProperties":true}}}}}},"/reddit/posts/repurpose":{"post":{"operationId":"reddit-repurpose","tags":["Reddit Videos"],"summary":"Repurpose an existing Reddit post into a script.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"originalPost":{"type":"object","description":"{ subreddit, username, title, selftext, upvotes, comments }."},"mode":{"type":"string","enum":["repurpose","longer"],"description":"Repurpose verbatim-ish or expand into a longer story."},"durationSeconds":{"type":"number","description":"Target length 10–120. Defaults to 60."}},"required":["originalPost","mode"],"additionalProperties":true}}}}}},"/reddit/projects":{"post":{"operationId":"reddit-create","tags":["Reddit Videos"],"summary":"Create a Reddit story project.","description":"Provide exactly one of script or blocks, plus optional settings.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Project title (max 120 chars)."},"voiceId":{"type":["string","null"],"description":"Narrator voice."},"backgroundVideoUrl":{"type":["string","null"],"description":"Background by URL."},"backgroundVideoId":{"type":"string","description":"Background by catalog ID."},"captionStyle":{"type":"object","description":"Caption styling object. List valid presets via GET /catalog/caption-styles."},"captionGrouping":{"type":"object","description":"Controls how words are grouped into caption chunks."},"backgroundMusic":{"type":["object","null"],"description":"Background music config."},"playbackRate":{"type":"number","description":"Speed 1–2."},"watermarkEnabled":{"type":"boolean","description":"Toggle watermark."},"captionPositionY":{"type":"number","description":"Caption position, 0–1."},"script":{"type":"object","description":"A generated Reddit script object (mutually exclusive with blocks)."},"blocks":{"type":"array","items":{},"description":"Explicit story blocks (mutually exclusive with script)."}},"additionalProperties":true}}}}}},"/reddit/projects/{projectId}":{"patch":{"operationId":"reddit-update","tags":["Reddit Videos"],"summary":"Update a Reddit story project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":true}}}}}},"/reddit/videos/from-prompt":{"post":{"operationId":"reddit-from-prompt","tags":["Reddit Videos"],"summary":"Create a Reddit video from a text prompt in one call.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","description":"What the story is about (max 2000 chars)."},"style":{"type":"string","description":"Optional style hint."},"durationSeconds":{"type":"number","description":"Target length 10–120. Defaults to 90."},"approved":{"type":"boolean","description":"Start a render immediately. Defaults to false."}},"required":["description"],"additionalProperties":true}}}}}},"/reddit/videos/from-url":{"post":{"operationId":"reddit-from-url","tags":["Reddit Videos"],"summary":"Create a Reddit video from a Reddit URL in one call.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"A valid Reddit post URL."},"originalPost":{"type":"object","description":"Optional pre-fetched post payload."},"mode":{"type":"string","enum":["repurpose","longer"],"description":"Defaults to repurpose."},"durationSeconds":{"type":"number","description":"Target length 10–120. Defaults to 60."},"approved":{"type":"boolean","description":"Start a render immediately. Defaults to false."}},"required":["url"],"additionalProperties":true}}}}}},"/reddit/projects/{projectId}/blocks/{blockId}/audio":{"post":{"operationId":"reddit-block-audio","tags":["Reddit Videos"],"summary":"Generate narration audio for a Reddit block.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"blockId","in":"path","required":true,"description":"The block ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}]}},"/voiceover/scripts/generate":{"post":{"operationId":"voiceover-script-generate","tags":["AI Voice Over"],"summary":"Generate a voice-over script from a description.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string","description":"What the video is about (max 2000 chars)."},"style":{"type":"string","description":"Optional style hint (max 100 chars)."},"durationSeconds":{"type":"number","description":"Target length 10–120. Defaults to 60."}},"required":["description"],"additionalProperties":true}}}}}},"/voiceover/projects":{"post":{"operationId":"voiceover-create","tags":["AI Voice Over"],"summary":"Create an AI voice-over project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Project title (max 120 chars)."},"voiceId":{"type":["string","null"],"description":"Narrator voice ID."},"backgroundVideoUrl":{"type":["string","null"],"description":"Background video URL."},"captionStyle":{"type":"object","description":"Caption styling object. List valid presets via GET /catalog/caption-styles."},"captionGrouping":{"type":"object","description":"Controls how words are grouped into caption chunks."},"captionPositionY":{"type":"number","description":"Caption position, 0–1."},"backgroundMusic":{"type":"object","description":"Background music config."},"playbackRate":{"type":"number","description":"Speed 1–2."},"watermarkEnabled":{"type":"boolean","description":"Toggle watermark."},"scenes":{"type":"array","items":{},"description":"≥1 scene: { text (required), id?, narrationAudioUrl?, generatedCaptions?, durationInSeconds? }."}},"required":["scenes"],"additionalProperties":true}}}}}},"/voiceover/projects/{projectId}":{"patch":{"operationId":"voiceover-update","tags":["AI Voice Over"],"summary":"Update an AI voice-over project.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":true}}}}}},"/voiceover/projects/{projectId}/scenes/{sceneId}/audio":{"post":{"operationId":"voiceover-scene-audio","tags":["AI Voice Over"],"summary":"Generate narration audio for a voice-over scene.","responses":{"200":{"description":"Success. The payload is wrapped in an envelope with the request ID.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"default":{"description":"Error. Documented codes: MISSING_API_KEY (401), INVALID_API_KEY (401), FORBIDDEN (403), INSUFFICIENT_CREDITS (402), VALIDATION_ERROR (400), UNSUPPORTED_VIDEO_TYPE (400), NOT_FOUND (404), RATE_LIMITED (429), IDEMPOTENCY_CONFLICT (409), IDEMPOTENCY_IN_PROGRESS (409), INTERNAL_ERROR (500).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"name":"projectId","in":"path","required":true,"description":"The project ID.","schema":{"type":"string"}},{"name":"sceneId","in":"path","required":true,"description":"The scene ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Any stable string of your choosing. Retrying a POST with the same key and body replays the stored response instead of creating duplicate projects or renders.","schema":{"type":"string"}}]}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"SuccessEnvelope":{"type":"object","properties":{"data":{"description":"The endpoint-specific payload."},"requestId":{"type":"string"}},"required":["data","requestId"]},"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Documented codes: MISSING_API_KEY, INVALID_API_KEY, FORBIDDEN, INSUFFICIENT_CREDITS, VALIDATION_ERROR, UNSUPPORTED_VIDEO_TYPE, NOT_FOUND, RATE_LIMITED, IDEMPOTENCY_CONFLICT, IDEMPOTENCY_IN_PROGRESS, INTERNAL_ERROR. Unexpected upstream errors may surface other codes."},"message":{"type":"string"},"details":{"description":"Machine-readable context for the error: an array of validation issues for VALIDATION_ERROR, an object elsewhere."}},"required":["code","message"]},"requestId":{"type":"string"}},"required":["error","requestId"]}}}}