Developer docs

Upload a song

MCP tool
create_song
CLI
kinetune songs create
POST/api/v1/songs

Not sent from the docs: it uploads files to your workspace. Run it with curl, the CLI or its MCP tool.

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. Needs an active plan (402 plan_required without one; get_account: plan.active) and room in its storage (402 storage_full when it would not fit; get_account: storage).

Authorization

headerAuthorizationBearer <token>

An organization API key (kt_live_…) or an OAuth access token

Request Body

  1. body
artist_id?string

The artist id. An artist workspace may leave it out: its songs are its artist's

Length1 <= length <= 120
title*string

The song title

Length1 <= length <= 300
language?string

Lyrics language (ISO 639-1, e.g. "en"); detected when omitted

Match^[a-z]{2,3}$
audio_url?string

A public https URL of the master audio

Formaturi
Lengthlength <= 2000
cover_art_url?string

A public https URL of the square cover art

Formaturi
Lengthlength <= 2000
lyrics?string

Optional. 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")

Lengthlength <= 100000

Response Body

OK

Example Request
curl -X POST 'https://kinetune.com/api/v1/songs' \
  -H 'Content-Type: application/json' \
  -d '{
  "title": "string"
}'
Example Response
Empty