Django integration guide

Django Music API

Django developers who need on-demand music generation without blocking a web worker on a long request.

The approach

MusicAPI is a plain REST API, so a Django view talks to it with requests. Submit the generation in the view and return the task_id immediately. Run the minute-long poll off the request thread in a Celery task or a management command so a web worker is never blocked.

Install

pip install requests

How it works

  1. 1

    Install requests and read MUSICAPI_KEY from the environment, not from settings committed to the repo.

  2. 2

    In a view, POST to /sonic/create and return the task_id to the client right away.

  3. 3

    Hand the task_id to a Celery task or a management command that polls /sonic/task/{id}.

  4. 4

    Treat an HTTP 202 or a not_ready body as keep waiting, sleeping a few seconds between polls.

  5. 5

    When the terminal response arrives, read audio_url from each item in data and store or stream it.

Full working example

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

python
# views.py  -- submit a generation
import os
import requests
from django.http import JsonResponse
from django.views.decorators.http import require_POST

API = "https://api.musicapi.ai/api/v1"
HEADERS = {
    "Authorization": f"Bearer {os.environ['MUSICAPI_KEY']}",
    "Content-Type": "application/json",
}

@require_POST
def create_music(request):
    resp = requests.post(
        f"{API}/sonic/create",
        headers=HEADERS,
        json={
            "custom_mode": False,
            "mv": "sonic-v5",
            "gpt_description_prompt": "calm piano for a focus timer",
        },
        timeout=30,
    )
    resp.raise_for_status()
    return JsonResponse({"task_id": resp.json()["task_id"]})

# tasks.py  -- poll off the request thread (Celery)
import time
from celery import shared_task

@shared_task
def wait_for_music(task_id):
    while True:
        poll = requests.get(
            f"{API}/sonic/task/{task_id}", headers=HEADERS, timeout=30
        )
        if poll.status_code == 202:
            time.sleep(5)
            continue
        poll.raise_for_status()
        body = poll.json()
        if body.get("type") == "not_ready":
            time.sleep(5)
            continue
        return [s["audio_url"] for s in body.get("data", [])]

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

Can I poll inside the view instead?

You can for a quick prototype, but a generation takes a couple of minutes and that ties up a worker and the browser request. A Celery task or a webhook is the production pattern.

Is there a Django-specific SDK?

None is needed. The REST API is language-agnostic and requests is enough. A typed Python SDK is on the roadmap. Until then this REST flow is the supported path.

How do I keep the API key out of the client?

Read it from a server environment variable. All calls happen in the Django backend, so the key is never sent to the browser.

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.