How to Generate AI Music with Lyria 3 Pro via the Flow Music API

5 min read • June 19, 2026 (November 7, 2026)

Table of contents

  1. Introduction
  2. Capabilities and parameters
  3. Pricing
  4. Generate a song in two API calls
  5. Custom lyrics, instrumentals, and editing a song
  6. Batch-generate with a script
  7. Examples
  8. Frequently asked questions
  9. Conclusion

Introduction

Lyria 3 Pro is Google DeepMind’s text-to-music model, and the useapi.net Flow Music API runs it over plain REST on your Flow Music website subscription. Lyria 3 Pro powers Flow Music, Google Labs’ generator (formerly Producer AI, originally Riffusion). One prompt returns a complete, produced song — vocals, melody, and arrangement — and from there you can supply your own lyrics, force an instrumental, or edit a clip with cover, remix, extend, replace, effects, and stem-splitting.

Capabilities and parameters

Songs default to Lyria 3 Pro, and model: "lyria-3.5" selects the newer Lyria 3.5. Each call returns up to two clips (an A/B pair), each up to roughly three minutes long. The main fields on the music endpoint:

Parameter Type What it does
prompt string (required) Song description — style, mood, genre, instruments, BPM, vocal direction. 1–10,000 chars.
instrumental boolean true forces an instrumental (prepends an [Instrumental] tag). false (default) lets the model decide whether to sing.
lyrics string Your own [Verse]/[Chorus]-tagged lyrics (≤10,000 chars) — forces a vocal render of those exact words.
model lyria-3-pro | lyria-3.5 Which Lyria model renders the song. lyria-3-pro is the default.
ghostwriter standard | pro Which lyrics-writer version writes the words when the model writes them. No effect if you supply your own lyrics.
mode sync | async sync (default) blocks ~40–150 s and returns the finished song. async returns a jobid to poll.
email string Which connected account to use. Omit it and the API load-balances across accounts with free capacity.

If you omit both instrumental and lyrics, the model decides whether to sing from your prompt alone. The endpoint also accepts replyUrl/replyRef webhooks and experimental refImage/refAudio reference hints — see the music endpoint docs for the full body.

Generation is only the first step — the music/edit endpoint reworks any existing clip with six operations:

Operation What it does
cover Restyle the whole song (a Lyria 3 Pro cover)
remix Re-sing with edited lyrics
extend Add 1–300 s of new music (default 150 s), at the end or from a chosen point
replace Regenerate a specific time section
effect Apply Trim, Fade, Gain, Reverb, Pan, or Equalizer
stems Split into four stems — drums, bass, vocals, other

The editing section below shows the request shapes for each.

Pricing

Your Flow Music website subscription pays for every song, with no per-song surcharge from useapi.net. A song costs 5 credits, which comes to about 1.3¢ on Flow Music Starter ($8 a month for 3,000 credits) and 1.1¢ on Member ($64 for 30,000), against 8¢ a song for Lyria 3 Pro on Google’s Gemini API (as of October 2026). A Google AI subscription includes a Flow Music plan with its own credits, separate from the Google AI credits: Starter on Google AI Plus, Plus on Google AI Pro and Member on Google AI Ultra. Cover, remix, extend, replace, effects and stem-splitting run on the same credits, the Free plan generates a little each day from daily top-up credits, and downloads (mp3, wav, m4a, stems) cost nothing. The Flow Music API overview has the full cost calculator, and Setup Flow Music connects an account.

Generate a song in two API calls

You need a useapi.net API token and a connected Flow Music account — export the token so the curl examples below run as-is: export USEAPI_TOKEN="user:1234-...". The fastest reliable workflow is asynchronous: the create call returns a jobid immediately, then you poll until the song is ready.

First, submit the job with POST https://api.useapi.net/v1/flowmusic/music:

curl -X POST "https://api.useapi.net/v1/flowmusic/music" \
  -H "Authorization: Bearer $USEAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "warm indie folk ballad, acoustic guitar, soft female vocals, 70 bpm, wistful and hopeful",
    "ghostwriter": "pro",
    "mode": "async"
  }'

In async mode the response returns immediately with 201 Created, a jobid, and status: "pending":

{
  "jobid": "job:aaaabbbb-cccc-4ddd-8eee-ffff99990000-user:[email protected]:flowmusic",
  "email": "[email protected]",
  "status": "pending",
  "created_at": "2026-06-01T18:40:42.412Z",
  "request": { "prompt": "warm indie folk ballad...", "mode": "async" }
}

Then poll for the result with GET https://api.useapi.net/v1/flowmusic/jobs/{jobid} (the jobid is URL-encoded in the path — it contains : and @):

curl "https://api.useapi.net/v1/flowmusic/jobs/JOBID" \
  -H "Authorization: Bearer $USEAPI_TOKEN"

When status is completed, the finished audio lives in the clips[] array — audio_url is the signed .m4a, and wav_url is the WAV file:

{
  "jobid": "job:aaaabbbb-...-bot:flowmusic",
  "status": "completed",
  "duration_ms": 132711,
  "clips": [
    {
      "clip": "user:[email protected]:a1b2c3d4-...",
      "title": "Morning Sun",
      "duration_s": 173.04,
      "lyrics": "[Verse 1]\nCity lights blur in the rain\n[Chorus]\nAnd I will wait for the morning sun",
      "audio_url": "https://storage.googleapis.com/...a1b2c3d4.m4a",
      "wav_url": "https://storage.googleapis.com/...a1b2c3d4.wav",
      "image_url": "https://storage.googleapis.com/...b2c3d4e5.jpg"
    }
  ]
}

Lyria 3 Pro typically finishes in 40–150 seconds. Result URLs are signed, so download promptly. Prefer not to poll? mode: "sync" (the default) blocks until the song is ready and returns the same completed record inline with 200 OK — handy for quick tests, but on mobile or flaky networks prefer async, since a dropped connection in sync mode loses the result. You can also pass a replyUrl to receive a webhook when the job completes. A job can come back status: "failed" (e.g. a content-moderation refusal), and the create call may return 402 (insufficient credits), 422 (prompt moderated / no audio), or 429 (all accounts busy) — see the endpoint docs for the full list.

Custom lyrics, instrumentals, and editing a song

You control the voicing entirely from the request body. Set instrumental: true for a purely instrumental track, or paste tagged lyrics to force a sung render of your exact words:

# Instrumental only
curl -X POST "https://api.useapi.net/v1/flowmusic/music" \
  -H "Authorization: Bearer $USEAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "energetic synthwave, driving bass, retro 80s, 120 bpm", "instrumental": true }'

# Your own lyrics → forces a vocal render of those words
curl -X POST "https://api.useapi.net/v1/flowmusic/music" \
  -H "Authorization: Bearer $USEAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "soulful R&B, lush keys, 90 bpm",
    "lyrics": "[Verse 1]\nCity lights blur in the rain\n[Chorus]\nAnd I will wait for the morning sun"
  }'

Once you have a clip’s id, the music/edit endpoint runs any of the six operations from the table above. For example, to extend a song by 30 seconds:

curl -X POST "https://api.useapi.net/v1/flowmusic/music/edit" \
  -H "Authorization: Bearer $USEAPI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "extend",
    "clip": "CLIP_ID_FROM_A_PREVIOUS_GENERATION",
    "extend_s": 30
  }'

See the editing docs for each operation’s parameters.

Batch-generate with a script

Finding the right track takes many attempts, and running them by hand is tedious. The Node.js script below reads a list of prompts from prompts.json, submits each one to the music endpoint in async mode, polls every job until it is done, then downloads all the resulting .m4a clips — so you can queue a batch and come back to a folder of finished songs.

You need Node.js v21 or newer. Put prompts.json and flowmusic.mjs in the same folder and run node ./flowmusic.mjs API_TOKEN EMAIL, where API_TOKEN is your useapi.net API token and EMAIL is the configured Flow Music account email you want to use. Each entry’s prompt is required, and the optional instrumental, lyrics, and ghostwriter fields map straight to the music endpoint.

Expand prompts.json
[
    {
        "prompt": "lo-fi hip hop, mellow piano, 80 bpm. By default the model decides whether to sing based on your prompt."
    },
    {
        "prompt": "warm indie folk ballad, acoustic guitar, soft female vocals, 70 bpm, wistful and hopeful",
        "ghostwriter": "pro"
    },
    {
        "prompt": "energetic synthwave, driving bass, retro 80s, 120 bpm",
        "instrumental": true
    },
    {
        "prompt": "soulful R&B, lush keys, 90 bpm. Provide your own [Verse]/[Chorus]-tagged lyrics to force a vocal render of those exact words. For all parameters see https://useapi.net/docs/api-flowmusic-v1/post-flowmusic-music",
        "lyrics": "[Verse 1]\nCity lights blur in the rain\n[Chorus]\nAnd I will wait for the morning sun"
    }
]
Expand flowmusic.mjs script
/*

Script version 1.0, June 19, 2026

Script to batch-generate music using prompts with the Flow Music API v1 by useapi.net 🚀
Generates complete songs with Google's Lyria 3 Pro via the music endpoint.
For more details visit https://useapi.net/docs/api-flowmusic-v1/post-flowmusic-music

Installation Instructions:
==========================

You need Node.js v21 or newer installed to run this script. Download and install Node.js from:

- Windows, macOS, Linux: https://nodejs.org/

After installation, verify by running the following command in a terminal:

   node -v

Running the Script:
===================

Usage: node flowmusic.mjs <API_TOKEN> <EMAIL> [PROMPTS_FILE]

Replace API_TOKEN with your actual useapi.net API token, see https://useapi.net/docs/start-here/setup-useapi
Replace EMAIL with configured Flow Music email account, see https://useapi.net/docs/start-here/setup-flowmusic
If optional PROMPTS_FILE not provided prompts.json will be used.

Example:
--------

node flowmusic.mjs user:1234-abcdefhijklmnopqrstuv [email protected]

This command executes the script using API token user:1234-abcdefhijklmnopqrstuv with [email protected] Flow Music account email.

Changelog:
==========

- June 19, 2026: Initial release. Submits prompts to the music endpoint in async mode and downloads the resulting m4a clips.

*/

import readline from 'node:readline';
import fs from 'fs/promises';
import { writeFile } from 'node:fs/promises';
import { Readable } from 'node:stream';


// Constants
const RESULTS_FILE = 'flowmusic_results.txt';
const ERRORS_FILE = 'flowmusic_errors.txt';
const DEFAULT_PROMPTS_FILE = 'prompts.json';
const SLEEP_429 = 10 * 1000; // in milliseconds
const MAX_429_RETRIES = 6;   // give up a prompt after this many consecutive 429s (all accounts busy)
const SLEEP_POLL = 15 * 1000; // in milliseconds

const urlAccounts = 'https://api.useapi.net/v1/flowmusic/accounts';
const urlMusic = 'https://api.useapi.net/v1/flowmusic/music';
const urlJobs = 'https://api.useapi.net/v1/flowmusic/jobs/';

// Utility to sleep for given milliseconds
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const elapsedTimeSec = (start) => (Date.now() - start) / 1000;

// Function to fetch configured Flow Music API accounts
async function fetchAccounts(apiToken) {
    const response = await fetch(urlAccounts, {
        headers: {
            'Accept': 'application/json',
            'Authorization': `Bearer ${apiToken}`
        }
    });

    if (!response.ok) {
        console.error(`⛔ Error fetching accounts (HTTP ${response.status}): ${response.statusText}`);
        process.exit(1);
    }

    return response.json();
}

// Submit a single prompt to the music endpoint in async mode.
// Returns the HTTP status; on 201 the jobid is appended to RESULTS_FILE.
async function submitMusic(apiToken, email, prompt, index) {
    const { prompt: text, instrumental, lyrics, ghostwriter } = prompt;

    console.log(`🚀 Lyria 3 Pro » Prompt #${index} • account ${email} • ${instrumental ? 'instrumental' : 'auto vocals'} …`);

    const body = JSON.stringify({
        email,
        prompt: text,
        instrumental,
        lyrics,
        ghostwriter,
        mode: 'async'
    });

    const createResponse = await fetch(urlMusic, {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${apiToken}`
        },
        body
    });

    const createBody = await createResponse.text();

    // 201 Created — async job queued; 200 OK — sync result (returned if mode is overridden).
    if (createResponse.status == 201 || createResponse.status == 200) {
        const json = JSON.parse(createBody);
        const { jobid } = json;
        if (jobid) {
            await fs.appendFile(RESULTS_FILE, `${jobid},#${index}:${text}\n`);
            console.log(`✅ jobid`, jobid);
            return 201;
        } else {
            const error = `No jobid found in HTTP ${createResponse.status} response`;
            console.log(`❓ ${error}`, createBody);
            await fs.appendFile(ERRORS_FILE, `${error},#${index}:${text}\n`);
            return 500;
        }
    } else {
        switch (createResponse.status) {
            case 429:
                console.log(`🔄️ Retry on HTTP ${createResponse.status}`);
                break;
            case 422:
                console.log(`🛑 MODERATED prompt — the model declined to generate audio`, createBody);
                await fs.appendFile(ERRORS_FILE, `${createResponse.status},#${index}:${text}\n`);
                break;
            case 402:
                console.log(`🛑 account has insufficient credits`, createBody);
                await fs.appendFile(ERRORS_FILE, `${createResponse.status},#${index}:${text}\n`);
                break;
            case 596:
                console.log(`🛑 account in error state — re-add it at https://useapi.net/docs/start-here/setup-flowmusic`, createBody);
                await fs.appendFile(ERRORS_FILE, `${createResponse.status},#${index}:${text}\n`);
                break;
            default:
                console.log(`❗ FAILED with HTTP ${createResponse.status}`, createBody);
                await fs.appendFile(ERRORS_FILE, `${createResponse.status},#${index}:${text}\n`);
        }
        return createResponse.status;
    }
}

// Function to poll jobs and download generated audio clips
async function download(apiToken) {
    if (! await fileExists(RESULTS_FILE)) return;

    try {
        const resultsContent = await fs.readFile(RESULTS_FILE, 'utf8');
        const lines = resultsContent.trim().split('\n');

        for (const line of lines) {
            const [jobid, prompt] = line.split(',');

            console.log(`👉 ${jobid}`);

            while (true) {
                const response = await fetch(`${urlJobs}${encodeURIComponent(jobid)}`, {
                    headers: {
                        'Accept': 'application/json',
                        'Authorization': `Bearer ${apiToken}`
                    }
                });

                if (!response.ok) {
                    console.log(`🛑 Poll failed ${jobid} (HTTP ${response.status}):\n${prompt}\n`, await response.text());
                    break;
                }

                const jobResponseBody = await response.json();
                const { status, clips, error } = jobResponseBody;

                if (status == 'failed') {
                    console.error(`🛑 FAILED ${jobid} (${error?.code}: ${error?.message}):\n${prompt}\n`);
                    break;
                }

                if (status == 'completed') {
                    if (Array.isArray(clips) && clips.length > 0) {
                        // A single generation returns up to two clips (an A/B pair) — download all of them.
                        for (let c = 0; c < clips.length; c++) {
                            const { clip, audio_url } = clips[c];
                            const audioFilename = `${clip.replace(/[:/]/g, '_')}.m4a`;

                            if (await fileExists(audioFilename)) {
                                console.log(`⚠️ ${audioFilename} already exists. Skipping download.`);
                                continue;
                            }

                            if (audio_url) {
                                console.log(`✅ Downloading ${audio_url} to ${audioFilename}`);
                                try {
                                    const audioResponse = await fetch(audio_url);
                                    if (!audioResponse.ok) {
                                        console.error(`⛔ Unable to download ${jobid} (HTTP ${audioResponse.status}):\n${prompt}\n`, audio_url);
                                        continue;
                                    }
                                    const stream = Readable.fromWeb(audioResponse.body);
                                    await writeFile(audioFilename, stream);
                                } catch (err) {
                                    console.error(`⛔ Error during download: ${err}`);
                                }
                            } else {
                                console.error(`🛑 No audio_url for clip ${clip} (${jobid}):\n${prompt}\n`);
                            }
                        }
                    } else {
                        console.error(`🛑 ${jobid} completed but returned no clips:\n${prompt}\n`);
                    }

                    break;
                }

                console.log(`⌛ ${jobid} status (${status}) and is still in progress, waiting…`);
                await sleep(SLEEP_POLL);
            }
        }
    } catch (error) {
        console.log(`⛔ Error during download:`, error.stack || error);
    }
}

// Main function
async function main() {
    const apiToken = process.argv[2];
    const email = process.argv[3];
    const promptFile = process.argv[4] || DEFAULT_PROMPTS_FILE;

    if (!apiToken || !email) {
        console.error('Usage: node flowmusic.mjs <API_TOKEN> <EMAIL> [PROMPTS_FILE]');
        process.exit(1);
    }

    console.info('Script v1.0');

    console.info('Node version is: ' + process.version);

    try {
        if (await fileExists(RESULTS_FILE)) {
            let user_input;
            while (!['y', 'n'].includes(user_input)) {
                user_input = (await promptUser(`❔ ${RESULTS_FILE} file detected. Do you want to download the results now? (y/n): `))?.toLowerCase();
                if (user_input == 'y') {
                    await download(apiToken);
                    await fs.unlink(RESULTS_FILE);
                }
            }
        }

        const start = new Date();
        try {
            console.info('START EXECUTION', start);
            await execute(apiToken, email, promptFile); // Pass the promptFile to execute function
        }
        finally {
            console.info('COMPLETED', new Date());
            console.info('EXECUTION ELAPSED', diffInMinutesAndSeconds(start, new Date()));
        }

        try {
            console.info('START DOWNLOAD', start);
            await download(apiToken);
        }
        finally {
            console.info('TOTAL ELAPSED', diffInMinutesAndSeconds(start, new Date()));
        }
    } catch (error) {
        console.error('⛔ Error during execution:', error.stack || error);
    }
}

// Modify the execute function to accept promptFile as a parameter
async function execute(apiToken, email, promptFile) {
    const accounts = await fetchAccounts(apiToken);

    console.info(`Configured Flow Music API accounts (${Object.values(accounts).length}):`, Object.values(accounts).map(a => a.email).join(', '));

    if (Object.values(accounts).length <= 0) {
        console.error(`⛔ No configured Flow Music accounts found. Please refer to https://useapi.net/docs/start-here/setup-flowmusic`);
        process.exit(1);
    }

    if (!accounts[email]) {
        console.error(`⛔ Account ${email} not found. Please refer to https://useapi.net/docs/start-here/setup-flowmusic`);
        process.exit(1);
    }

    if (accounts[email].error) {
        console.error(`⛔ Account ${email} has pending error. Please re-add the account, see https://useapi.net/docs/start-here/setup-flowmusic`);
        process.exit(1);
    }

    const promptData = await fs.readFile(promptFile, 'utf8');
    const prompts = JSON.parse(promptData);
    console.log(`Total number of prompts to process`, prompts.length);

    let warnings = [];

    // Parameters accepted by this script for the music endpoint.
    // See https://useapi.net/docs/api-flowmusic-v1/post-flowmusic-music for the full parameter set.
    const supportedParams = ['prompt', 'instrumental', 'lyrics', 'ghostwriter'];

    const invalidKeys = (prompt) => Object.keys(prompt).filter(key => !key.startsWith('__') && !supportedParams.includes(key));

    for (let i = 1; i <= prompts.length; i++) {
        const prompt = prompts[i - 1];
        const { prompt: text, ghostwriter } = prompt;

        const notSupported = invalidKeys(prompt);
        if (notSupported.length)
            warnings.push(`⚠️  Following params not supported: ${notSupported.join(',')}. Prompt ${i}`);

        if (!text || typeof text !== 'string' || text.trim().length === 0)
            warnings.push(`⚠️  Please specify a non-empty prompt. Prompt ${i}`);

        if (typeof text === 'string' && text.length > 10000)
            warnings.push(`⚠️  prompt exceeds 10,000 characters. Prompt ${i}`);

        if (ghostwriter !== undefined && !['standard', 'pro'].includes(ghostwriter))
            warnings.push(`⚠️  ghostwriter must be 'standard' or 'pro'. Prompt ${i}`);
    }

    if (warnings.length > 0) {
        warnings.forEach(warning => console.warn(warning));
        console.error(`⛔ Execution stopped due to warnings.`);
        process.exit(1);
    }

    for (let i = 0; i < prompts.length; i++) {
        const prompt = prompts[i];
        let retries429 = 0;
        while (true) {
            const responseCode = await submitMusic(apiToken, email, prompt, i + 1);
            if (responseCode == 429) {
                if (++retries429 > MAX_429_RETRIES) {
                    console.error(`⛔ Gave up on prompt #${i + 1} after ${MAX_429_RETRIES} retries — all accounts still busy.`);
                    await fs.appendFile(ERRORS_FILE, `429 (gave up after ${MAX_429_RETRIES} retries),#${i + 1}\n`);
                    break;
                }
                await sleep(SLEEP_429);
            }
            else
                if (responseCode == 402 || responseCode == 596) {
                    process.exit(1);
                } else
                    break;
        }
    }
}

// Utility function to check if a file exists
async function fileExists(path) {
    try {
        await fs.access(path);
        return true;
    } catch {
        return false;
    }
}

// Function to prompt user input
async function promptUser(query) {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    return new Promise((resolve) => rl.question(query, answer => {
        rl.close();
        resolve(answer);
    }));
}

function diffInMinutesAndSeconds(date1, date2) {
    const diffInSeconds = Math.floor((date2 - date1) / 1000);
    return `${Math.floor(diffInSeconds / 60)} minutes ${diffInSeconds % 60} seconds`;
};

main();

Examples

These are real songs generated with Lyria 3 Pro through the Flow Music API — each from a single text prompt, exactly as the workflow above produces them. Full prompts and curl for each are in the FlowMusic API v1 launch post.

“Euphoric Currents”, an instrumental liquid drum & bass track (instrumental: true), from FlowMusic API v1: Powered by Lyria 3 Pro:

“Solid Ground”, an emotional pop ballad with a soaring female vocal (model-written lyrics), from FlowMusic API v1: Powered by Lyria 3 Pro:

“Running on Empty”, an epic power ballad rendered from custom [Verse]/[Chorus] lyrics, from FlowMusic API v1: Powered by Lyria 3 Pro:

For more samples — including extend, cover, remix, studio effects, and AI-generated cover art — see the full launch post.

Related tutorials: four AI music APIs on the same six briefs, AI music with the Mureka API and AI music APIs compared.

Frequently asked questions

Is there a Lyria 3 Pro API? Through useapi.net, yes: the Flow Music API runs Lyria 3 Pro, and the newer Lyria 3.5, on your Flow Music website subscription through a standard REST endpoint, with cover, remix, extend, replace, effects and stem-splitting on top of plain generation. Google offers no public Flow Music API of its own (as of October 2026). You connect the account once at Setup Flow Music.

How much does it cost? Through useapi.net, a Lyria song costs about 0.8¢ on Flow Music Member billed yearly ($48 a month for 30,000 credits, about 6,000 songs), against 8¢ a song on Google’s Gemini API (as of October 2026). You pay nothing per song on top of the Flow Music subscription, and Google AI Plus, Pro and Ultra include the Starter, Plus and Member plans. See Pricing for the monthly plans.

Is this a Suno or Udio alternative? Through useapi.net, yes. Like Suno and Udio, the Flow Music API generates full songs with vocals from a single text prompt, but it runs on Google DeepMind’s Lyria models and adds cover, remix, extend and stem-splitting over REST. It also sings your own [Verse]/[Chorus] lyrics word for word, or makes an instrumental when you set instrumental: true.

Do I need a Google Cloud project or API key? Through useapi.net, no. You call the API with a useapi.net API token and connect the Google account you use at flowmusic.app once during setup. Google’s own Lyria API runs through the Gemini API instead, which needs a Google Cloud project and an API key. One useapi.net account connects up to 50 Flow Music accounts, 3 on each subscription.

Can I cover, extend, or split a song into stems? Through useapi.net, yes. The music/edit endpoint takes any generated clip and runs cover, remix, extend (up to 300 seconds), replace, effect, or stems, which splits it into drums, bass, vocals and other. Each edit spends credits from the same Flow Music subscription. See Custom lyrics, instrumentals, and editing above.

Conclusion

Visit our Discord Server or Telegram Channel for any support questions and concerns.

The full runnable example is in the flowmusic-api GitHub repo.

The same calls are available as tools on the hosted Flow Music MCP server for Claude Code, Cursor and VS Code.