Go integration guide
Go Music API
Go developers who want to add music generation to a service or CLI without hosting an audio model or pulling in dependencies.
The approach
MusicAPI is a plain JSON REST API, so Go needs nothing beyond net/http and encoding/json from the standard library. Submit a job to POST /sonic/create, then poll GET /sonic/task/{task_id} on an interval. Generation runs a couple of minutes, so do the polling in a goroutine or a queued worker rather than blocking a request handler.
Install
go mod init example.com/musicHow it works
- 1
Initialise a module. No third-party packages are needed; net/http and encoding/json cover everything.
- 2
Create an API key in the MusicAPI dashboard and read it from the MUSICAPI_KEY environment variable.
- 3
POST to /sonic/create with custom_mode, mv, and gpt_description_prompt, and decode the returned task_id.
- 4
Poll GET /sonic/task/{task_id}. An HTTP 202, or a body with type set to not_ready, means keep waiting.
- 5
When the job finishes, read the data array and use each song's audio_url, a ready-to-stream MP3.
Full working example
Copy this, set the MUSICAPI_KEY environment variable, and run it. It is a real request against the live API.
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
)
const api = "https://api.musicapi.ai/api/v1"
func main() {
key := os.Getenv("MUSICAPI_KEY")
// 1. Submit a generation job.
body, _ := json.Marshal(map[string]any{
"custom_mode": false,
"mv": "sonic-v5",
"gpt_description_prompt": "driving techno for a workout app",
})
req, _ := http.NewRequest("POST", api+"/sonic/create", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+key)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
var created struct {
TaskID string `json:"task_id"`
}
json.NewDecoder(res.Body).Decode(&created)
res.Body.Close()
// 2. Poll until the audio is ready.
for {
poll, _ := http.NewRequest("GET", api+"/sonic/task/"+created.TaskID, nil)
poll.Header.Set("Authorization", "Bearer "+key)
resp, err := http.DefaultClient.Do(poll)
if err != nil {
panic(err)
}
if resp.StatusCode == http.StatusAccepted {
resp.Body.Close()
time.Sleep(5 * time.Second)
continue
}
var task struct {
Type string `json:"type"`
Data []struct {
Title string `json:"title"`
AudioURL string `json:"audio_url"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&task)
resp.Body.Close()
if task.Type == "not_ready" {
time.Sleep(5 * time.Second)
continue
}
for _, song := range task.Data {
fmt.Println(song.Title, song.AudioURL)
}
break
}
}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
Do I need a Go SDK or client library?
No. The example uses only net/http and encoding/json from the standard library. MusicAPI is a JSON REST API, so any HTTP client works and there is no dependency to keep up to date.
How do I know when the song is ready?
Poll GET /sonic/task/{task_id}. While the job runs you get an HTTP 202 or a body with type set to not_ready. When it finishes, the response carries a data array where each item has a streamable audio_url.
Where should the polling loop run?
Not in an HTTP handler. A generation takes a couple of minutes, so run the loop in a goroutine, a background worker, or react to a webhook, and keep the user request fast.
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-06-26. The API surface evolves; the pricing page always has current rates.