{"basePath":"/v1","definitions":{"ai.AIModelDetail":{"properties":{"action":{"allOf":[{"$ref":"#/definitions/ai_manager_types.ActionName"}],"example":"generate_video"},"description":{"type":"string"},"id":{"allOf":[{"$ref":"#/definitions/ai_manager_types.ModelName"}],"example":"kling-v2.6"},"name":{"example":"Kling 2.6","type":"string"},"params_schema":{"type":"object"},"schema_url":{"example":"/v1/ai/models/kling-v2.6","format":"uri-reference","type":"string"},"tagline":{"example":"Realistic motion, audio included","type":"string"}},"type":"object"},"ai.AIModelSummary":{"properties":{"action":{"allOf":[{"$ref":"#/definitions/ai_manager_types.ActionName"}],"example":"generate_video"},"description":{"type":"string"},"id":{"allOf":[{"$ref":"#/definitions/ai_manager_types.ModelName"}],"example":"kling-v2.6"},"name":{"example":"Kling 2.6","type":"string"},"schema_url":{"example":"/v1/ai/models/kling-v2.6","format":"uri-reference","type":"string"},"tagline":{"example":"Realistic motion, audio included","type":"string"}},"type":"object"},"ai.GenerateMotionGraphicsDTO":{"properties":{"duration":{"maximum":600,"type":"number"},"height":{"maximum":4096,"type":"integer"},"images":{"items":{"$ref":"#/definitions/ai.MotionGraphicsImageInput"},"maxItems":16,"type":"array"},"project_id":{"type":"string"},"prompt":{"maxLength":5000,"type":"string"},"width":{"maximum":4096,"type":"integer"}},"required":["project_id","prompt"],"type":"object"},"ai.MotionGraphicsImageInput":{"properties":{"description":{"type":"string"},"height":{"type":"integer"},"mediaId":{"type":"string"},"width":{"type":"integer"}},"required":["mediaId"],"type":"object"},"ai.SmartCutDTO":{"properties":{"clip_id":{"type":"string"},"end_time":{"minimum":0,"type":"number"},"instruction":{"maxLength":1000,"type":"string"},"join_air_seconds":{"maximum":2,"minimum":0,"type":"number"},"media":{"type":"string"},"min_pause_seconds":{"maximum":10,"minimum":0.1,"type":"number"},"params":{"allOf":[{"$ref":"#/definitions/ai.smartCutParams"}],"description":"Params carries the source in the model-params envelope that every other\naction uses ({\"params\": {\"media\": …}}); either spot satisfies Media."},"project_id":{"type":"string"},"start_time":{"minimum":0,"type":"number"},"workspace_id":{"type":"string"}},"required":["project_id"],"type":"object"},"ai.VoicePreviewResponse":{"properties":{"preview_audio_url":{"type":"string"}},"type":"object"},"ai.aiToolResponseItem":{"properties":{"action":{"type":"string"},"description":{"type":"string"},"models":{"items":{"$ref":"#/definitions/ai_manager_types.ModelInfo"},"type":"array"}},"type":"object"},"ai.smartCutParams":{"properties":{"end_time":{"type":"number"},"instruction":{"type":"string"},"join_air_seconds":{"type":"number"},"media":{"type":"string"},"min_pause_seconds":{"type":"number"},"start_time":{"type":"number"}},"required":["media"],"type":"object"},"ai_manager_feature_text_to_speech.FilterOption":{"properties":{"label":{"type":"string"},"value":{"type":"string"}},"type":"object"},"ai_manager_feature_text_to_speech.FilterOptions":{"properties":{"accents":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.FilterOption"},"type":"array"},"ages":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.FilterOption"},"type":"array"},"genders":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.FilterOption"},"type":"array"},"languages":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.FilterOption"},"type":"array"}},"type":"object"},"ai_manager_feature_text_to_speech.VoiceResult":{"properties":{"accent":{"type":"string"},"age":{"type":"string"},"description":{"type":"string"},"gender":{"type":"string"},"id":{"type":"string"},"language":{"type":"string"},"model_id":{"type":"string"},"name":{"type":"string"},"preview_audio_url":{"type":"string"},"recommended":{"description":"Recommended marks the curated voices, listed before library results.","type":"boolean"},"use":{"type":"string"}},"type":"object"},"ai_manager_feature_video_avatars.VideoAvatar":{"properties":{"avatar_name":{"type":"string"},"gender":{"type":"string"},"id":{"type":"string"},"model_id":{"type":"string"}},"type":"object"},"ai_manager_feature_video_translate.VideoTranslateLanguage":{"properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"ai_manager_types.ActionName":{"enum":["transcribe","generate_image","generate_video","generate_video_avatar","text_to_speech","voice_isolation","remove_video_background","remove_image_background","video_translate","generate_text","voice_changer","generate_music","generate_sound_effect","upscale_image","upscale_video","lipsync","smart_cut"],"type":"string","x-enum-varnames":["ActionTranscribe","ActionGenerateImage","ActionGenerateVideo","ActionGenerateVideoAvatar","ActionTextToSpeech","ActionVoiceIsolation","ActionRemoveVideoBackground","ActionRemoveImageBackground","ActionVideoTranslate","ActionGenerateText","ActionVoiceChanger","ActionGenerateMusic","ActionGenerateSoundEffect","ActionUpscaleImage","ActionUpscaleVideo","ActionLipsync","ActionSmartCut"]},"ai_manager_types.GenerateImageDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.GenerateMusicDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.GenerateSoundEffectDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.GenerateVideoAvatarDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.GenerateVideoDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.LipsyncDTO":{"properties":{"audio_file_url":{"type":"string"},"clip_id":{"type":"string"},"duration":{"type":"number"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"video_file_url":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.ModelInfo":{"properties":{"action":{"$ref":"#/definitions/ai_manager_types.ActionName"},"description":{"description":"Description is written for the agent: capabilities, price class, when to\npick it over siblings. Tagline is the one line a person sees in a picker.","type":"string"},"id":{"$ref":"#/definitions/ai_manager_types.ModelName"},"name":{"type":"string"},"schema":{"type":"object"},"tagline":{"type":"string"},"transparent_background":{"description":"TransparentBackground marks an image model that returns an alpha-channel\nimage when asked (params.background = \"transparent\"). Every other model\nreturns an opaque image whatever the request says.","type":"boolean"}},"type":"object"},"ai_manager_types.ModelName":{"enum":["grok-imagine-image-2","minimax-h3","kling-v3-omni-video","dalle-3","whisper","gpt-4o-mini-tts","veo-3.1","veo-3.1-fast","heygen","nano-banana","nano-banana-pro","gpt-image-2","eleven-labs-tts","eleven-labs-voice-isolation","eleven-labs-voice-changer","eleven-labs-speech-to-text","remove-video-background","remove-image-background","kling-v2.6","kling-v2.6-motion-control","kling-v2.5-turbo-pro","seedance-1.5-pro","seedance-2.0","seedance-2.0-fast","seedance-2.5","grok-imagine-r2v","grok-imagine-video","grok-imagine-video-extension","grok-imagine-video-1.5","p-video","wan-2.7-t2v","wan-2.7-i2v","hailuo-2.3","imagen-4","seedream-4","flux-1.1-pro","lipsync","video-translate","gemini-2.5-flash","lyria-3-pro","eleven-labs-music","eleven-labs-sound-effect","upscale-image","video-upscaler","flux-video-upscale","wan-3-prime","flux-2-pro","eleven-labs-dubbing","seedream-5-lite","wan-3","gemini-omni-1.1","kling-v3-video","gpt-image-2.5-sunburst","gpt-image-2.5-flare","flux-2-flex","ltx-2.5-fast","pixverse-v6","qwen-image-3-pro","flux-2-max","qwen-image-3","z-image-turbo","flux-3","omni-human-1.5","seedream-4.5","seedance-2.0-mini","seedream-5-pro"],"type":"string","x-enum-varnames":["GrokImagineImage2Model","MinimaxH3Model","KlingV3OmniVideoModel","Dalle3Model","WhisperModel","GPT4OMiniTTSModel","Veo31Model","Veo31FastModel","HeygenVideoAvatarModel","NanoBananaModel","NanoBananaProModel","GPTImage2Model","ElevenLabsTTSModel","ElevenLabsVoiceIsolationModel","ElevenLabsVoiceChangerModel","ElevenLabsSpeechToTextModel","RemoveVideoBackgroundModel","RemoveImageBackgroundModel","KlingV26Model","KlingV26MotionControlModel","KlingV25TurboProModel","Seedance15ProModel","Seedance20Model","Seedance20FastModel","Seedance25Model","GrokImagineR2VModel","GrokImagineVideoModel","GrokImagineVideoExtensionModel","GrokImagineVideo15Model","PVideoModel","Wan27T2VModel","Wan27I2VModel","Hailuo23Model","Imagen4Model","Seedream4Model","Flux11ProModel","LipsyncModel","VideoTranslateModel","Gemini25FlashModel","Lyria3ProModel","ElevenLabsMusicModel","ElevenLabsSoundEffectModel","UpscaleImageModel","VideoUpscalerModel","FluxVideoUpscaleModel","Wan3PrimeModel","Flux2ProModel","ElevenLabsDubbingModel","Seedream5LiteModel","Wan3Model","GeminiOmni11Model","KlingV3VideoModel","GPTImage25SunburstModel","GPTImage25FlareModel","Flux2FlexModel","LTX25FastModel","PixverseV6Model","QwenImage3ProModel","Flux2MaxModel","QwenImage3Model","ZImageTurboModel","Flux3Model","OmniHuman15Model","Seedream45Model","Seedance20MiniModel","Seedream5ProModel"]},"ai_manager_types.RemoveImageBackgroundDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.RemoveVideoBackgroundDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.TextToSpeechDTO":{"properties":{"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.TranscribeDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.UpscaleImageDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.UpscaleVideoDTO":{"properties":{"clip_id":{"type":"string"},"duration":{"type":"number"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.VideoTranslateDTO":{"properties":{"clip_id":{"type":"string"},"duration":{"type":"number"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.VoiceChangerDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"ai_manager_types.VoiceIsolationDTO":{"properties":{"clip_id":{"type":"string"},"file_url":{"type":"string"},"model_id":{"type":"string"},"params":{"description":"Params is model-specific: its accepted fields are defined by the model in\nmodel_id, not by this endpoint. Fetch the JSON Schema for a model from\nGET /v1/ai/models/{model_id} — it is generated from the runtime validator\nand is the source of truth. GET /v1/ai/models lists the model ids.","type":"object"},"project_id":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"brandkit.BrandkitImportDTO":{"properties":{"website_url":{"type":"string"}},"required":["website_url"],"type":"object"},"export.ExportCostResponse":{"properties":{"credits":{"type":"integer"}},"type":"object"},"http_response.APIError":{"properties":{"code":{"type":"string"},"fields":{"items":{"$ref":"#/definitions/http_response.FieldError"},"type":"array"},"message":{"type":"string"}},"type":"object"},"http_response.FieldError":{"properties":{"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"http_response.Response":{"properties":{"data":{"description":"Success data"},"error":{"allOf":[{"$ref":"#/definitions/http_response.APIError"}],"description":"Error information"},"meta":{"description":"Meta data"}},"type":"object"},"project.UpdateProjectDTO":{"properties":{"adopt_file_hashes":{"description":"AdoptFileHashes lists role=pending uploads to retag role=library in the\nsame request, AFTER the project JSON is saved — the atomic \"save project\n+ adopt pending uploads\" step of the library injection flow. Adoption is\nskipped when the save itself fails.","items":{"type":"string"},"maxItems":500,"type":"array"},"agent_prompt":{"description":"AgentPrompt updates the stored handoff prompt out of band from the\nversion-guarded document save: \"\" clears it (on send), non-empty sets it,\nnil leaves it untouched.","maxLength":100000,"type":"string"},"agent_skill":{"description":"AgentSkill is the handoff prompt's pinned workflow skill, with the same\nset/clear/untouched semantics as AgentPrompt.","maxLength":64,"type":"string"},"fit_duration":{"type":"number"},"name":{"type":"string"},"project_json":{"type":"string"},"template":{"allOf":[{"$ref":"#/definitions/types.TemplateDefinition"}],"description":"Template replaces the promoted fields, outside the version guard."},"template_mode":{"description":"TemplateMode turns the fields form on or off.","type":"boolean"},"version":{"type":"integer"}},"type":"object"},"social.CreatePostDTO":{"properties":{"account_ids":{"description":"Ids from GET /social/accounts.","items":{"type":"string"},"maxItems":20,"minItems":1,"type":"array","uniqueItems":true},"caption":{"description":"Checked against each target platform's limit, e.g. 280 characters on X.","maxLength":5000,"type":"string"},"captions":{"additionalProperties":{"type":"string"},"description":"Per-platform caption keyed by platform, e.g. {\"x\": \"...\"}; overrides caption for that platform.","type":"object"},"media_url":{"description":"Public HTTPS link to an mp4/mov video or a jpeg/png/webp/gif image, e.g. an export URL.","maxLength":4096,"type":"string"},"platform_options":{"allOf":[{"$ref":"#/definitions/social.PlatformOptions"}],"description":"Settings only some platforms use."},"project_id":{"description":"The Rendley project the video comes from, shown with the post in the app.","type":"string"},"scheduled_at":{"description":"RFC 3339 time to publish at; omit to publish now.","type":"string"},"thumbnail_url":{"description":"Preview image the app shows with the post; not sent to the platforms.","maxLength":2048,"type":"string"},"workspace_id":{"type":"string"}},"required":["account_ids","media_url","workspace_id"],"type":"object"},"social.InstagramOptions":{"properties":{"placement":{"description":"reels (default), timeline (feed) or stories.","enum":["reels","timeline","stories"],"type":"string"},"share_to_feed":{"description":"A reel also shows in the feed, not only in the Reels tab.","type":"boolean"}},"type":"object"},"social.PlatformOptions":{"properties":{"instagram":{"$ref":"#/definitions/social.InstagramOptions"},"tiktok":{"$ref":"#/definitions/social.TiktokOptions"},"youtube":{"allOf":[{"$ref":"#/definitions/social.YoutubeOptions"}],"description":"Used for YouTube accounts; the caption becomes the video description."}},"type":"object"},"social.PostMetrics":{"properties":{"comments":{"type":"integer"},"likes":{"type":"integer"},"saves":{"type":"integer"},"shares":{"type":"integer"},"views":{"type":"integer"}},"type":"object"},"social.SocialAccountResponse":{"properties":{"id":{"type":"string"},"photo_url":{"type":"string"},"platform":{"type":"string"},"reconnect_required":{"description":"The platform rejected the login; posts fail until the account is reconnected.","type":"boolean"},"token_expires_at":{"description":"When the platform login stops working; reconnect before then.","type":"string"},"username":{"type":"string"}},"type":"object"},"social.SocialPostResponse":{"properties":{"account_username":{"type":"string"},"caption":{"type":"string"},"created_at":{"type":"string"},"error":{"type":"string"},"error_code":{"description":"account_expired, media_rejected or rate_limited when the failure is a known kind.","type":"string"},"id":{"type":"string"},"metrics":{"allOf":[{"$ref":"#/definitions/social.PostMetrics"}],"description":"Latest numbers from the platform, once published (plans with analytics)."},"platform":{"type":"string"},"platform_options":{"$ref":"#/definitions/social.PlatformOptions"},"project_id":{"type":"string"},"result":{"type":"object"},"scheduled_at":{"type":"string"},"status":{"type":"string"},"thumbnail_url":{"type":"string"}},"type":"object"},"social.TiktokOptions":{"properties":{"allow_comment":{"type":"boolean"},"allow_duet":{"type":"boolean"},"allow_stitch":{"type":"boolean"},"is_ai_generated":{"type":"boolean"},"privacy_status":{"description":"public (default) or private.","enum":["public","private"],"type":"string"}},"type":"object"},"social.UpdatePostDTO":{"properties":{"caption":{"description":"New caption; omit to keep the current one.","maxLength":5000,"type":"string"},"platform_options":{"allOf":[{"$ref":"#/definitions/social.PlatformOptions"}],"description":"Replaces the post's platform settings; omit to keep the current ones."},"scheduled_at":{"description":"RFC 3339 time to publish at; omit to keep the current one.","type":"string"}},"type":"object"},"social.YoutubeOptions":{"properties":{"made_for_kids":{"type":"boolean"},"privacy_status":{"description":"public (default), unlisted or private.","enum":["public","unlisted","private"],"type":"string"},"tags":{"items":{"type":"string"},"maxItems":30,"type":"array"},"title":{"description":"Video title; defaults to the caption, so it is required when the caption is longer than 100 characters.","maxLength":100,"type":"string"}},"required":["tags"],"type":"object"},"template.GetOverviewFromTemplatesRow":{"properties":{"category_id":{"type":"string"},"category_name":{"type":"string"},"templates":{"items":{"$ref":"#/definitions/types.Template"},"type":"array"}},"type":"object"},"template.TemplateCategory":{"properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"types.BatchComplete":{"properties":{"completed":{"type":"integer"},"failed":{"items":{"$ref":"#/definitions/types.BatchCompleteFailed"},"type":"array"}},"type":"object"},"types.BatchCompleteFailed":{"properties":{"error":{"type":"string"},"upload_id":{"type":"string"}},"type":"object"},"types.BatchCompleteInput":{"properties":{"upload_ids":{"items":{"type":"string"},"maxItems":200,"minItems":1,"type":"array"}},"required":["upload_ids"],"type":"object"},"types.BatchUpload":{"properties":{"items":{"items":{"$ref":"#/definitions/types.BatchUploadItem"},"type":"array"},"rejected":{"items":{"$ref":"#/definitions/types.BatchUploadRejected"},"type":"array"}},"type":"object"},"types.BatchUploadInput":{"properties":{"files":{"items":{"$ref":"#/definitions/types.UploadInput"},"maxItems":200,"minItems":1,"type":"array"},"project_id":{"type":"string"}},"required":["files"],"type":"object"},"types.BatchUploadItem":{"properties":{"media_id":{"example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"presigned_url":{"type":"string"},"upload_id":{"type":"string"}},"type":"object"},"types.BatchUploadRejected":{"properties":{"media_id":{"example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"reason":{"type":"string"}},"type":"object"},"types.BrandVoice":{"properties":{"audience":{"type":"string"},"energy":{"type":"string"},"name":{"description":"Name is the editable brand display name. Seeded once from the import's\nextracted name; a user's value is never overwritten by a re-import.","type":"string"},"notes":{"description":"free-form extra direction, read verbatim by the agent","type":"string"},"tone":{"type":"string"}},"type":"object"},"types.Brandkit":{"properties":{"brand_voice":{"$ref":"#/definitions/types.BrandVoice"},"branding":{"description":"Branding is the raw extracted branding payload (logo URLs, suggested\ncolors/fonts). Empty when never imported.","type":"object"},"id":{"type":"string"},"onboarded":{"type":"boolean"},"summary":{"type":"string"},"tone":{"type":"string"},"website_url":{"type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"types.BrandkitImportAssetInput":{"properties":{"asset_type":{"type":"string"},"library_upload_id":{"type":"string"},"name":{"maxLength":255,"type":"string"},"url":{"maxLength":2048,"type":"string"}},"required":["asset_type"],"type":"object"},"types.BrandkitUpload":{"properties":{"asset_type":{"type":"string"},"duration":{"type":"number"},"height":{"type":"integer"},"id":{"type":"string"},"mime_type":{"type":"string"},"name":{"type":"string"},"original_file_name":{"type":"string"},"source_url":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"},"width":{"type":"integer"}},"type":"object"},"types.CreateExport":{"properties":{"job_id":{"example":"d97241f2-e1e4-4651-b078-8663fc35c584","format":"uuid","type":"string"}},"type":"object"},"types.CreateExportInput":{"properties":{"project":{"description":"Render-ready project JSON to export inline, used instead of project_id when\nthe project is not stored on Rendley. Every media item referenced in the\nJSON (video, image, audio, font) must use a permanent, publicly reachable\nURL so the render server can resolve and download it. Temporary or signed\nURLs that expire will cause the render to fail.","type":"object"},"project_id":{"description":"ID of a project already stored on Rendley to export. Provide either\nproject_id or project, not both.","type":"string"},"settings":{"allOf":[{"$ref":"#/definitions/types.ExportSettings"}],"description":"Optional render settings. Defaults are applied when omitted."}},"type":"object"},"types.CreateProjectExportInput":{"properties":{"settings":{"$ref":"#/definitions/types.ExportSettings"}},"type":"object"},"types.CreateProjectInput":{"properties":{"agent_prompt":{"description":"AgentPrompt, when set, is stored on the project and prefilled into the\nassistant when the editor opens (MCP draft handoff).","maxLength":100000,"type":"string"},"agent_skill":{"description":"AgentSkill, when set with AgentPrompt, pre-selects that workflow skill\nin the assistant's picker so the handoff prompt runs pinned to it.","maxLength":64,"type":"string"},"fields":{"additionalProperties":{},"description":"Values for the template's fields, by key or path. Requires template_id.","type":"object"},"name":{"description":"Max matches the projects.name column (VARCHAR(255)). Defaults to the template's name when template_id is set.","maxLength":255,"type":"string"},"template_id":{"type":"string"},"workspace_id":{"description":"Optional when the account has exactly one workspace — the project is\ncreated there. Required once a second workspace exists.","type":"string"}},"type":"object"},"types.CreateUpload":{"properties":{"media_id":{"description":"MediaID identifies the file once complete: pass it as the `media`\nreference of AI actions and as an agent attachment. Echoes the request's\nmedia_id, or the server-generated one when the request sent none.","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"presigned_url":{"type":"string"},"upload_id":{"type":"string"}},"type":"object"},"types.CreateWorkspaceInput":{"properties":{"name":{"description":"Max matches the workspaces.name column (VARCHAR(255)).","maxLength":255,"type":"string"}},"required":["name"],"type":"object"},"types.CurrentUser":{"properties":{"credits":{"$ref":"#/definitions/types.UserCredits"},"email":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"photo_url":{"type":"string"},"subscription":{"$ref":"#/definitions/types.UserSubscription"},"usage":{"$ref":"#/definitions/types.UserUsage"},"usage_meters":{"items":{"$ref":"#/definitions/types.UsageMeter"},"type":"array"}},"type":"object"},"types.DirectUpload":{"properties":{"control_url":{"type":"string"},"expires_at":{"type":"string"},"file_name":{"type":"string"},"file_size":{"type":"integer"},"media_id":{"type":"string"},"part_count":{"type":"integer"},"part_size":{"type":"integer"},"upload_id":{"type":"string"}},"type":"object"},"types.DirectUploadInput":{"properties":{"file_name":{"maxLength":255,"type":"string"},"file_size":{"maximum":5368709120,"minimum":1,"type":"integer"},"mime_type":{"maxLength":100,"type":"string"}},"required":["file_name","file_size","mime_type"],"type":"object"},"types.ExportSettings":{"properties":{"codec":{"description":"Optional. Video codec to render with. Defaults are applied server-side when omitted.","enum":["h264","vp8"],"type":"string"},"quality":{"description":"Optional. Render quality (encoder bitrate). Defaults to high when omitted. Higher quality produces larger files.","enum":["high","medium","low"],"type":"string"},"target_resolution":{"description":"Optional. Output resolution. Defaults to 1080p when omitted. Applies to the canvas's short edge for standard aspect ratios (a 9:16 project exports as 1080x1920 at 1080p) and to the long edge for custom canvas sizes; the aspect ratio is always preserved.","enum":["360p","480p","720p","1080p","2K","4K"],"type":"string"}},"type":"object"},"types.ImportUploadInput":{"properties":{"async":{"description":"Async returns the row at once and downloads in the background; follow\nit with the upload status endpoint.","type":"boolean"},"download_url":{"type":"string"},"file_name":{"maxLength":255,"type":"string"},"mime_type":{"maxLength":100,"type":"string"},"project_id":{"type":"string"},"role":{"description":"Role/Source follow the same defaults as UploadInput.","enum":["library","pending","staged","transient"],"type":"string"},"source":{"enum":["editor","mcp","agent","export","ai","duplicate"],"type":"string"}},"required":["download_url"],"type":"object"},"types.Job":{"properties":{"acknowledged":{"type":"boolean"},"error":{"type":"string"},"error_message":{"description":"ErrorMessage says what Error's code means, when it is a known one.","type":"string"},"id":{"example":"f0e1d2c3-b4a5-4678-9012-3456789abcde","format":"uuid","type":"string"},"input_data":{"type":"string"},"output":{"$ref":"#/definitions/types.JobOutput"},"result_data":{"type":"string"},"sentences":{"description":"Sentences is a finished transcription's speech, sentence by sentence\nwith its times in the recording.","items":{"$ref":"#/definitions/types.TranscriptSentence"},"type":"array"},"source_id":{"type":"string"},"source_type":{"type":"string"},"status":{"description":"queued | processing | completed | failed | canceled","enum":["queued","processing","completed","failed","canceled"],"type":"string"},"type":{"type":"string"}},"type":"object"},"types.JobOutput":{"properties":{"duration":{"type":"number"},"expires_at":{"format":"date-time","type":"string"},"file_hash":{"description":"FileHash is the engine's content hash (XXH3-64, 16 hex chars).","example":"c6c8ec4f9a6fdd9d","type":"string"},"media_id":{"description":"MediaID is the output file's storage key, a UUID.","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","format":"uuid","type":"string"},"mime_type":{"type":"string"},"project_id":{"example":"cf32a652-56cf-4dfd-9ac6-191e90465df5","format":"uuid","type":"string"},"size":{"type":"integer"},"url":{"description":"URL is a fresh signed download URL for the generated or exported file.","example":"https://cdn.example.com/generated/video.mp4?signature=...","format":"uri","type":"string"},"url_expires_at":{"description":"URLExpiresAt tells automation clients when to poll again for a fresh URL.","example":"2026-08-31T15:00:00Z","format":"date-time","type":"string"},"workspace_id":{"example":"3b66b9b6-de8e-44c3-9f27-848a09c79320","format":"uuid","type":"string"}},"type":"object"},"types.JobSummary":{"properties":{"acknowledged":{"type":"boolean"},"error":{"type":"string"},"error_message":{"description":"ErrorMessage says what Error's code means, when it is a known one.","type":"string"},"id":{"example":"f0e1d2c3-b4a5-4678-9012-3456789abcde","format":"uuid","type":"string"},"input_data":{"type":"string"},"result_data":{"type":"string"},"source_id":{"type":"string"},"source_type":{"type":"string"},"status":{"description":"queued | processing | completed | failed | canceled","enum":["queued","processing","completed","failed","canceled"],"type":"string"},"type":{"type":"string"}},"type":"object"},"types.LibraryAddToProjectInput":{"properties":{"project_id":{"type":"string"}},"required":["project_id"],"type":"object"},"types.LibraryChunkedInit":{"properties":{"part_size_max":{"type":"integer"},"part_size_min":{"description":"Parts must be sent sequentially (1, 2, 3, ...) within these size bounds;\nonly the final part may be smaller than the minimum.","type":"integer"},"upload_id":{"type":"string"},"upload_url":{"description":"UploadURL, for MCP callers, takes the whole file as one PUT (or parts as\n`PUT \u003cupload_url\u003e\u0026part=N`) with no other credential; the upload\ncompletes when the last byte arrives.","type":"string"}},"type":"object"},"types.LibraryChunkedInitInput":{"properties":{"duration":{"type":"number"},"file_size":{"minimum":1,"type":"integer"},"mime_type":{"maxLength":100,"type":"string"},"original_file_name":{"maxLength":255,"type":"string"},"project_id":{"description":"ProjectID, when set, adds the asset to that project's media once the\nupload completes through its upload_url.","type":"string"},"source":{"enum":["uploaded","export"],"type":"string"}},"required":["file_size"],"type":"object"},"types.LibraryChunkedPartResult":{"properties":{"asset":{"allOf":[{"$ref":"#/definitions/types.LibraryUpload"}],"description":"Set on the final part sent through an upload_url: the completed asset\nand, when the upload named a project, the project's copy."},"next_part":{"type":"integer"},"project_upload":{"$ref":"#/definitions/types.Upload"},"received_bytes":{"type":"integer"}},"type":"object"},"types.LibraryImportStatus":{"properties":{"error":{"type":"string"},"file_name":{"type":"string"},"file_size":{"type":"integer"},"id":{"type":"string"},"media_id":{"type":"string"},"status":{"allOf":[{"$ref":"#/definitions/types.UploadStatus"}],"description":"Status is importing, complete or failed."}},"type":"object"},"types.LibraryMultipartInit":{"properties":{"existing":{"$ref":"#/definitions/types.LibraryUpload"},"media_id":{"description":"MediaID identifies the file once complete (see CreateUpload.MediaID).","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"presigned_urls":{"items":{"$ref":"#/definitions/types.MultipartPartURL"},"type":"array"},"s3_upload_id":{"type":"string"},"upload_id":{"type":"string"}},"type":"object"},"types.LibraryMultipartInitInput":{"properties":{"duration":{"type":"number"},"file_hash":{"description":"FileHash is required: multipart bytes go client→bucket, so the client\nis the only party that ever holds the full stream — every completed\nlibrary row must carry its content hash (XXH3-64, 16 hex chars).","example":"c6c8ec4f9a6fdd9d","maxLength":64,"minLength":1,"type":"string"},"file_size":{"minimum":1,"type":"integer"},"mime_type":{"maxLength":100,"type":"string"},"original_file_name":{"maxLength":255,"type":"string"},"part_count":{"maximum":10000,"minimum":1,"type":"integer"},"source":{"description":"Source provenance; clients may claim \"uploaded\" (default) or \"export\".","enum":["uploaded","export"],"type":"string"},"transient":{"description":"Transient uploads are scratch input for an AI job: never listed as a\nLibrary asset, unmetered, removed by the daily stale-upload sweep.\nReference by upload id only.","type":"boolean"}},"required":["file_hash","file_size","part_count"],"type":"object"},"types.LibraryPromoteInput":{"properties":{"file_hash":{"example":"c6c8ec4f9a6fdd9d","maxLength":64,"type":"string"},"project_id":{"type":"string"}},"required":["file_hash","project_id"],"type":"object"},"types.LibraryRenameInput":{"properties":{"name":{"maxLength":255,"type":"string"},"upload_id":{"description":"UploadID is read from the {uploadId} path segment on the public routes;\nthe editor's flat mount still sends it in the body.","type":"string"}},"required":["name"],"type":"object"},"types.LibraryTagsInput":{"properties":{"tags":{"items":{"type":"string"},"maxItems":20,"type":"array"},"upload_id":{"description":"UploadID is read from the {uploadId} path segment on the public routes;\nthe editor's flat mount still sends it in the body.","type":"string"}},"type":"object"},"types.LibraryUpload":{"properties":{"created_at":{"type":"string"},"deduplicated":{"description":"Deduplicated marks a proxy-upload response that resolved to an existing\nasset with identical content instead of storing a second copy.","type":"boolean"},"download_url":{"description":"DownloadUrl is a presigned GET that forces a browser download\n(Content-Disposition: attachment) under the original filename.\nExpires like Url.","type":"string"},"duration":{"type":"number"},"file_hash":{"example":"c6c8ec4f9a6fdd9d","type":"string"},"file_size":{"type":"integer"},"id":{"type":"string"},"media_id":{"description":"MediaID is the upload's storage_key; clients reuse it as the editor media\nid when bridging a library asset into a project, so ids stay stable.","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"mime_type":{"type":"string"},"original_file_name":{"type":"string"},"source":{"type":"string"},"status":{"allOf":[{"$ref":"#/definitions/types.UploadStatus"}],"description":"Status is set on an async import response: \"importing\"."},"tags":{"items":{"type":"string"},"type":"array"},"thumbnail_url":{"description":"ThumbnailUrl is a presigned GET for the server-generated poster (video\nfirst frame / GIF still). Empty when none exists. Expires like Url.","type":"string"},"url":{"description":"Url is a presigned GET for the asset bytes. Expires — never persist it.","type":"string"},"workspace_id":{"type":"string"}},"type":"object"},"types.LibraryUploadList":{"properties":{"items":{"items":{"$ref":"#/definitions/types.LibraryUpload"},"type":"array"},"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}},"type":"object"},"types.MultipartAbortInput":{"properties":{"s3_upload_id":{"type":"string"},"upload_id":{"type":"string"}},"required":["s3_upload_id","upload_id"],"type":"object"},"types.MultipartCompleteInput":{"properties":{"parts":{"items":{"$ref":"#/definitions/types.MultipartCompletedPart"},"minItems":1,"type":"array"},"s3_upload_id":{"type":"string"},"upload_id":{"type":"string"}},"required":["parts","s3_upload_id","upload_id"],"type":"object"},"types.MultipartCompletedPart":{"properties":{"etag":{"type":"string"},"part_number":{"minimum":1,"type":"integer"}},"required":["etag","part_number"],"type":"object"},"types.MultipartInit":{"properties":{"media_id":{"description":"MediaID identifies the file once complete (see CreateUpload.MediaID).","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"presigned_urls":{"items":{"$ref":"#/definitions/types.MultipartPartURL"},"type":"array"},"s3_upload_id":{"type":"string"},"upload_id":{"type":"string"}},"type":"object"},"types.MultipartInitInput":{"properties":{"duration":{"type":"number"},"file_hash":{"description":"FileHash is the client-computed content hash (XXH3-64, 16 hex chars).\nOptional for API keys.","example":"c6c8ec4f9a6fdd9d","maxLength":64,"type":"string"},"file_size":{"type":"integer"},"media_id":{"description":"MediaId is the client-chosen media id (a UUID). Optional for API keys.","maxLength":128,"type":"string"},"metadata":{"type":"string"},"mime_type":{"maxLength":100,"type":"string"},"original_file_name":{"maxLength":255,"type":"string"},"part_count":{"maximum":10000,"minimum":1,"type":"integer"},"project_id":{"type":"string"},"role":{"description":"Role is the sync-lifecycle tag: \"library\" (reconciled by the editor's\nhash sync), \"pending\" (awaiting auto-injection into the library;\ninvisible to the sync), \"staged\" (agent/AI workflow file; invisible to\nthe sync AND not auto-injected — adopted to library only when\nexplicitly referenced) or \"transient\" (never a library asset).\nDefaults to \"library\"; \"pending\" when Source is \"mcp\"; \"staged\" for\nAPI-key requests (so opening the project in the editor never reaps an\nAPI-uploaded file before it is referenced).","enum":["library","pending","staged","transient"],"type":"string"},"source":{"description":"Source is provenance: which flow created the upload.","enum":["editor","mcp","agent","export","ai","duplicate"],"type":"string"}},"required":["part_count"],"type":"object"},"types.MultipartPartURL":{"properties":{"part_number":{"type":"integer"},"url":{"type":"string"}},"type":"object"},"types.PageMeta":{"properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"total_results":{"type":"integer"}},"type":"object"},"types.Project":{"properties":{"agent_prompt":{"description":"Handoff prompt the editor prefills into the assistant; cleared on send.","type":"string"},"agent_skill":{"description":"Handoff workflow skill (a name from GET /agent/skills) the editor\npre-selects in the assistant's skill picker alongside AgentPrompt.","type":"string"},"created_at":{"type":"string"},"created_by":{"type":"string"},"deleted_at":{"type":"string"},"fit_duration":{"type":"number"},"id":{"type":"string"},"last_viewed_at":{"type":"string"},"name":{"type":"string"},"project_json":{"type":"string"},"template":{"allOf":[{"$ref":"#/definitions/types.TemplateDefinition"}],"description":"Fields the author promoted for a template; kept outside the engine document."},"template_mode":{"description":"Set on projects started from a template: the editor opens the fields form.","type":"boolean"},"thumbnail_url":{"type":"string"},"updated_at":{"type":"string"},"version":{"type":"integer"},"workspace_id":{"type":"string"}},"type":"object"},"types.SaveTemplateInput":{"properties":{"fields":{"description":"Replaces the project's template fields before saving; omitted keeps the ones set in the editor.","items":{"$ref":"#/definitions/types.TemplateFieldDefinition"},"maxItems":200,"type":"array"},"name":{"maxLength":255,"type":"string"}},"type":"object"},"types.Template":{"properties":{"created_at":{"type":"string"},"created_by":{"type":"string"},"fields":{"items":{"$ref":"#/definitions/types.TemplateField"},"type":"array"},"fit_duration":{"type":"number"},"height":{"type":"integer"},"id":{"type":"string"},"is_premium":{"type":"boolean"},"name":{"type":"string"},"preview_video_url":{"type":"string"},"source_project_id":{"description":"The project a user template was saved from, while that project exists.","type":"string"},"template_json":{"type":"string"},"thumbnail_url":{"type":"string"},"updated_at":{"type":"string"},"width":{"type":"integer"},"workspace_id":{"type":"string"}},"type":"object"},"types.TemplateDefinition":{"properties":{"fields":{"items":{"$ref":"#/definitions/types.TemplateFieldDefinition"},"maxItems":200,"type":"array"},"version":{"type":"integer"}},"type":"object"},"types.TemplateField":{"properties":{"group":{"description":"The clip, or the canvas, the field belongs to.","type":"string"},"key":{"description":"Name in POST /projects `fields`; the path when the author set no key.","type":"string"},"label":{"type":"string"},"length":{"description":"Item count of a list field; a value must have the same.","type":"integer"},"linked":{"description":"How many more places the same value fills: fields sharing a key are linked.","type":"integer"},"media_kind":{"enum":["image","video","gif","audio"],"type":"string"},"path":{"type":"string"},"type":{"enum":["text","number","color","boolean","list","media"],"type":"string"},"value":{"description":"Empty for media fields: a synced file has no public url."}},"type":"object"},"types.TemplateFieldDefinition":{"properties":{"alias":{"description":"Name the author gave the field in the editor.","maxLength":200,"type":"string"},"clip_id":{"description":"Clip a media field was promoted from.","maxLength":64,"type":"string"},"group":{"description":"The clip, media or canvas the field belongs to.","maxLength":200,"type":"string"},"key":{"description":"Name in POST /projects `fields`; the path when unset.","maxLength":64,"type":"string"},"label":{"maxLength":200,"type":"string"},"path":{"description":"Document path, e.g. clips.\u003cid\u003e.text or media.\u003cid\u003e.url.","maxLength":512,"type":"string"},"property_id":{"description":"Editor panel field and right-sidebar step that render it.","maxLength":128,"type":"string"},"step":{"maxLength":64,"type":"string"}},"required":["path"],"type":"object"},"types.TranscriptSentence":{"properties":{"end":{"type":"number"},"start":{"type":"number"},"text":{"type":"string"}},"type":"object"},"types.Upload":{"properties":{"duration":{"type":"number"},"error":{"description":"Error says why a failed upload failed.","type":"string"},"file_hash":{"example":"c6c8ec4f9a6fdd9d","type":"string"},"media_id":{"description":"MediaID is the upload's storage_key — the library media id the client\nshould reuse when injecting a pending upload, so ids stay stable across\nbackend and editor.","example":"c448b6e3-2b78-4bda-b369-d1afc6aec07f","type":"string"},"mime_type":{"type":"string"},"original_file_name":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"storage_url":{"type":"string"}},"type":"object"},"types.UploadInput":{"properties":{"duration":{"type":"number"},"file_hash":{"description":"FileHash is the client-computed content hash (XXH3-64, 16 hex chars).\nOptional for API keys.","example":"c6c8ec4f9a6fdd9d","maxLength":64,"type":"string"},"file_size":{"type":"integer"},"media_id":{"description":"MediaId is the client-chosen media id (a UUID). Optional for API keys.","maxLength":128,"type":"string"},"metadata":{"type":"string"},"mime_type":{"maxLength":100,"type":"string"},"original_file_name":{"maxLength":255,"type":"string"},"project_id":{"type":"string"},"role":{"description":"Role is the sync-lifecycle tag: \"library\" (reconciled by the editor's\nhash sync), \"pending\" (awaiting auto-injection into the library;\ninvisible to the sync), \"staged\" (agent/AI workflow file; invisible to\nthe sync AND not auto-injected — adopted to library only when\nexplicitly referenced) or \"transient\" (never a library asset).\nDefaults to \"library\"; \"pending\" when Source is \"mcp\"; \"staged\" for\nAPI-key requests (so opening the project in the editor never reaps an\nAPI-uploaded file before it is referenced).","enum":["library","pending","staged","transient"],"type":"string"},"source":{"description":"Source is provenance: which flow created the upload.","enum":["editor","mcp","agent","export","ai","duplicate"],"type":"string"}},"type":"object"},"types.UploadStatus":{"enum":["uploading","importing","complete","failed"],"type":"string","x-enum-varnames":["UploadStatusUploading","UploadStatusImporting","UploadStatusComplete","UploadStatusFailed"]},"types.UploadStatusView":{"properties":{"error":{"type":"string"},"file_name":{"type":"string"},"file_size":{"type":"integer"},"media_id":{"type":"string"},"received_bytes":{"type":"integer"},"status":{"$ref":"#/definitions/types.UploadStatus"}},"type":"object"},"types.UsageMeter":{"properties":{"key":{"type":"string"},"limit":{"type":"integer"},"reset_at":{"type":"string"},"used":{"type":"integer"}},"type":"object"},"types.UserCredits":{"properties":{"balance":{"type":"integer"},"purchased_credits":{"description":"never expire","type":"integer"},"subscription_credits":{"description":"resets each billing period","type":"integer"}},"type":"object"},"types.UserSubscription":{"properties":{"auto_reframe":{"type":"boolean"},"billing_interval":{"type":"string"},"brandkit_asset_upload":{"type":"boolean"},"brandkit_font_upload":{"type":"boolean"},"brandkit_logo_limit":{"type":"integer"},"brandkit_voice_limit":{"type":"integer"},"mcp_agent_max_concurrent":{"type":"integer"},"music_seconds":{"type":"integer"},"plan_name":{"type":"string"},"plan_variant_id":{"type":"string"},"projects":{"type":"integer"},"social_analytics":{"type":"boolean"},"social_publishing":{"type":"boolean"},"status":{"type":"string"},"storage_bytes":{"type":"integer"},"templates":{"type":"boolean"},"transcription_seconds":{"type":"integer"},"tts_chars":{"type":"integer"},"workspaces":{"type":"integer"}},"type":"object"},"types.UserUsage":{"properties":{"music_seconds_used":{"type":"integer"},"projects_used":{"type":"integer"},"storage_counted_bytes":{"type":"integer"},"storage_limit_bytes":{"description":"StorageLimitBytes is the plan's storage, free plan included; uploads\nare refused once StorageCountedBytes plus StorageUploadingBytes would\npass it. The free plan counts only its expiring files.","type":"integer"},"storage_uploading_bytes":{"type":"integer"},"storage_used":{"type":"integer"},"transcription_seconds_used":{"type":"integer"},"tts_chars_used":{"type":"integer"},"workspaces_used":{"type":"integer"}},"type":"object"},"types.Workspace":{"properties":{"created_by":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"social_analytics":{"type":"boolean"},"social_publishing":{"type":"boolean"},"templates":{"type":"boolean"}},"type":"object"},"workspace.UpdateWorkspaceDTO":{"properties":{"name":{"type":"string"}},"required":["name"],"type":"object"}},"host":"api.rendley.com","info":{"contact":{"email":"support@rendley.com","name":"Rendley Support"},"description":"Public REST API for Rendley. Authenticate with an API key by sending it as a Bearer token in the Authorization header.\n\nYou can obtain an API key from https://app.rendley.com/settings\n\nExample:\ncurl https://api.rendley.com/v1/jobs/{id} -H \"Authorization: Bearer \u003cyour-api-key\u003e\"","license":{"name":"Proprietary","url":"https://rendley.com/terms-and-conditions"},"title":"Rendley API","version":"1.0"},"paths":{"/ai/generate-image":{"post":{"consumes":["application/json"],"description":"Enqueue a job to generate an image from a text prompt, or edit an existing image.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Image generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateImageDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate an image","tags":["AI"]}},"/ai/generate-image/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of generating or editing an image.","parameters":[{"description":"Image generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateImageDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate image generation cost","tags":["AI"]}},"/ai/generate-motion-graphics":{"post":{"consumes":["application/json"],"description":"Start a project-scoped motion-graphics generation and return its API job ID. Motion graphics are project content and are not added to the workspace Library.","parameters":[{"description":"Motion-graphics request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai.GenerateMotionGraphicsDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate motion graphics","tags":["AI"]}},"/ai/generate-motion-graphics/cost":{"post":{"description":"Return the fixed credit cost for a motion-graphics generation.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate motion-graphics generation cost","tags":["AI"]}},"/ai/generate-music":{"post":{"consumes":["application/json"],"description":"Enqueue a job to generate music from a text prompt describing genre, instruments, tempo, and structure.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Music generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateMusicDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate music","tags":["AI"]}},"/ai/generate-music/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of generating music from a text prompt.","parameters":[{"description":"Music generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateMusicDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate music generation cost","tags":["AI"]}},"/ai/generate-sound-effect":{"post":{"consumes":["application/json"],"description":"Enqueue a job to generate a custom sound effect from a text description.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Sound effect request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateSoundEffectDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate a sound effect","tags":["AI"]}},"/ai/generate-sound-effect/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of generating a sound effect from a text description.","parameters":[{"description":"Sound effect request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateSoundEffectDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate sound effect generation cost","tags":["AI"]}},"/ai/generate-video":{"post":{"consumes":["application/json"],"description":"Enqueue a job to generate a video clip from a text prompt, optionally animating a starting/ending image.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Video generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateVideoDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate a video","tags":["AI"]}},"/ai/generate-video/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of generating a video clip.","parameters":[{"description":"Video generation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.GenerateVideoDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate video generation cost","tags":["AI"]}},"/ai/lipsync":{"post":{"consumes":["application/json"],"description":"Enqueue a job to lip-sync a video clip to a separate audio track.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Lipsync request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.LipsyncDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Lip-sync a video to audio","tags":["AI"]}},"/ai/lipsync/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of lip-syncing a video clip to an audio track.","parameters":[{"description":"Lipsync request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.LipsyncDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate lipsync cost","tags":["AI"]}},"/ai/models":{"get":{"description":"List available AI models. Use schema_url to retrieve the JSON Schema accepted in the request's params object for a specific model.","operationId":"listAIModels","parameters":[{"description":"Filter by action, for example generate_video","in":"query","name":"action","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/ai.AIModelSummary"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List AI models","tags":["AI"]}},"/ai/models/{modelId}":{"get":{"description":"Return one model and the JSON Schema accepted in the params object by that model's generation and cost endpoints. This schema is generated from the runtime validator and is the source of truth for dynamic forms and integrations.","operationId":"getAIModel","parameters":[{"description":"Model ID","in":"path","name":"modelId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/ai.AIModelDetail"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get an AI model schema","tags":["AI"]}},"/ai/models/{modelId}/voices":{"get":{"description":"Voices a voice model takes: on page 1 the recommended voices matching the filters, then public voice library voices page by page. Filter values come from GET /ai/models/{modelId}/voices/filters.","parameters":[{"description":"Model ID","in":"path","name":"modelId","required":true,"type":"string"},{"description":"Page number","in":"query","name":"page","type":"string"},{"description":"Page size","in":"query","name":"limit","type":"string"},{"description":"Search query","in":"query","name":"query","type":"string"},{"description":"Gender filter","in":"query","name":"gender","type":"string"},{"description":"Age filter","in":"query","name":"age","type":"string"},{"description":"Accent filter","in":"query","name":"accent","type":"string"},{"description":"Language filter (ISO 639-1)","in":"query","name":"language","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.VoiceResult"},"type":"array"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List a model's voices","tags":["AI"]}},"/ai/models/{modelId}/voices/filters":{"get":{"description":"Filter options for GET /ai/models/{modelId}/voices: genders, ages, languages, and the accents of the given language.","parameters":[{"description":"Model ID","in":"path","name":"modelId","required":true,"type":"string"},{"description":"Language whose accents to list (ISO 639-1)","in":"query","name":"language","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.FilterOptions"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List a model's voice filters","tags":["AI"]}},"/ai/remove-image-background":{"post":{"consumes":["application/json"],"description":"Enqueue a job to remove the background from an image, leaving only the foreground subject.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Remove image background request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.RemoveImageBackgroundDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Remove image background","tags":["AI"]}},"/ai/remove-image-background/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of removing the background from an image.","parameters":[{"description":"Remove image background request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.RemoveImageBackgroundDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate remove image background cost","tags":["AI"]}},"/ai/remove-video-background":{"post":{"consumes":["application/json"],"description":"Enqueue a job to remove the background from a video frame-by-frame, leaving only the foreground subject.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Remove video background request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.RemoveVideoBackgroundDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Remove video background","tags":["AI"]}},"/ai/remove-video-background/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of removing the background from a video.","parameters":[{"description":"Remove video background request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.RemoveVideoBackgroundDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate remove video background cost","tags":["AI"]}},"/ai/smart-cut":{"post":{"consumes":["application/json"],"description":"Enqueue a job that transcribes a recording, decides which stretches are filler, dead air, false starts or repeated takes, and returns a new video with them removed.","parameters":[{"description":"Smart cut request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai.SmartCutDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Cut bad takes and filler words","tags":["AI"]}},"/ai/smart-cut/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of cutting bad takes and filler words out of a recording. Free while the user has transcription minutes left.","parameters":[{"description":"Smart cut request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai.SmartCutDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate smart cut cost","tags":["AI"]}},"/ai/text-to-speech":{"post":{"consumes":["application/json"],"description":"Enqueue a job to generate spoken-word audio from text using a selected voice.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Text-to-speech request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.TextToSpeechDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Generate text-to-speech audio","tags":["AI"]}},"/ai/text-to-speech/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of generating spoken-word audio from text.","parameters":[{"description":"Text-to-speech request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.TextToSpeechDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate text-to-speech cost","tags":["AI"]}},"/ai/text-to-speech/voices":{"get":{"description":"Voices of the default text-to-speech model; same as GET /ai/models/{modelId}/voices.","parameters":[{"description":"Page number","in":"query","name":"page","type":"string"},{"description":"Page size","in":"query","name":"limit","type":"string"},{"description":"Search query","in":"query","name":"query","type":"string"},{"description":"Gender filter","in":"query","name":"gender","type":"string"},{"description":"Age filter","in":"query","name":"age","type":"string"},{"description":"Accent filter","in":"query","name":"accent","type":"string"},{"description":"Language filter (ISO 639-1)","in":"query","name":"language","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/ai_manager_feature_text_to_speech.VoiceResult"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List text-to-speech voices","tags":["AI"]}},"/ai/text-to-speech/voices/{voiceId}/preview":{"get":{"description":"Get a preview audio URL for a specific text-to-speech voice.","parameters":[{"description":"Voice ID","in":"path","name":"voiceId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/ai.VoicePreviewResponse"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get a voice preview","tags":["AI"]}},"/ai/tools":{"get":{"description":"List the available AI tools (actions) and the models available under each.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/ai.aiToolResponseItem"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List AI tools","tags":["AI"]}},"/ai/transcribe":{"post":{"consumes":["application/json"],"description":"Enqueue a job to transcribe spoken words in an audio or video clip to text with word-level timestamps.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Transcription request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.TranscribeDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Transcribe audio or video","tags":["AI"]}},"/ai/transcribe/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of transcribing an audio or video clip.","parameters":[{"description":"Transcription request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.TranscribeDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate transcription cost","tags":["AI"]}},"/ai/upscale-image":{"post":{"consumes":["application/json"],"description":"Enqueue a job to upscale an existing image to higher resolution using AI super-resolution.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Upscale image request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.UpscaleImageDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Upscale an image","tags":["AI"]}},"/ai/upscale-image/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of upscaling an image to higher resolution.","parameters":[{"description":"Upscale image request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.UpscaleImageDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate image upscale cost","tags":["AI"]}},"/ai/upscale-video":{"post":{"consumes":["application/json"],"description":"Enqueue a job to upscale an existing video to higher resolution (up to 4K) using AI super-resolution.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Upscale video request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.UpscaleVideoDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Upscale a video","tags":["AI"]}},"/ai/upscale-video/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of upscaling a video to higher resolution (billed per second of source video).","parameters":[{"description":"Upscale video request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.UpscaleVideoDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate video upscale cost","tags":["AI"]}},"/ai/video-translate":{"post":{"consumes":["application/json"],"description":"Enqueue a job to translate the spoken content of a video into another language and dub it back in.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Video translate request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VideoTranslateDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Translate a video","tags":["AI"]}},"/ai/video-translate/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of translating and dubbing a video into another language.","parameters":[{"description":"Video translate request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VideoTranslateDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate video translation cost","tags":["AI"]}},"/ai/video-translate/languages":{"get":{"description":"List the languages supported as targets for video translation.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/ai_manager_feature_video_translate.VideoTranslateLanguage"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List video translate languages","tags":["AI"]}},"/ai/voice-changer":{"post":{"consumes":["application/json"],"description":"Enqueue a job to replace the voice in an audio or video clip with a different target voice.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Voice changer request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VoiceChangerDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Change the voice in a clip","tags":["AI"]}},"/ai/voice-changer/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of replacing the voice in an audio or video clip.","parameters":[{"description":"Voice changer request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VoiceChangerDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate voice changer cost","tags":["AI"]}},"/ai/voice-isolation":{"post":{"consumes":["application/json"],"description":"Enqueue a job to isolate human voice and remove background noise, music, and other unwanted sounds.\nThe params object is model-specific — fetch its JSON Schema from GET /v1/ai/models/{model_id}. model_id is optional and falls back to this action's default model.","parameters":[{"description":"Voice isolation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VoiceIsolationDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"402":{"description":"Payment Required","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Isolate voice from audio","tags":["AI"]}},"/ai/voice-isolation/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of isolating voice and removing background noise from audio.","parameters":[{"description":"Voice isolation request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/ai_manager_types.VoiceIsolationDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"type":"integer"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate voice isolation cost","tags":["AI"]}},"/brandkit/{id}":{"get":{"description":"Retrieve the brand kit profile (website, summary, tone, onboarded) for a workspace.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Brandkit"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get the workspace brand kit","tags":["Brand Kit"]}},"/brandkit/{id}/assets/import":{"post":{"consumes":["application/json"],"description":"Copies one file into the brand kit as a logo, font or asset: from a public HTTPS URL, or from an item in the workspace library. Up to 50 MB.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Asset to import","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.BrandkitImportAssetInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.BrandkitUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Add a brand asset from a URL or the library","tags":["Brand Kit"]}},"/brandkit/{id}/import":{"post":{"consumes":["application/json"],"description":"Extract a website's brand (via the Gemini-backed extractor) and populate the brand kit profile, colors and fonts.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Website to import","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/brandkit.BrandkitImportDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Brandkit"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Import brand kit from a website","tags":["Brand Kit"]}},"/export":{"post":{"consumes":["application/json"],"description":"Start an export render job. Provide either `project_id` (a project stored on Rendley) or `project` (render-ready project JSON), but not both.\nWhen sending `project` inline, every media item referenced in the JSON (video, image, audio, font) must use a permanent, publicly reachable URL so the render server can resolve and download it; expiring/signed URLs will fail the render.\nThe response returns a job ID; poll `GET /jobs/{id}` for status and the resulting file.","parameters":[{"description":"Export request","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.CreateExportInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Create an export","tags":["Exports"]}},"/export/cost":{"post":{"consumes":["application/json"],"description":"Calculate the credit cost of an export without starting the render.","parameters":[{"description":"Export request to price","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.CreateExportInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/export.ExportCostResponse"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Calculate export cost","tags":["Exports"]}},"/jobs":{"get":{"description":"List up to 200 jobs. API-key requests always return only API-created jobs. List entries carry no output object — fetch GET /jobs/{id} for a completed job's download URL.","parameters":[{"description":"Filter by project ID","in":"query","name":"project_id","type":"string"},{"description":"Filter by workspace ID (jobs whose output lands in the workspace Library)","in":"query","name":"workspace_id","type":"string"},{"description":"Filter by job type","in":"query","name":"job_type","type":"string"},{"description":"Filter by acknowledged state","in":"query","name":"acknowledged","type":"boolean"},{"description":"Session-only source filter; API-key requests always use api","in":"query","name":"source_type","type":"string"},{"description":"Filter by source ID","in":"query","name":"source_id","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.JobSummary"},"type":"array"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List jobs","tags":["Jobs"]}},"/jobs/{id}":{"delete":{"description":"Cancel a queued job owned by the authenticated user and release its credits. A job already running finishes, is charged, and keeps its result.","parameters":[{"description":"Job ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Cancel a job","tags":["Jobs"]},"get":{"description":"Get a single API-created job. Completed media and export jobs include output.url and output.url_expires_at when the stored result is available. With wait (0-20 seconds) a queued or processing job is held open until it changes or the wait runs out.","parameters":[{"description":"Job ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Seconds to wait for a queued or processing job to change (0-20)","in":"query","name":"wait","type":"integer"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Job"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get a job","tags":["Jobs"]}},"/library/{workspaceId}/uploads/import":{"post":{"consumes":["application/json"],"description":"The server downloads a public HTTPS file and stores it as a Library asset. The host must report Content-Length. Dropbox and Google Drive share links are converted to direct downloads. With `async: true` the link is checked and the asset returned at once with status `importing`; follow it with GET /library/{workspaceId}/uploads/{uploadId}/status.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"File to import (project_id is ignored)","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.ImportUploadInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}}},"security":[{"BearerAuth":[]}],"summary":"Import a Library asset from a URL","tags":["Library"]}},"/library/{workspaceId}/uploads/{uploadId}/status":{"get":{"description":"Follows a Library import started with `async: true`: status is importing, complete or failed (with error).","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library asset id (the import response's id)","in":"path","name":"uploadId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryImportStatus"}},"type":"object"}]}}},"security":[{"BearerAuth":[]}],"summary":"Status of an async Library import","tags":["Library"]}},"/projects":{"get":{"description":"List all projects in a workspace.","parameters":[{"description":"Workspace ID. Optional when the account has exactly one workspace.","in":"query","name":"workspace_id","type":"string"},{"description":"Page number, newest first (default 1). Only used together with limit.","in":"query","name":"page","type":"integer"},{"description":"Results per page (1-500). Omit for all projects in last-viewed order.","in":"query","name":"limit","type":"integer"},{"description":"Page order: created_at (default, newest first) or last_viewed_at. Only used together with limit.","in":"query","name":"sort","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.Project"},"type":"array"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List projects","tags":["Projects"]},"post":{"consumes":["application/json"],"description":"Create a new project, optionally from a template. workspace_id may be omitted when the account has exactly one workspace. template_id takes a Rendley template or a user template. `fields` sets a user template's fields by key or path (see GET /templates/{id}); a media field takes a public https URL, which is imported into the project.","parameters":[{"description":"Project to create","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.CreateProjectInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Project"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"TEMPLATE_NOT_FOUND","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Create a project","tags":["Projects"]}},"/projects/{id}":{"delete":{"description":"Delete a project by its ID.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Delete a project","tags":["Projects"]},"get":{"description":"Retrieve a single project by its ID.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Project"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get a project","tags":["Projects"]},"patch":{"consumes":["application/json"],"description":"Update a project's mutable fields. Send only the fields you want to change. Public API keys may update metadata but cannot persist project_json until SDK schema validation is available; browser sessions retain the editor save behavior.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Fields to update","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/project.UpdateProjectDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Update a project","tags":["Projects"]}},"/projects/{id}/duplicate":{"post":{"description":"Create a copy of an existing project, including its media assets.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Project"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Duplicate a project","tags":["Projects"]}},"/projects/{id}/template":{"post":{"consumes":["application/json"],"description":"Copy the project (document and files) into a user template of its workspace. Saving again from the same project overwrites that template and keeps its id; deleting the project does not affect it. Start it with POST /projects and template_id. `fields` replaces the project's template fields first, each named by its path: clips.\u003cclip_id\u003e.\u003cproperty\u003e (e.g. clips.\u003cid\u003e.text, clips.\u003cid\u003e.style.color), display.\u003cproperty\u003e, or media.\u003cmedia_id\u003e.url for the file behind a media. Omitted, the fields set in the editor are kept.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Template name, defaulting to the current template or project name, and optional fields","in":"body","name":"body","schema":{"$ref":"#/definitions/types.SaveTemplateInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Template"}},"type":"object"}]}},"400":{"description":"VALIDATION_ERROR (e.g. a field path the project can't fill), or ANIMATED_TEMPLATE_FIELDS when keyframes drive a field","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"SUBSCRIPTION_REQUIRED on free plans, PLAN_LIMIT_REACHED when storage runs out","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"TEMPLATE_NOT_FOUND when the template was deleted during the save","schema":{"$ref":"#/definitions/http_response.Response"}},"409":{"description":"TEMPLATE_SAVE_IN_PROGRESS","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Save a project as a template","tags":["Projects"]}},"/projects/{id}/version":{"get":{"description":"Retrieve the current version number of a project. The version increments on every document save; poll it to detect edits made in the studio.","parameters":[{"description":"Project ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get a project's version","tags":["Projects"]}},"/projects/{projectId}/export":{"post":{"consumes":["application/json"],"description":"Start an export for the project identified by the path. Returns a job ID for polling.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Export settings","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.CreateProjectExportInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateExport"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Export a stored project","tags":["Exports"]}},"/projects/{projectId}/uploads":{"get":{"description":"List uploads for a project. Passing media_id or hash looks up one upload and returns `data` as a single upload object, not an array; without either, `data` is an array. An optional role filter scopes the list to one lifecycle role (the editor's hash sync passes role=library so pending/transient files are invisible to its reconciliation; the pending poller passes role=pending).","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Media id to fetch a single upload","in":"query","name":"media_id","type":"string"},{"description":"File hash to fetch a single upload","in":"query","name":"hash","type":"string"},{"description":"Filter by lifecycle role","enum":["library","pending","staged","transient"],"in":"query","name":"role","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.Upload"},"type":"array"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List uploads","tags":["Uploads"]},"post":{"consumes":["application/json"],"description":"Register a file and get a presigned URL to PUT its bytes to, then call the complete endpoint. media_id and file_hash are optional for API keys: the server generates the media_id (returned in the response) and records a placeholder hash. Use the media_id as the `media` reference of AI actions once the upload is complete.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Upload to create","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.UploadInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CreateUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Create an upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/batch":{"post":{"consumes":["application/json"],"description":"Create multiple uploads at once, returning presigned URLs for accepted files and reasons for rejected ones.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Uploads to create","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.BatchUploadInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.BatchUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Create a batch of uploads","tags":["Uploads"]}},"/projects/{projectId}/uploads/batch/complete":{"post":{"consumes":["application/json"],"description":"Mark a batch of uploads as completed by their upload IDs.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Upload IDs to complete","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.BatchCompleteInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.BatchComplete"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Complete a batch of uploads","tags":["Uploads"]}},"/projects/{projectId}/uploads/direct":{"get":{"description":"The caller's direct uploads into the project that are still waiting for their bytes, oldest first, each with its control URL, so a client that has the file can send it into the upload already announced.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.DirectUpload"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List the caller's unfinished direct uploads","tags":["Uploads"]},"post":{"consumes":["application/json"],"description":"Registers a file and returns a signed control URL. GET the control URL for one `part \u003cN\u003e \u003curl\u003e` line per part still missing, PUT each part's bytes (part_size bytes each, the last one the rest) to its URL, then POST the control URL to finish. Running the GET again after a failure lists only what is still missing. A part stored with the wrong size fails the upload: the control URL then answers 422 `size_mismatch …`. DELETE the control URL to cancel. Video, audio and image files only, up to 5 GB; an audio or video file ffprobe can't read fails once its bytes arrive.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"File to upload","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.DirectUploadInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.DirectUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Start a direct upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/import":{"post":{"consumes":["application/json"],"description":"One-call upload for a file that is already hosted: the server downloads it from a public HTTPS direct link, stores it and returns the completed upload. Use the returned media_id as the `media` reference of AI actions. No client-side hashing or presigned PUT is needed. The host must report Content-Length; files are capped at 5 GB and must be video, audio or images. Dropbox and Google Drive share links are converted to direct downloads. With `async: true` the link is checked and the upload returned at once with status `importing`; the download runs in the background (follow it with GET /projects/{projectId}/uploads/{media_id}/status).","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"File to import","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.ImportUploadInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Upload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Import an upload from a URL","tags":["Uploads"]}},"/projects/{projectId}/uploads/multipart/abort":{"post":{"consumes":["application/json"],"description":"Abort an in-progress multipart upload.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Multipart upload to abort","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.MultipartAbortInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Abort a multipart upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/multipart/complete":{"post":{"consumes":["application/json"],"description":"Complete a multipart upload by submitting the uploaded parts.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Multipart upload to complete","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.MultipartCompleteInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Complete a multipart upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/multipart/initiate":{"post":{"consumes":["application/json"],"description":"For large files: register the file and get presigned URLs for each part, PUT the parts, then call the multipart complete endpoint with their ETags. media_id and file_hash are optional for API keys (see the create upload endpoint); the response carries the media_id.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Multipart upload to initiate","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.MultipartInitInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.MultipartInit"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Initiate a multipart upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/{mediaId}":{"delete":{"description":"Delete a project upload by its media ID.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Media ID of the upload to delete","in":"path","name":"mediaId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Delete an upload","tags":["Uploads"]}},"/projects/{projectId}/uploads/{mediaId}/status":{"get":{"description":"Progress of a project upload: uploading (direct upload still receiving parts; received_bytes counts them), importing (a URL import still downloading), complete, or failed (error says why).","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Media ID","in":"path","name":"mediaId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.UploadStatusView"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get an upload's status","tags":["Uploads"]}},"/projects/{projectId}/uploads/{uploadId}/complete":{"post":{"description":"Mark a single upload as completed by its ID once the bytes have been PUT to the presigned URL. Returns the completed upload, including the media_id to use as the `media` reference of AI actions.","parameters":[{"description":"Project ID","in":"path","name":"projectId","required":true,"type":"string"},{"description":"Upload ID","in":"path","name":"uploadId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Upload"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Complete an upload","tags":["Uploads"]}},"/social/accounts":{"get":{"description":"Social accounts connected to the workspace. Connect them in the Rendley app (Social media); use their ids as account_ids when creating a post.","parameters":[{"description":"Workspace ID","in":"query","name":"workspace_id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/social.SocialAccountResponse"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List connected social accounts","tags":["Social"]}},"/social/posts":{"get":{"description":"One page of the workspace's scheduled, published and failed posts, one per account, by publish time.","parameters":[{"description":"Workspace ID","format":"uuid","in":"query","name":"workspace_id","required":true,"type":"string"},{"description":"Scheduled includes posts being published; all statuses when empty","enum":["scheduled","published","failed"],"in":"query","name":"status","type":"string"},{"description":"Comma-separated platform:username channels; all when empty","in":"query","name":"channels","type":"string"},{"default":"newest","description":"By publish time","enum":["newest","oldest"],"in":"query","name":"order","type":"string"},{"default":1,"description":"Page number","in":"query","minimum":1,"name":"page","type":"integer"},{"default":25,"description":"Results per page","in":"query","maximum":500,"minimum":1,"name":"limit","type":"integer"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/social.SocialPostResponse"},"type":"array"},"meta":{"$ref":"#/definitions/types.PageMeta"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List social posts","tags":["Social"]},"post":{"consumes":["application/json"],"description":"Posts a video or image to the given connected accounts now, or at scheduled_at. Creates one post per account. If some accounts fail after others went out, the call still succeeds and the failed ones come back with status failed and an error, so retrying never posts twice. media_url can be any public HTTPS link to the file, for example a Rendley export URL: posting now hands the link to Post for Me as is; a scheduled post copies the file first, so the link may expire before the scheduled time. Requires a plan with social publishing.","parameters":[{"description":"Post to create","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/social.CreatePostDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/social.SocialPostResponse"},"type":"array"}},"type":"object"}]}},"400":{"description":"VALIDATION_ERROR (caption over a platform's limit, scheduled_at in the past), INVALID_MEDIA_URL, SOCIAL_POST_REJECTED","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"SUBSCRIPTION_REQUIRED","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"PROJECT_NOT_FOUND, or an account id not connected to the workspace","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Publish or schedule a post","tags":["Social"]}},"/social/posts/{id}":{"delete":{"description":"Cancels a post that hasn't started publishing, or hides a failed one. Only its author or the workspace owner can.","parameters":[{"description":"Post ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"FORBIDDEN","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}},"409":{"description":"POST_NOT_SCHEDULED","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Cancel a scheduled post","tags":["Social"]},"put":{"consumes":["application/json"],"description":"Changes the time, caption or platform settings of a post that hasn't started publishing. Only its author or the workspace owner can.","parameters":[{"description":"Post ID","in":"path","name":"id","required":true,"type":"string"},{"description":"Fields to change","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/social.UpdatePostDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/social.SocialPostResponse"}},"type":"object"}]}},"400":{"description":"VALIDATION_ERROR","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"FORBIDDEN","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}},"409":{"description":"POST_NOT_SCHEDULED, ACCOUNT_DISCONNECTED, ACCOUNT_RECONNECT_REQUIRED","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Update a scheduled post","tags":["Social"]}},"/templates":{"get":{"description":"Without workspace_id: the published Rendley templates, paginated, with optional search and category filtering. With workspace_id (signed in): the user templates saved in that workspace, newest first; source_project_id is set while that project exists. There, query/category_id are ignored.","parameters":[{"description":"Workspace whose user templates to list","in":"query","name":"workspace_id","type":"string"},{"description":"With workspace_id: only the user template saved from this project","in":"query","name":"source_project_id","type":"string"},{"description":"Page number","in":"query","name":"page","type":"string"},{"description":"Results per page. With workspace_id: 1-500, default 50.","in":"query","name":"limit","type":"string"},{"description":"Search query (Rendley templates)","in":"query","name":"query","type":"string"},{"description":"Category ID filter (Rendley templates)","in":"query","name":"category_id","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.Template"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"summary":"List templates","tags":["Templates"]}},"/templates/categories":{"get":{"description":"Retrieve all available template categories.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/template.TemplateCategory"},"type":"array"}},"type":"object"}]}}},"summary":"List template categories","tags":["Templates"]}},"/templates/overview":{"get":{"description":"Retrieve an overview of Rendley templates grouped by category.","parameters":[{"description":"Number of templates per category","in":"query","name":"limit","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/template.GetOverviewFromTemplatesRow"},"type":"array"}},"type":"object"}]}}},"summary":"Get templates overview","tags":["Templates"]}},"/templates/{id}":{"delete":{"description":"Delete the user template and its files. Only its author or the workspace owner can. Its source project and projects started from it are not affected. Rendley templates can't be deleted here.","parameters":[{"description":"Template ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"NOT_FOUND","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Delete a user template","tags":["Templates"]},"get":{"description":"A Rendley template with its document, or (signed in) a user template with the fields it exposes and their current values. Rendley templates have no fields. Pass values to POST /projects as `fields`, keyed by each field's key. A media field takes a public https URL of a file of its media_kind.","parameters":[{"description":"Template ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Template"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"TEMPLATE_NOT_FOUND","schema":{"$ref":"#/definitions/http_response.Response"}}},"summary":"Get a template","tags":["Templates"]}},"/users/me":{"get":{"description":"Get the authenticated user's profile, credits, subscription and usage.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.CurrentUser"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get current user","tags":["Users"]}},"/workspaces":{"get":{"description":"List all workspaces belonging to the authenticated user.","produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"items":{"$ref":"#/definitions/types.Workspace"},"type":"array"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List workspaces","tags":["Workspaces"]},"post":{"consumes":["application/json"],"description":"Create a new workspace for the authenticated user.","parameters":[{"description":"Workspace to create","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.CreateWorkspaceInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Workspace"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Create a workspace","tags":["Workspaces"]}},"/workspaces/{id}":{"delete":{"description":"Delete a workspace and all of its contents (projects, brand kit, etc.). Only the\nworkspace owner can do this, and the user's last remaining workspace can't be deleted.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Delete a workspace","tags":["Workspaces"]},"get":{"description":"Returns a single workspace the authenticated user has access to. Used to load a\nspecific (e.g. last-opened) workspace at startup rather than defaulting to the first.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Workspace"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Get a workspace","tags":["Workspaces"]},"put":{"consumes":["application/json"],"description":"Update a workspace's name. Only the workspace owner can do this.","parameters":[{"description":"Workspace ID","in":"path","name":"id","required":true,"type":"string"},{"description":"New workspace name","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/workspace.UpdateWorkspaceDTO"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Workspace"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"403":{"description":"Forbidden","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Rename a workspace","tags":["Workspaces"]}},"/workspaces/{workspaceId}/library":{"get":{"description":"One page of the workspace's shared Library, newest first. Each item carries a presigned GET URL that expires — never persist it.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Page size (default 50, max 500)","in":"query","name":"limit","type":"integer"},{"description":"Page offset","in":"query","name":"offset","type":"integer"},{"description":"Match against file name and tags (case-insensitive substring)","in":"query","name":"search","type":"string"},{"description":"Comma-separated type buckets: video,audio,image,gif,other","in":"query","name":"kinds","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUploadList"}},"type":"object"}]}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"List workspace Library assets","tags":["Library"]},"post":{"consumes":["application/octet-stream"],"description":"Single-call upload: stream the raw file bytes as the request body. The server hashes while storing and returns the completed asset — no separate complete step. Metadata travels in query params. Content-Length is required; files above the proxy cap must use the multipart flow. If identical content already exists in the Library the existing asset is returned with deduplicated=true.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Original file name","in":"query","name":"file_name","type":"string"},{"description":"MIME type of the file","in":"query","name":"mime_type","type":"string"},{"description":"Media duration in seconds","in":"query","name":"duration","type":"number"},{"description":"Client-computed content hash (XXH3-64, 16 hex chars) for instant dedup","in":"query","name":"file_hash","type":"string"},{"description":"Provenance: uploaded (default) or export","in":"query","name":"source","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"413":{"description":"Request Entity Too Large","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Upload a file into the workspace Library (proxy transport)","tags":["Library"]}},"/workspaces/{workspaceId}/library/chunked/initiate":{"post":{"consumes":["application/json"],"description":"Hashless large-file transport for API/MCP clients that cannot compute the content hash: parts are PUT to the API strictly in order, the server hashes them incrementally while forwarding to storage, and the hash exists at complete — computed server-side. Files under the proxy cap should use the single-call proxy upload instead.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Chunked upload to initiate","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryChunkedInitInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryChunkedInit"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Start a chunked server-hashed Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/chunked/{uploadId}/abort":{"post":{"description":"Discards the in-progress session, its stored parts, and the pending asset row.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library upload ID","in":"path","name":"uploadId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Abort a chunked server-hashed Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/chunked/{uploadId}/complete":{"post":{"description":"Assembles the parts and finalizes the asset with the server-computed hash. Requires every declared byte to have arrived. Dedup-aware: identical existing content is returned with deduplicated=true.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library upload ID","in":"path","name":"uploadId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Complete a chunked server-hashed Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/chunked/{uploadId}/parts/{partNumber}":{"put":{"consumes":["application/octet-stream"],"description":"Raw part bytes as the request body. Parts must be sent strictly in order (409 CHUNK_OUT_OF_ORDER carries the expected part number); only the final part may be under the minimum part size. Content-Length is required.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library upload ID","in":"path","name":"uploadId","required":true,"type":"string"},{"description":"1-based part number","in":"path","name":"partNumber","required":true,"type":"integer"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryChunkedPartResult"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"409":{"description":"Conflict","schema":{"$ref":"#/definitions/http_response.Response"}},"413":{"description":"Request Entity Too Large","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Upload one part of a chunked Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/from-project":{"post":{"consumes":["application/json"],"description":"Copies the media (resolved by project ID + content hash) into the Library server-side — no bytes transit the client. Returns the existing asset with deduplicated=true when identical content is already in the Library.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Project media to promote","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryPromoteInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Add a project's media file to the workspace Library","tags":["Library"]}},"/workspaces/{workspaceId}/library/multipart/abort":{"post":{"consumes":["application/json"],"description":"Discard an in-progress multipart upload and its pending asset row.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Upload to abort","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.MultipartAbortInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Abort a chunked Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/multipart/complete":{"post":{"consumes":["application/json"],"description":"Assemble the uploaded parts into the final object and mark the asset complete. Quota is charged from the size the bucket actually stored.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Parts to assemble","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.MultipartCompleteInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Complete a chunked Library upload","tags":["Library"]}},"/workspaces/{workspaceId}/library/multipart/initiate":{"post":{"consumes":["application/json"],"description":"For files above the proxy cap: records a pending asset and returns presigned part URLs pointing straight at object storage. Finish with the multipart complete call. When identical content already exists in the Library the response carries `existing` (deduplicated=true) instead of an upload session — skip the transfer.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Multipart upload to initiate","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryMultipartInitInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryMultipartInit"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Start a chunked Library upload (large-file transport)","tags":["Library"]}},"/workspaces/{workspaceId}/library/transient":{"post":{"consumes":["application/octet-stream"],"description":"Stream raw file bytes to be used as an AI job input without adding them to the Library: the file is never listed as an asset, charges no storage, and is removed by the daily stale-upload sweep. Reference it in the job's params by the returned id only. Content-Length is required.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"MIME type of the file","in":"query","name":"mime_type","type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"413":{"description":"Request Entity Too Large","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Upload scratch input for an AI job","tags":["Library"]}},"/workspaces/{workspaceId}/library/{uploadId}":{"delete":{"description":"Remove the asset and refund its storage. Does not touch any project copies bridged from it.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library upload ID","in":"path","name":"uploadId","required":true,"type":"string"}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Delete a workspace Library asset","tags":["Library"]},"patch":{"consumes":["application/json"],"description":"Update the asset's display name.","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library asset ID","in":"path","name":"uploadId","required":true,"type":"string"},{"description":"New name","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryRenameInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Rename a workspace Library asset","tags":["Library"]}},"/workspaces/{workspaceId}/library/{uploadId}/add-to-project":{"post":{"consumes":["application/json"],"description":"Server-side copy of the asset into the project's media storage plus a role=staged upload row — the editor adopts it on reference instead of re-uploading bytes. Returns the project-side upload (media_id, file_hash, presigned URL).","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library upload ID","in":"path","name":"uploadId","required":true,"type":"string"},{"description":"Target project","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryAddToProjectInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.Upload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Bridge a Library asset into a project","tags":["Library"]}},"/workspaces/{workspaceId}/library/{uploadId}/tags":{"patch":{"consumes":["application/json"],"description":"Replace the asset's tag set (used to classify library media).","parameters":[{"description":"Workspace ID","in":"path","name":"workspaceId","required":true,"type":"string"},{"description":"Library asset ID","in":"path","name":"uploadId","required":true,"type":"string"},{"description":"New tag set","in":"body","name":"body","required":true,"schema":{"$ref":"#/definitions/types.LibraryTagsInput"}}],"produces":["application/json"],"responses":{"200":{"description":"OK","schema":{"allOf":[{"$ref":"#/definitions/http_response.Response"},{"properties":{"data":{"$ref":"#/definitions/types.LibraryUpload"}},"type":"object"}]}},"400":{"description":"Bad Request","schema":{"$ref":"#/definitions/http_response.Response"}},"401":{"description":"Unauthorized","schema":{"$ref":"#/definitions/http_response.Response"}},"404":{"description":"Not Found","schema":{"$ref":"#/definitions/http_response.Response"}}},"security":[{"BearerAuth":[]}],"summary":"Update a workspace Library asset's tags","tags":["Library"]}}},"schemes":["https"],"securityDefinitions":{"BearerAuth":{"description":"API key sent as \"Bearer \u003cyour-api-key\u003e\".","in":"header","name":"Authorization","type":"apiKey"}},"swagger":"2.0"}
