Laravel integration guide

Laravel Music API

Laravel developers who want a music generation feature using the framework's own HTTP client and queue.

The approach

Laravel already includes an HTTP client and a queue, so no extra package is needed. Submit the generation from a controller and return the task_id immediately, then poll the task endpoint from a queued job so a web request is never held open for the full generation.

Install

# Laravel ships the HTTP client and queue system, no extra package

How it works

  1. 1

    Add MUSICAPI_KEY to your .env. The HTTP client and queues ship with Laravel.

  2. 2

    In a controller action, POST to /sonic/create with the Http facade and return the task_id.

  3. 3

    Dispatch a queued job with that task_id so the polling runs off the web request.

  4. 4

    In the job, GET /sonic/task/{id} and treat an HTTP 202 or a not_ready body as keep waiting.

  5. 5

    When the terminal response arrives, persist audio_url from each item in data.

Full working example

Copy this, set the MUSICAPI_KEY environment variable, and run it. It is a real request against the live API.

php
<?php
// app/Http/Controllers/MusicController.php  -- submit a generation
namespace App\Http\Controllers;

use Illuminate\Support\Facades\Http;

class MusicController extends Controller
{
    private string $api = 'https://api.musicapi.ai/api/v1';

    public function create()
    {
        $res = Http::withToken(env('MUSICAPI_KEY'))
            ->post($this->api . '/sonic/create', [
                'custom_mode' => false,
                'mv'          => 'sonic-v5',
                'gpt_description_prompt' => 'warm acoustic podcast intro',
            ])
            ->throw();

        return response()->json(['task_id' => $res->json('task_id')]);
    }
}

<?php
// app/Jobs/WaitForMusic.php  -- poll off the request in a queued job
namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Http;

class WaitForMusic implements ShouldQueue
{
    use Queueable;

    public function __construct(private string $taskId) {}

    public function handle(): void
    {
        $api = 'https://api.musicapi.ai/api/v1';
        while (true) {
            $poll = Http::withToken(env('MUSICAPI_KEY'))
                ->get($api . '/sonic/task/' . $this->taskId);

            if ($poll->status() === 202) {
                sleep(5);
                continue;
            }
            $body = $poll->json();
            if (($body['type'] ?? null) === 'not_ready') {
                sleep(5);
                continue;
            }
            foreach ($body['data'] ?? [] as $song) {
                // persist $song['audio_url']
            }
            return;
        }
    }
}

Pricing

MusicAPI is pay-as-you-go with credit packs, plus predictable monthly subscriptions. The per-credit rate is the same across packs and subscriptions. See the pricing page for current rates, free credits, and volume options.

FAQ

Should I use env() or config() for the key?

In code paths that run with cached config, env() returns null. The robust pattern is to map MUSICAPI_KEY into config/services.php and read it with config(). env() is shown here for brevity.

Why a queued job instead of polling in the controller?

A generation takes a couple of minutes. Polling in the controller blocks a worker and the user's request. A queued job, or a webhook, keeps the request fast.

Does this need Guzzle installed separately?

No. Laravel's Http facade wraps Guzzle and ships by default, so you do not add it yourself. The same REST contract applies if you call Guzzle directly.

Build it in 5 minutes

Get free credits on signup and run real generations before any payment. No credit card required to start.

API details verified 2026-05-18. The API surface evolves; the pricing page always has current rates.