Kinetune

Transformez des chansons en vidéos de paroles synchronisées (9:16, 16:9, 1:1) et en boucles Spotify Canvas. Téléchargez un morceau, parcourez les Looks, obtenez un devis de crédit exact, puis rendez et téléchargez.

Serveur MCP hébergé

npx add-mcp 'https://kinetune.com/mcp'

S’installe dans Claude Code, Codex, Cursor et plus

Documentation

Overview

One host serves everything, and every surface runs the same operations with the same validation and the same exact prices as the app.

Endpoints

REST API

https://kinetune.com/api/v1

MCP server

https://kinetune.com/mcp · Streamable HTTP

OpenAPI 3.1

https://kinetune.com/api/v1/openapi.json

OAuth discovery

https://kinetune.com/.well-known/oauth-authorization-server

How a video is made

  1. Add a song: the master audio and its square cover art. It is analyzed (lyrics, beats, sections) in about a minute.
  2. Quote the video you want. The quote is the exact number of credits; nothing is charged.
  3. Create it with the same request plus the quote_id. Credits are held, and charged only when the video is delivered.
  4. Wait for status: "completed": poll the video or receive a signed callback.
  5. Download the files: one MP4 per format, links valid for 7 days (ask again for fresh ones).

Quickstart

The same request three ways. Pick the one that matches where your code or agent runs.

Terminal

npm install -g @kinetune/cli
kinetune auth login                       # opens the browser to sign in

kinetune artists create --name "Nova Lane"
kinetune songs create --artist-id ARTIST_ID --title "Midnight Drive" \
  --audio ./midnight-drive.wav --cover-art ./cover.jpg
kinetune songs get SONG_ID                # wait for analysis.status "ready"

kinetune create canvas --song-id SONG_ID  # quotes, shows the credits, asks first
kinetune videos wait VIDEO_ID
kinetune videos download VIDEO_ID

Authentication

Two kinds of credentials, both sent as a Bearer token and both scoped to one organization.

API keys — servers, CI and n8n

Create one on the API page in the app (owners and admins). The secret is shown once; we store only an HMAC. Keys act for the organization and are limited by your plan.

Header

Authorization: Bearer kt_live_YOUR_KEY

Scopes

videos:read

See videos, quotes and your credit balance

videos:write

Quote, create, cancel, retry and delete videos (spends credits)

music:read

See artists, their photos and songs

music:write

Add, rename and archive artists and songs, upload songs and artist photos

library:read

Browse Looks

library:write

Rename, delete and publish your Looks

organizations:read

See the organizations you belong to

organizations:write

Create organizations you own

OAuth endpoints

Authorization server

https://kinetune.com/.well-known/oauth-authorization-server

MCP resource

https://kinetune.com/mcp · metadata at /.well-known/oauth-protected-resource/mcp

REST resource

https://kinetune.com/api/v1 · metadata at /.well-known/oauth-protected-resource/api/v1

Authorize · token

/api/auth/oauth2/authorize · /api/auth/oauth2/token

Send resource (RFC 8707) with the MCP or REST URL so the token's audience matches; unauthenticated calls answer 401 with a WWW-Authenticate header that points to the resource metadata.

MCP server

Remote agents use Kinetune through the Model Context Protocol: one tool per API operation, Streamable HTTP, sign-in with your account.

Server URL

https://kinetune.com/mcp

Also listed in the official MCP Registry (com.kinetune/kinetune), on Smithery, Glama, mcp.so, Cursor Directory and mcpservers.org.

  1. In ChatGPT, open Settings → Apps & Connectors → Advanced and turn on Developer mode (it depends on your plan and workspace settings).
  2. Choose Create, name it Kinetune, paste the server URL and pick OAuth.
  3. Sign in, choose the organization and approve. Then enable it in a chat from the tools menu.

Tools

The server is stateless (JSON responses, protocol 2025-11-25). Tools that create videos spend credits, so agents are instructed to quote first and ask. wait_for_video waits up to 55 seconds per call.

ToolWhat it does
get_accountWho you are signed in as, the organization and its credit balance
get_optionsVideo types, Look categories, background sources, formats and the current credit prices
list_organizationsThe organizations you belong to, your role in each and the one these credentials act for
create_organizationA new organization owned by you, with its own music, videos, Looks and credits
list_artistsArtists by name, with their song and photo counts and a picture
create_artistAdd an artist by name
get_artistOne artist
rename_artistChange an artist’s name
archive_artist destructiveRemove an artist that has no songs
set_artist_pictureChoose which photo is the artist’s picture, and how it is cropped to a square
list_artist_photosThe artist’s photos (identity references, up to 6)
add_artist_photosUpload one or more photos of the artist (JPEG, PNG or WebP)
delete_artist_photo destructiveRemove one photo
list_songsSongs with their cover, duration and analysis status
create_songAdd a song: master audio and square cover art
get_songOne song and its analysis status
rename_songChange a song’s title
archive_song destructiveRemove a song (its videos stay)
get_song_analysisWord-timed lyrics, tempo, beats, sections and hook
reanalyze_songRetry a failed analysis
set_song_lyrics destructiveGive a song its own lyrics, or replace them
clear_song_lyrics destructiveGo back to the transcribed words
list_looksBrowse Official, Community and your own Looks
get_lookOne Look with its design and preview images
rename_lookRename one of your Looks
delete_look destructiveRemove one of your Looks (videos made with it stay)
set_look_visibilityMake one of your Looks public (earns 10 credits) or private
upload_backgroundUpload your own photo or video to design a New Look around
search_stockFind stock photos or clips to use as a background
quote_lyric_videoThe exact credits for a lyric video, before anything is charged
quote_canvasThe exact credits for a Spotify Canvas, before anything is charged
create_lyric_videoMake the lyric video a quote priced (spends credits)
create_canvasMake the Canvas a quote priced (spends credits)
list_videosVideos, newest first, with status and thumbnails
get_videoStatus, progress, credits and, when completed, the download links
cancel_video destructiveStop a queued or processing video (credits released)
retry_videoRun a finished, failed or cancelled video again (new charge)
delete_video destructiveDelete a finished video and its files
wait_for_videoWaits for a video to finish (up to 55 s per call), then returns it like get_video
show_looksShows Looks as a gallery to play and pick from (with a sample song, or the person's own with song_id)
show_songsShows songs with covers and analysis status, each offering a lyric video or a Canvas
show_videoShows videos as players that follow the render, with a download per format

Cards in chat apps

In apps that draw MCP Apps (ChatGPT, Claude, VS Code and others), results arrive as Kinetune cards instead of text: a gallery where each Look plays as the real render, the quote as an order ticket with a Make it button (tapping it is the go-ahead, and the card creates the videos), and the video as a player that follows the render and offers a download per format. The cards run in the app's sandbox, call the same tools, and load media only from Kinetune and its storage. Other clients get the same results as JSON.

Prompts and resources

Clients that show prompts as commands get three ready-made starts: make_lyric_video, make_canvas and browse_looks. Each one follows the quote-first workflow.

Read-only resources mirror the API reads: kinetune://account and kinetune://options, plus templates for kinetune://songs/{song_id}, …/analysis, kinetune://looks/{look_id}, kinetune://videos/{video_id} and kinetune://artists/{artist_id}, all returned as JSON.

CLI

kinetune runs every operation from the terminal. It prints JSON whenever its output is piped, so local agents and scripts read it directly.

Install (Node 20+)

npm install -g @kinetune/cli
# or without installing:
npx @kinetune/cli --help

Sign in

kinetune auth login                            # browser sign-in, picks the organization
kinetune auth login --api-key kt_live_YOUR_KEY  # or store an API key
kinetune auth status

Working with it

Commands follow the API: kinetune songs list --q "tide" --limit 20, kinetune looks get LOOK_ID, kinetune quote lyric-video --song-id SONG_ID. Path ids are arguments, fields are flags, and --input file.json (or - for stdin) takes the whole request. Files go up by path or https URL: --audio ./song.wav.

kinetune create … always quotes first and asks before charging; pass --yes or a ceiling with --max-credits 120 in scripts. kinetune videos wait and kinetune videos download finish the job.

Give a local agent (Codex, Cursor, opencode, Claude Code…) the Kinetune skill so it knows the workflow: npx skills add kinetune/skills. It's open source at kinetune/skills.

For agents

kinetune schema create canvas   # JSON Schema of a command's input
kinetune openapi                 # the whole API as OpenAPI 3.1
kinetune songs list --json       # JSON even in a terminal

Environment and exit codes

KINETUNE_API_KEY

An organization API key; wins over the stored sign-in (CI, servers).

KINETUNE_URL

Another deployment of the app (defaults to this site).

KINETUNE_CONFIG_DIR

Where credentials live; default ~/.config/kinetune (mode 600).

Exit codes

0 done · 1 API or network error · 2 invalid usage or over --max-credits · 3 not signed in or not allowed

REST API

JSON over HTTPS. Every request carries a Bearer credential; ids are prefixed strings; times are ISO 8601.

Basics

Base URL

https://kinetune.com/api/v1

Auth

Authorization: Bearer … — an API key or an OAuth access token

Uploads

multipart/form-data files, or JSON with public https URLs (audio_url, cover_art_url, photo_urls, file_url)

Song lyrics

A song’s words are transcribed from the audio, so one may be misheard. Give it its own lyrics as lyrics when you add it, or later with POST /songs/{id}/lyrics: plain text ([Verse] and [Chorus] tags are fine) or the contents of an SRT, WebVTT or LRC file. Every word is still timed from the audio; the text fixes the spelling and where lines break. Lyrics that don’t match what’s sung are refused (409) and nothing changes; DELETE goes back to the transcription. analysis.lyrics.status says whose words the videos show.

Your own background

POST /backgrounds takes your photo or video; a New Look with background.source upload-photo or upload-video and its upload_id is designed around it, with no media cost. Such a Look stays private.

Stock you choose

GET /stock?kind=photo&q=…&orientation=portrait searches stock photos or clips (24 a page; landscape when 16:9 is among the formats, seconds for a Canvas clip). A stock source with look.background.stock_id (or a Canvas’s stock_id) uses that item instead of the director’s pick, which drops the pick from the quote. Credit the photographer wherever you show an item.

Quotes

Valid for a limited time and once; create with the identical request plus quote_id. Re-sending the same quote returns the videos it already made.

Download links

Signed, valid 7 days; GET /videos/{id} returns fresh ones

Images

Kept at the sizes they're used at, not as uploaded: a song's cover_art.url (1536 px JPEG), preview_url (640 px) and thumbnail_url (160 px WebP); an artist photo's url (1536 px) and thumbnail_url; a Look's backgrounds.previews (480 px wide). Image links are signed for 7 days and stay the same all day, so they cache well.

Lyric styles

A New Look takes look.lyric_style: how the lyrics are presented and animated (block-stack, punch, player, neon, terminal …). GET /options lists them; leave it out and the director picks one. An Existing Look takes it too, to render the same design in another style at no extra cost. GET /looks?lyric_style= filters the Library.

Scenes

An AI image background can be 2–4 shots of the same world that cut on the song’s sections: look.background.scenes (1 by default). Each scene is priced like the first.

Quote a lyric video with a New Look in a lyric style

curl -s https://kinetune.com/api/v1/quotes -H "Authorization: Bearer $KINETUNE_API_KEY" \
  -H "content-type: application/json" -d '{
    "type": "lyric-video", "song_id": "SONG_ID", "aspect_ratios": ["9:16", "16:9"],
    "look": { "mode": "new", "category": "street", "lyric_style": "punch" }
  }'

Upload files (multipart)

curl -s https://kinetune.com/api/v1/songs -H "Authorization: Bearer $KINETUNE_API_KEY" \
  -F artist_id=ARTIST_ID -F title="Midnight Drive" \
  -F [email protected] -F [email protected]

Callbacks

Pass callback_url (https, public) with the quote and the create call, and the video is POSTed to you when it completes, fails or is cancelled.

Delivery

Body

The video, exactly as GET /videos/{id} returns it

Headers

Kinetune-Event (video.completed, video.failed, video.cancelled) · Kinetune-Delivery (unique id) · Kinetune-Signature

Retries

Any 2xx within 10 seconds counts. Otherwise it retries after 30 s, 2 min, 10 min, 30 min and 2 h.

Signing secret

On the API page in the app (whsec_…); rotate it there.

Verify Kinetune-Signature (Node)

import { createHmac, timingSafeEqual } from "node:crypto";

// header: "t=1760000000,v1=5f2c…"  body: the raw request body
export function verified(header, body, secret) {
  const { t, v1 } = Object.fromEntries(header.split(",").map(p => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // replay window
  const expected = createHmac("sha256", secret).update(\`${t}.${body}\`).digest("hex");
  return v1?.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Errors and limits

Errors are JSON: {"error": "…"} plus details where useful (field errors, required and available credits).

Status codes

400

Invalid request; details.fieldErrors names the fields.

401

Missing, invalid or expired credentials (OAuth clients refresh and retry).

402

Not enough credits: required and available tell you how many.

403

The credentials lack the scope, or the action is reserved to the app.

404

Not found in this organization.

409

A state conflict: the song is still being analyzed, or the quote expired, was used or no longer matches.

503

AI video is briefly unavailable on our side ("code": "AI_VIDEO_UNAVAILABLE"): nothing was held; try again after Retry-After seconds.

A failed video has error (a message to show) and error_code, and its credits are released. AI_VIDEO_UNAVAILABLE means its AI video couldn’t be made for a reason on our side, not the request’s: make it again later.

Concurrent renders are limited by your plan; extra videos wait in the queue.

n8n

The community node covers the same operations: songs, artists and photos, Looks, quotes, videos and downloads.

  1. In a self-hosted n8n, open Settings → Community nodes → Install and enter @kinetune/n8n-nodes-kinetune.
  2. Create a Kinetune API credential with an API key from the app; the base URL is https://kinetune.com.
  3. Pick artists and songs from a searchable list, or switch the field to By ID for an id or an expression. List Artists and List Songs search and page like the API.
  4. Quote, then create with the quote id. To continue when the video is ready, set its callback URL to an n8n Webhook node.

API reference

Every operation with its REST call, CLI command and MCP tool. Generated from the same definitions the API validates with.

Account

Get the account

GET /api/v1/account

Who you are signed in as, the organization and its credit balance. Returns the organization the credentials act for, how they authenticate and their scopes, the credit balance (available, monthly, top-ups) and its plan, if any (where it is billed, when the period ends, and a downgrade or interval switch waiting for the renewal as scheduled_change). Check it before creating videos.

CLI kinetune account MCP get_account Scopes videos:read or music:read or library:read

No parameters.

List the options

GET /api/v1/options

Video types, Look categories, background sources, formats and the current credit prices. Everything a request can choose from, with the credit table. Use it to pick a category or source and to explain prices.

CLI kinetune options MCP get_options Scopes videos:read or music:read or library:read

No parameters.

List your organizations

GET /api/v1/organizations

The organizations you belong to, your role in each and the one these credentials act for. Every organization the signed-in person is a member of; with an API key, the member who created it (the key needs organizations:read). current marks the organization these credentials act for. Each organization has its own music, videos, Looks and credits: to work in another one, sign in again and pick it on the consent screen, or use an API key created in it.

CLI kinetune organizations list MCP list_organizations Scopes organizations:read

No parameters.

Create an organization

POST /api/v1/organizations

A new organization owned by you, with its own music, videos, Looks and credits. Creates an empty organization with the signed-in person as its owner; with an API key, the member who created the key (the key needs organizations:write). It starts with no credits. These credentials keep acting for their current organization: to work in the new one, sign in again and pick it, or create an API key in it.

CLI kinetune organizations create MCP create_organization Scopes organizations:write

FieldTypeDescription
name body · requiredstringThe organization name, as people see it in the app

Artists and photos

List artists

GET /api/v1/artists

Artists by name, with their song and photo counts and a picture. Songs belong to an artist; create the artist first. Sorted by name, 50 per page by default: pass q to search by name, and limit/offset to page.

CLI kinetune artists list MCP list_artists Scopes music:read or videos:read

FieldTypeDescription
q querystringPart of the artist name
limit queryinteger 1–100Results per page, 1-100 (default 50)
offset queryinteger 0–9007199254740991How many results to skip

Create an artist

POST /api/v1/artists

Add an artist by name. Names are unique per organization (409 when taken).

CLI kinetune artists create MCP create_artist Scopes music:write or videos:write

FieldTypeDescription
name body · requiredstringThe artist name

Get an artist

GET /api/v1/artists/{artist_id}

One artist.

CLI kinetune artists get MCP get_artist Scopes music:read or videos:read

FieldTypeDescription
artist_id path · requiredstringThe artist id

Rename an artist

PATCH /api/v1/artists/{artist_id}

Change an artist’s name.

CLI kinetune artists rename MCP rename_artist Scopes music:write or videos:write

FieldTypeDescription
artist_id path · requiredstringThe artist id
name body · requiredstringThe new name

Archive an artist

DELETE /api/v1/artists/{artist_id}

Remove an artist that has no songs. Refused (409) while the artist still has songs.

CLI kinetune artists archive MCP archive_artist Scopes music:write or videos:write

FieldTypeDescription
artist_id path · requiredstringThe artist id

Set the artist picture

POST /api/v1/artists/{artist_id}/picture

Choose which photo is the artist’s picture, and how it is cropped to a square. The picture (image_url on the artist, a 512 px square) is cut from one of the artist’s photos; the photo itself is unchanged. The first photo becomes the picture automatically, centered. crop is in fractions of the photo (its url): x/y the top-left corner, size the side relative to the photo’s short side; leave it out to center.

CLI kinetune artists picture MCP set_artist_picture Scopes music:write or videos:write

FieldTypeDescription
artist_id path · requiredstringThe artist id
photo_id body · requiredstringOne of the artist’s photos (list_artist_photos)
crop bodyobjectThe square to keep, in fractions of the photo; centered when omitted

List artist photos

GET /api/v1/artists/{artist_id}/photos

The artist’s photos (identity references, up to 6). Photos keep the artist recognizable when a Look or Canvas shows them; the cover art stays the creative source. url is the photo upright at up to 1536 px (what the AI receives; width and height describe it), thumbnail_url a copy 320 px on its short side for grids.

CLI kinetune artists photos list MCP list_artist_photos Scopes music:read or videos:read

FieldTypeDescription
artist_id path · requiredstringThe artist id

Add artist photos

POST /api/v1/artists/{artist_id}/photos

Upload one or more photos of the artist (JPEG, PNG or WebP). Up to 6 per artist, at least 512 px on the short side, up to 15 MB each. Only with the rights to use them (rights_confirmed). They are identity references only: never shown publicly or used as they are. Each is kept upright at up to 1536 px, with a small thumbnail; the uploaded file itself is not kept.

CLI kinetune artists photos add MCP add_artist_photos Scopes music:write or videos:write

Files: photos (multipart) or photo_urls (JSON).

FieldTypeDescription
artist_id path · requiredstringThe artist id
photo_urls bodyURL[] (1–6)Public https URLs of the photos (or upload files with the CLI)
rights_confirmed body · requiredtrueYou have the rights to use these photos of the artist

Delete an artist photo

DELETE /api/v1/artists/{artist_id}/photos/{photo_id}

Remove one photo.

CLI kinetune artists photos delete MCP delete_artist_photo Scopes music:write or videos:write

FieldTypeDescription
artist_id path · requiredstringThe artist id
photo_id path · requiredstringThe photo id

Songs

List songs

GET /api/v1/songs

Songs with their cover, duration and analysis status. A song must be analyzed (analysis.status "ready") before videos can be made. 50 per page by default: pass q to search, and limit/offset to page. cover_art.url is the cover at up to 1536 px (JPEG; width and height describe it), preview_url a 640 px and thumbnail_url a 160 px WebP. Image links are signed for 7 days and stay the same all day, so they can be cached.

CLI kinetune songs list MCP list_songs Scopes music:read or videos:read

FieldTypeDescription
artist_id querystringOnly this artist’s songs
q querystringPart of the song title or artist name
limit queryinteger 1–100Results per page, 1-100 (default 50)
offset queryinteger 0–9007199254740991How many results to skip
status query"pending" | "processing" | "ready" | "failed"Only songs whose analysis has this status (ready = usable for videos)
sort query"title" | "newest"title (default): by artist then title; newest: latest uploads first

Upload a song

POST /api/v1/songs

Add a song: master audio and square cover art. Audio: MP3, WAV or M4A up to 250 MB. Cover: a square JPEG or PNG, 1000–6000 px (3000×3000 recommended), up to 20 MB; it is kept at 1536, 640 and 160 px, not as uploaded. The song is analyzed next (lyrics, beats, sections): poll get_song until analysis.status is "ready", usually about a minute. Pass lyrics (or set them later with set_song_lyrics) to have the videos spell every word right.

CLI kinetune songs create MCP create_song Scopes music:write or videos:write

Files: audio (multipart) or audio_url (JSON), cover_art (multipart) or cover_art_url (JSON).

FieldTypeDescription
artist_id body · requiredstringThe artist id
title body · requiredstringThe song title
language bodystringLyrics language (ISO 639-1, e.g. "en"); detected when omitted
audio_url bodyURLA public https URL of the master audio
cover_art_url bodyURLA public https URL of the square cover art
lyrics bodystringOptional. The song’s lyrics as text: plain (Suno-style [Verse]/[Chorus] tags and (x2) marks are fine), or the contents of an SRT, WebVTT or LRC file. Every word is still timed from the audio: your text fixes misheard words and sets where lines break in videos. A part sung again (a chorus) can be written once; lyrics that don’t match what’s sung, or cover only part of it, are refused once the song is analyzed (get_song: analysis.lyrics.status "mismatch")

Get a song

GET /api/v1/songs/{song_id}

One song and its analysis status. cover_art.url is the cover at up to 1536 px (JPEG; width and height describe it), preview_url a 640 px and thumbnail_url a 160 px WebP. Image links are signed for 7 days and stay the same all day, so they can be cached. analysis.lyrics.status says whose words its videos show: "transcribed" (as heard), "checked" (your lyrics, timed from the audio; corrected, added and kept count what checking did), "waiting" (your lyrics, checked once the analysis finishes) or "mismatch" (your lyrics didn’t match what’s sung, so the transcription is used).

CLI kinetune songs get MCP get_song Scopes music:read or videos:read

FieldTypeDescription
song_id path · requiredstringThe song id

Rename a song

PATCH /api/v1/songs/{song_id}

Change a song’s title.

CLI kinetune songs rename MCP rename_song Scopes music:write or videos:write

FieldTypeDescription
song_id path · requiredstringThe song id
title body · requiredstringThe new title

Archive a song

DELETE /api/v1/songs/{song_id}

Remove a song (its videos stay).

CLI kinetune songs archive MCP archive_song Scopes music:write or videos:write

FieldTypeDescription
song_id path · requiredstringThe song id

Get a song’s analysis

GET /api/v1/songs/{song_id}/analysis

Word-timed lyrics, tempo, beats, sections and hook. Use the section times to choose a trim for a lyric video. lyrics.text is the song’s lyrics to edit: yours as you gave them, or the transcription a line per phrase (lyrics.yours says which).

CLI kinetune songs analysis MCP get_song_analysis Scopes music:read or videos:read

FieldTypeDescription
song_id path · requiredstringThe song id

Analyze a song again

POST /api/v1/songs/{song_id}/analysis

Retry a failed analysis.

CLI kinetune songs reanalyze MCP reanalyze_song Scopes music:write or videos:write

FieldTypeDescription
song_id path · requiredstringThe song id

Set a song’s lyrics

POST /api/v1/songs/{song_id}/lyrics

Give a song its own lyrics, or replace them. The song’s lyrics as text: plain (Suno-style [Verse]/[Chorus] tags and (x2) marks are fine), or the contents of an SRT, WebVTT or LRC file. Every word is still timed from the audio: your text fixes misheard words and sets where lines break in videos. A part sung again (a chorus) can be written once; lyrics that don’t match what’s sung, or cover only part of it, are refused (409, the song unchanged). They are checked right away (analysis.lyrics in the answer says what changed), or once the analysis finishes if it hasn’t (202). Videos made from then on use them; videos already made stay as they are.

CLI kinetune songs set-lyrics MCP set_song_lyrics Scopes music:write or videos:write

FieldTypeDescription
song_id path · requiredstringThe song id
lyrics body · requiredstringThe lyrics: text, or an SRT, WebVTT or LRC file’s contents

Remove a song’s lyrics

DELETE /api/v1/songs/{song_id}/lyrics

Go back to the transcribed words. Videos made from then on show the words as transcribed.

CLI kinetune songs clear-lyrics MCP clear_song_lyrics Scopes music:write or videos:write

FieldTypeDescription
song_id path · requiredstringThe song id

Looks

List Looks

GET /api/v1/looks

Browse Official, Community and your own Looks. A Look is a complete, reusable lyric-video design. Pass its id as {"mode":"existing","id":…} to reuse it exactly. A Look that shows an artist (featured_artist) is private and only serves that artist's songs: choosing for a song, pass its artist_id to leave out Looks that show another artist.

CLI kinetune looks list MCP list_looks Scopes library:read or videos:read

FieldTypeDescription
scope query"all" | "official" | "community" | "mine"Which library; default all
category querystringA category id from get_options
lyric_style querystringA lyric style id from get_options (how the lyrics move)
artist_id querystringThe artist of the song you are choosing for: Looks that show another artist are left out
q querystringSearch words
sort query"newest" | "popular"—
limit queryinteger 1–100—
offset queryinteger 0–9007199254740991—

Get a Look

GET /api/v1/looks/{look_id}

One Look with its design and preview images. backgrounds.portrait and backgrounds.landscape are the background plates the video uses; backgrounds.previews has 480 px wide copies of them for thumbnails (null for a Look without a photo or video background).

CLI kinetune looks get MCP get_look Scopes library:read or videos:read

FieldTypeDescription
look_id path · requiredstringThe Look id

Rename a Look

PATCH /api/v1/looks/{look_id}

Rename one of your Looks.

CLI kinetune looks rename MCP rename_look Scopes library:write or videos:write

FieldTypeDescription
look_id path · requiredstringThe Look id
name body · requiredstringThe new name

Delete a Look

DELETE /api/v1/looks/{look_id}

Remove one of your Looks (videos made with it stay).

CLI kinetune looks delete MCP delete_look Scopes library:write or videos:write

FieldTypeDescription
look_id path · requiredstringThe Look id

Publish or unpublish a Look

POST /api/v1/looks/{look_id}/visibility

Make one of your Looks public (earns 10 credits) or private. Public Looks join the Community library under your @username. A Look that shows your artist stays private (409).

CLI kinetune looks visibility MCP set_look_visibility Scopes library:write or videos:write

FieldTypeDescription
look_id path · requiredstringThe Look id
visibility body · required"public" | "private"—

Upload a background

POST /api/v1/backgrounds

Upload your own photo or video to design a New Look around. Photo: JPEG, PNG or WebP, at least 720 px on the short side, up to 25 MB. Video: MP4, MOV or WebM, 4–180 seconds, at least 720 px on the short side, up to 300 MB; it becomes a seamless loop of up to 20 s. Only with the rights to use it. Then quote a lyric video with look {"mode":"new","category":"…","background":{"source":"upload-photo" or "upload-video","upload_id":"…"},"visibility":"private"}.

CLI kinetune backgrounds upload MCP upload_background Scopes library:write or videos:write

Files: file (multipart) or file_url (JSON).

FieldTypeDescription
file_url bodyURLA public https URL of the photo or video
rights_confirmed body · requiredtrueYou have the rights to use this photo or video

Quotes and videos

Quote a lyric video

POST /api/v1/quotes body {"type":"lyric-video"}

The exact credits for a lyric video, before anything is charged. Returns quote_id, credits (total), credits_per_video and a breakdown. Always quote first and tell the user the credits before creating; credits are reserved at creation and charged only when the video is delivered. A quote is valid for 30 minutes.

CLI kinetune quote lyric-video MCP quote_lyric_video Scopes videos:write or videos:read

FieldTypeDescription
song_id body · requiredstringThe song id
variations bodyinteger 1–41–4 different New Looks, one video each (an Existing Look renders one) Default 1.
callback_url bodystringAn https URL to POST the finished video to (signed; see Callbacks). Quote and create with the same value
metadata bodyobjectYour own JSON (an order id, for example): kept with the video and returned in its request. Quote and create with the same value
look body · requiredobject{"mode":"existing","id":"look_…"} to reuse a saved Look (add "lyric_style" to render it in another lyric style, at no extra cost), or {"mode":"new","category":"…","lyric_style":"…","background":{"source":"ai-image","quality":"high"},"visibility":"private","direction":"…"} to have one designed (background.source "upload-photo"/"upload-video" with background.upload_id from upload_background designs it around your own media; such a Look stays private. "stock-photo"/"stock-video" with background.stock_id from search_stock uses that stock photo or clip instead of the director's pick). lyric_style (optional, from get_options) sets how the lyrics are presented and animated: block-stack, punch, player, neon, terminal, cinematic… Omit it and the director picks one. background.scenes (2–4, AI image only) makes that many shots of the same world that cut on the song's sections, each priced like the first. The singer is left out unless asked: feature_artist "always" (default "never") makes them the subject of the background, recognizable from their artist photos (add_artist_photos); it needs an AI image or AI video background, a private Look and display.cover false (the cover would hide them), and that Look then only serves this artist's songs. A saved Look that shows an artist (featured_artist) only serves that artist's songs, also with display.cover false
aspect_ratios body"9:16" | "16:9" | "1:1"[] (1–3)Formats to render, each its own file: "9:16" (vertical), "16:9" (wide), "1:1" (square) Default ["9:16"].
display bodyobjectWhich elements show (title, artist, cover, lyrics, badges, headline) and their sizes. cover must be false to show the artist in the background Default {"title":true,"artist":true,"cover":true,"lyrics":true,"badges":true}.
trim bodyobjectRender only this section of the song (at least 8 seconds)

Quote a Canvas

POST /api/v1/quotes body {"type":"canvas"}

The exact credits for a Spotify Canvas, before anything is charged. Returns quote_id, credits and a breakdown. Always quote first and tell the user the credits before creating; credits are reserved at creation and charged only when the video is delivered.

CLI kinetune quote canvas MCP quote_canvas Scopes videos:write or videos:read

FieldTypeDescription
song_id body · requiredstringThe song id
variations bodyinteger 1–41–4 different Canvases Default 1.
callback_url bodystringAn https URL to POST the finished video to (signed; see Callbacks). Quote and create with the same value
metadata bodyobjectYour own JSON (an order id, for example): kept with the video and returned in its request. Quote and create with the same value
source body"ai-video" | "ai-image" | "stock-photo" | "stock-video"ai-video (default), ai-image, stock-photo or stock-video Default "ai-video".
quality body"standard" | "high"AI video model tier: standard or high Default "standard".
resolution body"720p" | "1080p"1080p (1080×1920) or 720p Default "1080p".
style body"cinematic" | "dreamy" | "abstract" | "surreal" | "retro" | "minimal" | "dark" | "vibrant" | "nature" | "urban"Optional visual style
direction bodystringOptional mood, motifs or references; the concept still comes from the cover
feature_artist body"auto" | "always" | "never"Whether the Canvas shows the artist: auto (the director decides), always or never (AI sources; needs artist photos for "always") Default "auto".
seconds bodyinteger 5–8Canvas length in whole seconds, 5–8 (default 8). Spotify loops it, so no part of the song is chosen Default 8.
stock_id bodystringWith a stock source: the stock photo or video (search_stock with seconds) to use instead of the director's pick

Create a lyric video

POST /api/v1/videos body {"type":"lyric-video"}

Make the lyric video a quote priced (spends credits). Send the same request as the quote plus its quote_id. Returns the video ids at once; poll get_video until status is completed (or failed). Each video has one file per format.

CLI kinetune create lyric-video MCP create_lyric_video Scopes videos:write

FieldTypeDescription
song_id body · requiredstringThe song id
variations bodyinteger 1–41–4 different New Looks, one video each (an Existing Look renders one) Default 1.
callback_url bodystringAn https URL to POST the finished video to (signed; see Callbacks). Quote and create with the same value
metadata bodyobjectYour own JSON (an order id, for example): kept with the video and returned in its request. Quote and create with the same value
look body · requiredobject{"mode":"existing","id":"look_…"} to reuse a saved Look (add "lyric_style" to render it in another lyric style, at no extra cost), or {"mode":"new","category":"…","lyric_style":"…","background":{"source":"ai-image","quality":"high"},"visibility":"private","direction":"…"} to have one designed (background.source "upload-photo"/"upload-video" with background.upload_id from upload_background designs it around your own media; such a Look stays private. "stock-photo"/"stock-video" with background.stock_id from search_stock uses that stock photo or clip instead of the director's pick). lyric_style (optional, from get_options) sets how the lyrics are presented and animated: block-stack, punch, player, neon, terminal, cinematic… Omit it and the director picks one. background.scenes (2–4, AI image only) makes that many shots of the same world that cut on the song's sections, each priced like the first. The singer is left out unless asked: feature_artist "always" (default "never") makes them the subject of the background, recognizable from their artist photos (add_artist_photos); it needs an AI image or AI video background, a private Look and display.cover false (the cover would hide them), and that Look then only serves this artist's songs. A saved Look that shows an artist (featured_artist) only serves that artist's songs, also with display.cover false
aspect_ratios body"9:16" | "16:9" | "1:1"[] (1–3)Formats to render, each its own file: "9:16" (vertical), "16:9" (wide), "1:1" (square) Default ["9:16"].
display bodyobjectWhich elements show (title, artist, cover, lyrics, badges, headline) and their sizes. cover must be false to show the artist in the background Default {"title":true,"artist":true,"cover":true,"lyrics":true,"badges":true}.
trim bodyobjectRender only this section of the song (at least 8 seconds)
quote_id body · requireduuidThe quote_id from the matching quote: the request must be identical

Create a Canvas

POST /api/v1/videos body {"type":"canvas"}

Make the Canvas a quote priced (spends credits). Send the same request as the quote plus its quote_id. Returns the video ids at once; poll get_video until status is completed. Upload the file in Spotify for Artists.

CLI kinetune create canvas MCP create_canvas Scopes videos:write

FieldTypeDescription
song_id body · requiredstringThe song id
variations bodyinteger 1–41–4 different Canvases Default 1.
callback_url bodystringAn https URL to POST the finished video to (signed; see Callbacks). Quote and create with the same value
metadata bodyobjectYour own JSON (an order id, for example): kept with the video and returned in its request. Quote and create with the same value
source body"ai-video" | "ai-image" | "stock-photo" | "stock-video"ai-video (default), ai-image, stock-photo or stock-video Default "ai-video".
quality body"standard" | "high"AI video model tier: standard or high Default "standard".
resolution body"720p" | "1080p"1080p (1080×1920) or 720p Default "1080p".
style body"cinematic" | "dreamy" | "abstract" | "surreal" | "retro" | "minimal" | "dark" | "vibrant" | "nature" | "urban"Optional visual style
direction bodystringOptional mood, motifs or references; the concept still comes from the cover
feature_artist body"auto" | "always" | "never"Whether the Canvas shows the artist: auto (the director decides), always or never (AI sources; needs artist photos for "always") Default "auto".
seconds bodyinteger 5–8Canvas length in whole seconds, 5–8 (default 8). Spotify loops it, so no part of the song is chosen Default 8.
stock_id bodystringWith a stock source: the stock photo or video (search_stock with seconds) to use instead of the director's pick
quote_id body · requireduuidThe quote_id from the matching quote: the request must be identical

List videos

GET /api/v1/videos

Videos, newest first, with status and thumbnails. Each video's outputs carry aspect_ratio, poster_url, poster_seconds and web_url (for thumbnails and previews); get_video has the download links. A video that is waiting has queue: why (plan_limit or render_capacity), its place in line or about how long.

CLI kinetune videos list MCP list_videos Scopes videos:read

FieldTypeDescription
song_id querystringOnly this song’s videos
type query"lyric-video" | "canvas"—
limit queryinteger 1–100—

Get a video

GET /api/v1/videos/{video_id}

Status, progress, credits and, when completed, the download links. status is queued, processing, completed, failed or cancelled. While it waits, queue says why: plan_limit (the organization already makes as many videos at once as its plan allows; position is its place in line) or render_capacity (every render machine is busy; estimated_wait_seconds is about how long). Completed videos have outputs with download_url (full quality), web_url (720p) and poster_url, signed for 7 days. A lyric video's poster is a frame with one whole lyric line on screen (the hook when it can be), ready to set as the thumbnail where you post it; a Canvas's is its first frame. poster_seconds says where in that file the poster was cut, for posts that take a cover frame offset instead of an image (TikTok); null on videos made before it was kept. Failed videos have error and error_code; AI_VIDEO_UNAVAILABLE means the AI video couldn’t be made for a reason on our side, so make it again later.

CLI kinetune videos get MCP get_video Scopes videos:read

FieldTypeDescription
video_id path · requiredstringThe video id

Cancel a video

POST /api/v1/videos/{video_id}/cancel

Stop a queued or processing video (credits released).

CLI kinetune videos cancel MCP cancel_video Scopes videos:write

FieldTypeDescription
video_id path · requiredstringThe video id

Make a video again

POST /api/v1/videos/{video_id}/retry

Run a finished, failed or cancelled video again (new charge). Reuses the Look it made, with its background media and loops, so nothing already made is paid for again. A video that failed before its Look was saved is designed afresh.

CLI kinetune videos retry MCP retry_video Scopes videos:write

FieldTypeDescription
video_id path · requiredstringThe video id

Delete a video

DELETE /api/v1/videos/{video_id}

Delete a finished video and its files.

CLI kinetune videos delete MCP delete_video Scopes videos:write

FieldTypeDescription
video_id path · requiredstringThe video id