studio / N8N_ENDPOINTS.md
Ava2lon's picture
Upload 213 files
99d5f49 verified
|
Raw
History Blame Contribute Delete
25.2 kB

Unified Media Studio API for n8n

This reference describes every business API endpoint exposed by the unified Space and how to call it with n8n's HTTP Request node.

Base URL

Store the deployed Space URL in an n8n variable:

STUDIO_BASE_URL=https://<space-subdomain>.hf.space

Use this expression in HTTP Request nodes:

{{ $vars.STUDIO_BASE_URL }}/health

Do not add a trailing slash to STUDIO_BASE_URL.

Standard HTTP Request Node Settings

JSON request

  • Method: Use the method in the endpoint tables.
  • URL: {{ $vars.STUDIO_BASE_URL }}<path>
  • Send Body: On
  • Body Content Type: JSON
  • Specify Body: Using JSON
  • Response Format: JSON

For routes marked API key, add a Header Auth credential or enable Send Headers:

X-API-Key: <AVA2LON_API_KEY value>

The header is only enforced when AVA2LON_API_KEY or BASYX_API_KEY is set in the Space environment.

Query parameters

  • Enable Send Query Parameters.
  • Add each query parameter shown in the endpoint table.
  • Do not place simple query parameters in the JSON body.

Multipart file upload

  • Send Body: On
  • Body Content Type: Form-Data
  • For text fields, select Parameter Type: Form Data.
  • For files, select Parameter Type: n8n Binary File.
  • Set Name to the API field name, usually file or files.
  • Set Input Data Field Name to the incoming n8n binary field, commonly data.

Add another files parameter for every additional binary file.

File download response

For endpoints marked File response:

  • Set Response Format to File.
  • Set Put Output in Field to data.
  • The following n8n node can read the output from $binary.data.

Asynchronous job workflow

Most renderer operations return:

{
  "job_id": "job_123",
  "status_url": "/status/job_123",
  "download_url": "/download/job_123?token=..."
}

Recommended n8n flow:

  1. HTTP Request submits the job.
  2. Wait node pauses for several seconds.
  3. HTTP Request calls {{ $vars.STUDIO_BASE_URL }}{{ $json.status_url }}.
  4. IF node checks whether state equals COMPLETED, FAILED, or CANCELLED.
  5. Loop through Wait while the state is PENDING or RUNNING.
  6. Download using the original submission node's download_url.

For payloads with callback_url, use an n8n Webhook node's production URL to avoid polling.

Render callbacks use render.completed, render.failed, and render.cancelled; toolkit and analysis callbacks use task.*. The event is available in both the JSON event property and X-Ava2lon-Event header.

Root and Discovery

Method Path n8n input Response
GET / None Redirects to /dashboard; use only for browser access.
GET /apps None JSON map of mounted applications and MCP tool count.

Renderer Discovery and Monitoring

These routes use the root base URL.

Method Path n8n input Response
GET /health None Renderer health.
GET /healthz None Health-check alias for hosting probes.
GET /monitor None Runtime, queue, storage, and capability summary.
GET /queue None Job queue summary.
GET /workers None Worker and runtime settings.
GET /presets None Presets, templates, styles, transitions, and task IDs.
GET /platforms None Platform profile metadata.
GET /toolkit/tasks None Renderer toolkit task names.
GET /capabilities None Complete capability catalog.
GET /effects None Effects catalog.
GET /filters None Filter catalog.
GET /transitions None Transition catalog.
GET /templates/catalog None Templates, presets, and styles.
GET /projects None List saved projects.

Projects and Timeline

Method Path n8n input Auth Response
POST /projects JSON ProjectPayload API key Created project.
POST /project/create JSON ProjectPayload API key Alias of /projects.
GET /project/{project_id} Replace {project_id} None Project JSON.
POST /project/save JSON ProjectSavePayload API key Saved project.
POST /project/assets/add JSON ProjectAssetPayload API key Updated project.
POST /timeline/add JSON TimelineAddPayload API key Updated project.
POST /timeline/operation JSON TimelineOperationPayload API key Updated project.
POST /timeline/split JSON TimelineOperationPayload API key Runs split.
POST /timeline/trim JSON TimelineOperationPayload API key Runs trim.
POST /timeline/ripple-delete JSON TimelineOperationPayload API key Runs ripple_delete.
POST /timeline/insert JSON TimelineOperationPayload API key Runs insert.
POST /timeline/replace JSON TimelineOperationPayload API key Runs replace.
POST /timeline/group JSON TimelineOperationPayload API key Runs group.
POST /timeline/lock JSON TimelineOperationPayload API key Runs lock.
POST /timeline/hide JSON TimelineOperationPayload API key Runs hide.
POST /timeline/duplicate JSON TimelineOperationPayload API key Runs duplicate.
POST /effect/apply JSON EffectApplyPayload API key Updated project or asynchronous job.
POST /filter/apply JSON FilterApplyPayload API key Updated project or asynchronous job.
POST /transition/add JSON TransitionAddPayload API key Updated project or asynchronous job.
POST /keyframe/add JSON KeyframePayload API key Updated project.

Example project creation:

{
  "name": "Campaign 01",
  "metadata": {
    "platform": "tiktok",
    "creative_style": "high_energy"
  },
  "export_settings": {
    "platform": "tiktok"
  }
}

AI and Generation

All routes in this table return asynchronous job information.

Method Path n8n input Auth
POST /caption/generate JSON CaptionGeneratePayload API key
POST /music/generate JSON GenerationPayload API key
POST /voice/generate JSON GenerationPayload API key
POST /image/generate JSON GenerationPayload API key
POST /video/generate JSON GenerationPayload API key
POST /ai/{tool} Replace {tool}; JSON AIToolPayload API key
POST /assistant/{tool} Replace {tool}; JSON AIToolPayload API key

Example:

{
  "prompt": "Upbeat cinematic background music",
  "provider": "local",
  "callback_url": "https://n8n.example/webhook/studio-complete",
  "params": {
    "duration": 20
  }
}

Rendering and Uploads

Method Path n8n input Auth Response
POST /render JSON RenderPayload or AIReelsPayload None Async job.
POST /render/variants JSON RenderVariantsPayload None Render group plus child jobs.
POST /render/template JSON TemplateRenderPayload None Async job.
POST /render/ai-reels JSON AIReelsPayload None Async job.
POST /render/batch JSON BatchPayload None Array of job IDs.
POST /automation/batch JSON BatchPayload API key Array of job IDs.
POST /project/{project_id}/render Replace {project_id}; JSON ProjectRenderPayload API key Async job.
POST /render/upload Multipart request_json plus zero or more files None Async job.
POST /render/ai-reels/upload Multipart request_json plus zero or more files None Async job.
POST /assets/upload Multipart; one or more files None Uploaded asset references.
POST /upload Multipart files; optional expand_zip None Uploaded or expanded assets.
GET /render/groups/{group_id} Replace {group_id} None Aggregate state and child jobs.
GET /templates/automation None None Data-driven render templates.

Basic render body:

{
  "scenes": [
    {
      "start": 0,
      "duration": 5,
      "media": "https://example.com/video.mp4",
      "caption": "Opening hook",
      "transition": "fade",
      "background": "blur",
      "layout": "fill"
    }
  ],
  "output_name": "campaign.mp4",
  "template": "tiktok_classic",
  "auto_subtitles": true,
  "subtitle_language": "en"
}

For /render/upload, configure n8n Form-Data as:

Parameter Type Name Value
Form Data request_json JSON string shown below
n8n Binary File files Input Data Field Name such as data
{
  "scenes": [
    {
      "start": 0,
      "duration": 5,
      "media": "upload://clip.mp4",
      "caption": "Uploaded clip"
    }
  ],
  "output_name": "render.mp4"
}

The filename in upload://clip.mp4 must match the uploaded binary filename.

Render several platform outputs from one timeline with /render/variants:

{
  "scenes": [{"start": 0, "duration": 12, "media": "https://example.com/input.mp4"}],
  "callback_url": "https://n8n.example/webhook/render-events",
  "variants": [
    {"name": "shorts", "platform": "youtube_shorts", "output_name": "shorts.mp4"},
    {"name": "reels", "platform": "instagram_reels", "output_name": "reels.mp4"},
    {"name": "youtube", "platform": "youtube_1080p", "output_name": "youtube.mp4"}
  ]
}

Use /render/template for spreadsheet, CRM, and database-driven renders. An exact placeholder preserves arrays, objects, numbers, and booleans instead of converting them to strings.

{
  "template": "vertical-captioned-clip",
  "variables": {
    "output_name": "customer-42.mp4",
    "scenes": [{"start": 0, "duration": 8, "media": "https://example.com/42.mp4"}],
    "voiceover": null,
    "background_music": null
  }
}

Platform Processing and Toolkit

All routes in this table require X-API-Key and return asynchronous job information.

Method Path n8n input
POST /ingest JSON IngestPayload
POST /analyze JSON AnalyzePayload
POST /clips JSON ClipsPayload
POST /thumbnail JSON ThumbnailPayload
POST /thumbnail/create JSON ThumbnailPayload
POST /metadata JSON MetadataPayload
POST /publish JSON PublishPayload
POST /toolkit JSON ToolkitPayload
POST /edit JSON ToolkitPayload; alias of /toolkit

Toolkit example:

{
  "task": "compress",
  "media": "https://example.com/input.mp4",
  "output_name": "compressed.mp4",
  "params": {
    "crf": 28,
    "resolution": "720p"
  }
}

FFmpeg automation tasks added for n8n:

Task Important params Download artifact
inspect None FFprobe metadata JSON
loudness_analyze target_lufs LUFS/LRA/true-peak JSON
silence_detect noise_db, duration_seconds Timed silence events JSON
black_detect pixel_threshold, duration_seconds Timed black-frame events JSON
scene_detect threshold Scene-change timestamps JSON
contact_sheet columns, rows, interval_seconds, thumbnail_width JPEG/PNG
hls segment_seconds, playlist_type, crf ZIP with M3U8 and TS segments

All use the normal POST /toolkit body with task, media, optional params, and optional callback_url.

Transcription, Subtitles, Jobs, and Downloads

Method Path n8n input Response
POST /transcribe JSON TranscribePayload Transcription JSON.
POST /subtitles JSON SubtitlePayload File response (.srt or .ass).
POST /scene-builder JSON SceneBuildPayload Generated scene array.
POST /transcribe/upload Multipart file plus optional transcription fields Transcription JSON.
GET /status Optional query job_id Service status without job_id; job record with it.
GET /status/{job_id} Replace {job_id} Job record.
POST /cancel/{job_id} Replace {job_id} Updated job record.
POST /admin/cleanup Optional query older_than_seconds Cleanup counts.
GET /download Query job_id; optional token File response.
GET /download/{job_id} Replace {job_id}; optional query token File response.
POST /inspect Query path Media metadata JSON.
POST /media/inspect JSON { "media": "...", "callback_url": "..." } Async remote-safe inspection.

Transcription body:

{
  "audio": "https://example.com/audio.mp3",
  "model_size": "tiny",
  "language": "en",
  "task": "transcribe",
  "beam_size": 5,
  "vad_filter": true,
  "word_timestamps": true
}

Subtitle body:

{
  "events": [
    {
      "start": 0,
      "end": 2.5,
      "text": "Opening caption"
    }
  ],
  "format": "srt",
  "template": "tiktok_classic"
}

Kokoro TTS

Method Path n8n input Response
POST /tts/v1/audio/speech JSON shown below WAV file response.

Set the HTTP Request node's response format to File.

{
  "input": "This is generated speech.",
  "voice": "af_bella.pt",
  "model": "kokoro-v0_19.onnx",
  "speed": 1.0
}

voice and model are optional; the server uses its first configured voice and model when omitted.

MusicGen

Method Path n8n input Response
GET /music/health None Health JSON.
POST /music/generate Query prompt; optional query duration WAV file response.

For generation:

  • Method: POST
  • URL: {{ $vars.STUDIO_BASE_URL }}/music/generate
  • Send Query Parameters: On
  • prompt: Soft cinematic instrumental
  • duration: 10
  • Response Format: File

Whisper Operator

Method Path n8n input Response
POST /whisper/execute/{task_name} Multipart file or URL fields JSON or file response.
GET /whisper/api/health None Health JSON.
GET /whisper/api/status/{job_id} Replace {job_id} Whisper queue status.

Use one of these multipart inputs for /whisper/execute/{task_name}:

  • file: n8n Binary File.
  • url_input: downloadable media URL.
  • source: alternative media URL.
  • webhook: optional callback URL.

Supported task names:

autonomous
auto-publish
publish
bulk-publish
generate-metadata
generate-thumbnail
schedule-post
transcribe
subtitles
render
highlights
clips
viral-score
strategy
batch

FFmpeg Editor

Method Path n8n input Response
GET /editor/healthz None Health and dependency checks.
GET /editor/readyz None Readiness; returns 503 when dependencies fail.
GET /editor/tasks None Editor task registry.
POST /editor/n8n/execute/{task_id} JSON, multipart, or raw binary Synchronous file response.
POST /editor/n8n/jobs/{task_id} JSON, multipart, or raw binary Background job JSON.
POST /editor/execute/{task_id} Multipart fields Synchronous file response.
POST /editor/jobs/{task_id} Multipart fields Background job JSON.
GET /editor/status/{job_id} Replace {job_id} Background job status.
GET /editor/download/{job_id} Replace {job_id} File response.
GET /editor/history None Recent output metadata.
GET /editor/history/{history_id}/download Replace {history_id} File response.

Recommended editor request for n8n

Use /editor/n8n/jobs/{task_id} for long-running jobs.

Multipart request:

  • Add one or more n8n Binary File parameters. The field name may be files.
  • Add text options as Form Data.
  • A URL may use url, urls, file_url, source_url, or download_url.

JSON request:

{
  "url": "https://example.com/input.mp4",
  "options": {
    "resolution": "720p",
    "crf": "28",
    "preset": "medium",
    "text": "Caption text"
  }
}

Raw binary request:

  • Body Content Type: n8n Binary File
  • Input Data Field Name: data
  • Add header X-Filename: input.mp4
  • Put editor options in query parameters.

Available editor option fields:

text
start_time
end_time
duration
aspect_ratio
resolution
crf
preset
audio_bitrate
volume
position
opacity
fps
width
speed
timestamp
image_duration
frame_rate
font_size
wave_color

Editor task IDs

Use one value below as {task_id}:

Task ID Purpose Files
normalize Convert to H.264/AAC MP4 1 video
extract_audio Export MP3 audio 1 video/audio
resize_916 Crop to vertical 9:16 1 video
add_subtitles Burn SRT/ASS subtitles video + subtitle
burn_lyrics Burn styled lyrics video + subtitle
text_overlay Add caption text 1 video
merge_music Add background music video + audio
thumbnail Export JPG frame 1 video
watermark Overlay logo/image video + image
compress Reduce video size 1 video
batch_compress Compress videos into ZIP 1+ videos
make_gif Create GIF 1 video
tiktok_lyrics Vertical lyric clip 1 video
tiktok_pro_reframer Vertical reframe and style 1 video
reels_blur_fit Blurred 9:16 fit 1 video
reels_safe_caption Mobile-safe caption 1 video
reels_hook_title Top hook/title 1 video
reels_progress_bar Progress bar and trim 1 video
reels_loop Loop to target duration 1 video
reels_subtitle_safe Mobile-safe subtitles video + subtitle
reels_reaction_stack Stack reaction videos 2 videos
reels_audio_duck Duck music below video video + audio
faceless_quote_card Text-only quote short no file
faceless_story_pages Timed text story slides no file
faceless_image_narration Image with narration image + audio
faceless_video_narration B-roll with narration video + audio
faceless_broll_montage Silent b-roll montage 2+ videos
series_split_pack Split long video into series ZIP 1 video
series_episode_badge Add episode badge 1 video
series_batch_pack Package clips as numbered series 2+ videos
series_recap_card Text-only recap card no file
concat Join clips 2+ videos
slideshow Build video from images 2+ images
trim Cut by start/end 1 video/audio
crop_aspect Crop to target aspect ratio 1 video
waveform Create waveform video 1 audio/video
extract_frames Export frames as ZIP 1 video
add_intro_outro Join intro/main/outro 2-3 videos
speed Change playback speed 1 video
remove_audio Remove video audio 1 video
replace_audio Replace video audio video + audio

JSON Payload Reference

Fields marked * are required.

Rendering

ScenePayload

start*: number >= 0
duration*: number > 0
media*: string path or URL
caption: string
transition: string = "fade"
background: string = "blur"
layout: string = "fill"
effect: string | null

RenderPayload

scenes*: ScenePayload[]
template: string = "tiktok_classic"
preset, creative_style, platform: string | null
output_name: string = "render.mp4"
voiceover, background_music: string | null
music_volume: number = 0.316
music_fade_in, music_fade_out, music_start: number = 0
music_loop, music_ducking: boolean = true
voice_volume: number = 1
subtitle_format: string = "ass"
auto_subtitles: boolean = false
subtitle_language, whisper_model_size: string | null
preview, audio_normalize: boolean = false
watermark, intro, outro: string | null
watermark_position: string = "bottom-right"
callback_url, export_target: string | null
priority: integer = 0
scheduled_at: number | null
normalize: boolean = true
metadata: object = {}

AIReelsPayload

script*: string
voiceover*: string
assets*: string[]
template: string = "tiktok_classic"
creative_style, platform: string | null
output_name: string = "ai_reel.mp4"
background_music: string | null
music_volume: number = 0.316
music_fade_in, music_fade_out, music_start: number = 0
music_loop, music_ducking: boolean = true
voice_volume: number = 1
callback_url, export_target: string | null

BatchPayload

jobs*: RenderPayload[]

ProjectRenderPayload

output_name: string = "project_render.mp4"
template, preset, creative_style, platform: string | null
callback_url, export_target: string | null
preview: boolean = false
normalize: boolean = true
metadata: object = {}

Projects and Editing

ProjectPayload

name*: string
metadata: object = {}
export_settings: object = {}
template: object | null

ProjectSavePayload

project_id: string | null
project*: object

ProjectAssetPayload

project_id*: string
asset*: object

TimelineAddPayload

project_id*: string
track_type: string = "video"
track_id: string | null
item: object = {}

TimelineOperationPayload

project_id*: string
operation: string = "drag"
item_id: string | null
params: object = {}

EffectApplyPayload

project_id, target_id, item_id: string | null
effect*: string
params: object = {}
callback_url: string | null

FilterApplyPayload

project_id, target_id, item_id: string | null
filter*: string
params: object = {}
lut: string | null
callback_url: string | null

TransitionAddPayload

project_id, from_item_id, to_item_id, target_id: string | null
transition*: string
duration: number = 0.45
params: object = {}
callback_url: string | null

KeyframePayload

project_id*: string
target_id*: string
property*: string
time*: number >= 0
value*: any JSON value
easing: string = "linear"

Generation and Platform Tools

GenerationPayload

prompt, text, media, provider: string | null
callback_url, export_target: string | null
params: object = {}
additional JSON fields are accepted

CaptionGeneratePayload

media, audio, text, transcript: string | null
events: object[] | null
template: string = "capcut"
language: string | null
engine: string = "whisper"
word_timestamps: boolean = true
emoji_insertion, speaker_detection: boolean = false
karaoke, animated: boolean = true
callback_url: string | null
additional JSON fields are accepted

AIToolPayload

project_id, media, transcript, text, platform: string | null
callback_url: string | null
params: object = {}
additional JSON fields are accepted

IngestPayload

sources*: [{ "url": string, "type": string|null, "name": string|null }]
callback_url: string | null

AnalyzePayload

media*: string
transcript: string = ""
platform, callback_url: string | null

ClipsPayload

media*: string
clips: object[] | null
callback_url: string | null

ThumbnailPayload

media*: string
text: string = ""
timestamp: number | null
template: string = "bold"
callback_url: string | null

MetadataPayload

topic, transcript: string = ""
platform, callback_url: string | null

PublishPayload

media, asset, title, description: string | null
platforms: string[] = []
platform, scheduled_at: string | null
draft: boolean = true
callback_url: string | null

ToolkitPayload

task*: string
input, media, output_name: string | null
params: object = {}
callback_url, export_target: string | null
additional JSON fields are accepted

Transcription and Subtitles

TranscribePayload

audio*: string path or URL
model_size, language: string | null
task: string = "transcribe"
beam_size: integer = 5
vad_filter, word_timestamps: boolean = true

SubtitlePayload

events*: [{ "start": number, "end": number, "text": string }]
format: string = "srt"
template: string = "tiktok_classic"

SceneBuildPayload

script*: string
assets*: string[]
duration: number | null
transition: string = "fade"
creative_style: string | null

Framework and UI Endpoints

These are not business API operations:

Path Purpose
/dashboard Renderer Gradio interface.
/tts/ Kokoro TTS Gradio interface.
/music/ MusicGen Gradio interface.
/whisper/ Whisper Gradio interface.
/editor/ FFmpeg editor Gradio interface.
/mcp/ MCP Streamable HTTP transport; use an MCP client rather than a normal REST request.
/dashboard/gradio_api/mcp/ Gradio-native MCP transport for documented dashboard actions.
/mcp-health MCP transport discovery and custom tool count.
/docs Root FastAPI Swagger UI when ENABLE_API_DOCS=true.
/redoc Root FastAPI ReDoc UI when ENABLE_API_DOCS=true.
/openapi.json Root renderer OpenAPI schema when ENABLE_API_DOCS=true.
/<service>/docs Mounted service Swagger UI when ENABLE_API_DOCS=true.
/<service>/openapi.json Mounted service OpenAPI schema when ENABLE_API_DOCS=true.