Edit a song

June 3, 2026

Table of contents

  1. Request Headers
  2. Request Body
    1. operation: effect
    2. operation: extend
    3. operation: replace
    4. operation: cover
    5. operation: remix
    6. operation: stems
  3. Responses
  4. Model
  5. Examples
  6. Try It

Edit an existing clip β€” the operation field selects one of six edit kinds, each taking a clip (an encoded clip asset ID from a previous generation or GET /music).

operation is required β€” one of:

operation What it does Required params Optional params
effect Apply one audio effect effect + that effect’s scalar param(s) β€”
extend Add new music to the end, or from a point instruction extend_s, extend_from_s
replace Regenerate a time section instruction, mask_start_s, mask_end_s β€”
cover Restyle the whole song (a Lyria 3 Pro cover) β€” instruction, strength
remix Re-sing with edited lyrics lyrics prompt
stems Separate into 4 stem clips (drums/bass/vocals/other) β€” β€”

https://api.useapi.net/v1/flowmusic/music/edit

Request Headers

Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data

Request Body

Every operation accepts these common fields (there is no email β€” the clip already identifies its account, and the edit runs there):

  • clip is required, the encoded clip asset ID to edit.
  • seed is optional, an integer β‰₯ 0 β€” pins the result for reproducibility.
  • title is optional, a title for the result clip.
  • mode is optional, sync (default β€” blocks until ready) or async (returns 201 with a jobid; poll GET /jobs/jobid). Ignored by stems, which is always sync.
  • replyUrl is optional, a webhook URL β€” the job record is POSTed to it when the edit completes or fails. Ignored by stems.
  • replyRef is optional, a custom reference string echoed back in the webhook.

Plus the chosen operation’s own fields, below.

operation: effect

effect is one of Trim, Fade, Gain, Reverb, Pan, Equalizer. Each effect reads only its own flat scalar params (sending a param for a different effect is ignored):

  • Gain β€” gain_db (βˆ’30 … 30).
  • Reverb β€” mix, room_size (0 … 1 each).
  • Pan β€” pan (βˆ’1 left … 1 right).
  • Equalizer β€” bass_db, mid_db, treble_db (βˆ’12 … 12 each).
  • Fade β€” fade_in_s, fade_out_s (β‰₯ 0, at least one > 0).
  • Trim β€” start_s, end_s (end_s > start_s, ≀ duration).
{
  "operation": "effect",
  "clip": "user:[email protected]:...",
  "effect": "Reverb",
  "mix": 0.4,
  "room_size": 0.7
}

operation: extend

{
  "operation": "extend",
  "clip": "user:1234-...-clip:...",
  "instruction": "add an instrumental outro",
  "extend_s": 30
}
  • instruction is required, what to add.
  • extend_s is optional, seconds to add, 1–300 (default 150).
  • extend_from_s is optional, the point to extend from (default = end of clip).

operation: replace

{
  "operation": "replace",
  "clip": "user:1234-...-clip:...",
  "instruction": "softer piano in this section",
  "mask_start_s": 0,
  "mask_end_s": 8
}
  • instruction is required, how to regenerate the section.
  • mask_start_s is required, the section start (seconds).
  • mask_end_s is required, the section end (seconds), > mask_start_s, ≀ duration.

operation: cover

Restyle the entire song. instruction is optional (a free-text style direction); strength is the cover-strength slider.

{
  "operation": "cover",
  "clip": "user:1234-...-clip:...",
  "instruction": "lo-fi chillhop reinterpretation",
  "strength": 0.7
}
  • instruction is optional, a free-text style direction.
  • strength is optional, 0 … 1 (default 1).

operation: remix

Re-sing the song with edited lyrics. By default it reuses the source song’s sound prompt; override with prompt. The edited lyrics round-trip into the result clip’s lyrics.

{
  "operation": "remix",
  "clip": "user:1234-...-clip:...",
  "lyrics": "[Verse 1]\nNeon rain on the avenue\n[Chorus]\nWe rise again",
  "prompt": "dreamy synthwave, 100 bpm"
}
  • lyrics is required, the edited lyrics, [Verse]/[Chorus]-tagged.
  • prompt is optional, a sound-prompt override (defaults to the source clip’s).

operation: stems

Separate the song into its individual tracks. Flow Music runs the split server-side and creates 4 new clips β€” drums, bass, vocals, other β€” each a normal clip with its own id and a public audio_url/wav_url. Only clip is needed.

{
  "operation": "stems",
  "clip": "user:1234-...-clip:..."
}
  • stems is synchronous β€” the request blocks ~15–60 s while the split runs, then returns all four stems in one reply (it ignores mode/replyUrl/replyRef). Re-running on an already-split clip returns its stems immediately.
  • Download any stem with GET /music/download (mp3) or its audio_url/wav_url.

Its response differs from the other edits β€” it’s a flat manifest of the stem clips, not a job record:

{
  "email": "[email protected]",
  "operation": "stems",
  "source_clip": "user:1234-...-clip:...",
  "status": "completed",
  "clips": [
    {
      "stem_type": "drums",
      "clip": "user:1234-...-clip:...",
      "title": "Song - drums",
      "duration_s": 173.0,
      "audio_url": "https://storage.googleapis.com/...1a2b3c4d.m4a",
      "wav_url": "https://storage.googleapis.com/...1a2b3c4d.wav",
      "image_url": null
    }
  ]
}

(four entries β€” drums, bass, vocals, other).

Responses

Same job-record shape as POST /music β€” operation echoes the requested edit kind. (operation: stems is the exception β€” it returns the flat stem manifest shown above, not a job record.)

  • 200 OK

    Sync mode (default) β€” the edit is rendered and the full record is returned inline.

    {
      "jobid": "job:aaaabbbb-cccc-4ddd-8eee-ffff99990000-user:[email protected]:flowmusic",
      "email": "[email protected]",
      "operation": "cover",
      "status": "completed",
      "created_at": "2026-06-01T18:40:42.412Z",
      "completed_at": "2026-06-01T18:41:37.432Z",
      "duration_ms": 55020,
      "clips": [
        {
          "clip": "user:[email protected]:c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f",
          "title": "Morning Sun (Cover)",
          "duration_s": 171.02,
          "lyrics": "[Verse 1]\nCity lights blur in the rain\n[Chorus]\nAnd I will wait for the morning sun",
          "seed": 123456,
          "lyrics_timing": [ [0.0, 2.4], [2.4, 5.1] ],
          "created_at": "2026-06-01T18:41:30.118Z",
          "audio_url": "https://storage.googleapis.com/...c3d4e5f6.m4a",
          "wav_url": "https://storage.googleapis.com/...c3d4e5f6.wav",
          "image_url": "https://storage.googleapis.com/...d4e5f6a7.jpg"
        }
      ],
      "request": {
        "operation": "cover",
        "clip": "user:[email protected]:...",
        "strength": 0.7
      }
    }
    
  • 201 Created

    Async mode ("mode": "async") β€” the edit is queued and returned immediately as pending. Poll GET /jobs/jobid until status is completed or failed.

    {
      "jobid": "job:aaaabbbb-cccc-4ddd-8eee-ffff99990000-user:[email protected]:flowmusic",
      "email": "[email protected]",
      "operation": "remix",
      "status": "pending",
      "created_at": "2026-06-01T18:40:42.412Z",
      "request": {
        "operation": "remix",
        "clip": "user:1234-...-clip:...",
        "lyrics": "[Verse 1]\n...",
        "mode": "async"
      }
    }
    
  • 400 Bad Request

    Validation error β€” an unknown operation, a missing required field for the chosen operation (e.g. replace without mask_start_s/mask_end_s, or effect without effect), or a clip that isn’t a clip-type asset ID.

    {
      "error": "instruction required for operation=extend",
      "code": 400
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "Unauthorized",
      "code": 401
    }
    
  • 404

    The clip’s account isn’t configured under your useapi.net account, or the source clip no longer exists on Flow Music.

    {
      "error": "source clip not found on FlowMusic",
      "code": 404
    }
    
  • 422

    The edit produced no audio (e.g. a content-moderation refusal β€” a terminal status: "failed" record), or the source clip can’t be edited (an uploaded clip has no conversation_id).

    {
      "jobid": "job:aaaabbbb-cccc-4ddd-8eee-ffff99990000-user:[email protected]:flowmusic",
      "email": "[email protected]",
      "operation": "cover",
      "status": "failed",
      "created_at": "2026-06-01T18:40:42.412Z",
      "completed_at": "2026-06-01T18:41:10.512Z",
      "error": { "code": "moderation_reject", "message": "the model declined to generate audio for this edit" },
      "request": {
        "operation": "cover",
        "clip": "user:1234-...-clip:..."
      }
    }
    
  • 429 Too Many Requests

    Passed through from Flow Music when the clip’s account is already running too many concurrent jobs β€” retry once one finishes.

    {
      "error": "producer/tool-call failed (429): {\"detail\":\"Too Many Requests\"}",
      "code": 429
    }
    
  • 596 Account Error

    The clip’s account is in an error state and can’t be used β€” re-add it via POST /accounts.

    {
      "error": "Account [email protected] in error state: refresh token rejected",
      "code": 596
    }
    

Model

Same job-record shape as POST /music, plus a top-level operation. The request echoes the edit body you submitted. (operation: stems returns a flat manifest of the 4 stem clips instead β€” see operation: stems.)

  • {
      jobid: string                  // job:<uuid>-user:<id>-<email>-bot:flowmusic
      email: string
      operation: 'effect' | 'extend' | 'replace' | 'cover' | 'remix' | 'stems'
      status: 'completed' | 'pending' | 'failed'
      created_at: string             // ISO 8601 timestamp
      completed_at?: string          // present when terminal
      duration_ms?: number           // wall-clock render time
      clips: Array<{
        clip: string                 // encoded clip asset id β€” use with /music/download and /music/edit
        title: string | null
        duration_s: number | null
        lyrics: string | null        // [Verse]/[Chorus]-tagged; "[Instrumental]" for instrumentals
        seed: number | null
        lyrics_timing: Array<[number, number]> | null  // timing markers, [start, end] seconds (vocal clips)
        created_at: string           // ISO 8601 timestamp
        audio_url: string            // m4a download URL
        wav_url: string              // wav download URL
        image_url: string | null     // auto-generated artwork URL
      }>
      request: {                     // the edit body you submitted, echoed back verbatim
        operation: 'effect' | 'extend' | 'replace' | 'cover' | 'remix' | 'stems'
        clip: string
        seed?: number                // common β€” pins the result
        title?: string               // common
        mode?: 'sync' | 'async'      // common
        replyUrl?: string            // common β€” webhook
        replyRef?: string            // common β€” webhook reference
        effect?: 'Trim' | 'Fade' | 'Gain' | 'Reverb' | 'Pan' | 'Equalizer'   // effect
        gain_db?: number             // effect=Gain (-30..30)
        mix?: number                 // effect=Reverb (0..1)
        room_size?: number           // effect=Reverb (0..1)
        pan?: number                 // effect=Pan (-1..1)
        bass_db?: number             // effect=Equalizer (-12..12)
        mid_db?: number              // effect=Equalizer (-12..12)
        treble_db?: number           // effect=Equalizer (-12..12)
        fade_in_s?: number           // effect=Fade
        fade_out_s?: number          // effect=Fade
        start_s?: number             // effect=Trim
        end_s?: number               // effect=Trim
        instruction?: string         // extend / replace / cover
        extend_s?: number            // extend (1..300)
        extend_from_s?: number       // extend
        mask_start_s?: number        // replace
        mask_end_s?: number          // replace
        strength?: number            // cover (0..1)
        lyrics?: string              // remix
        prompt?: string              // remix
      }
    }
    
  • {
      jobid: string                  // job:<uuid>-user:<id>-<email>-bot:flowmusic
      email: string
      operation: 'effect' | 'extend' | 'replace' | 'cover' | 'remix' | 'stems'
      status: 'pending'
      created_at: string             // ISO 8601 timestamp
      request: { }                   // the edit body you submitted β€” same shape as the 200 (Completed) model above
    }
    

Examples

  • # Cover (restyle) β€” instruction optional
    curl -H "Content-Type: application/json" \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -X POST "https://api.useapi.net/v1/flowmusic/music/edit" \
         -d '{ "operation": "cover", "clip": "user:[email protected]:...", "strength": 0.7 }'
    
  • const response = await fetch('https://api.useapi.net/v1/flowmusic/music/edit', {
      method: 'POST',
      headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' },
      body: JSON.stringify({
        operation: 'remix',
        clip: 'user:[email protected]:...',
        lyrics: '[Verse 1]\nNeon rain on the avenue\n[Chorus]\nWe rise again'
      })
    });
    console.log(await response.json());
    
  • import requests
    
    response = requests.post(
        'https://api.useapi.net/v1/flowmusic/music/edit',
        headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
        json={'operation': 'effect', 'clip': 'user:[email protected]:...',
              'effect': 'Gain', 'gain_db': 6}
    )
    print(response.status_code, response.json())
    

Try It