REST API reference

Authentication, resumable uploads, render jobs, status polling and downloads over HTTP.

The Spatializer REST API turns a set of stems into delivery masters over plain HTTP. One request can produce both a Dolby Atmos master and an Eclipsa Audio (IAMF) master, and a 5.1 MP4 demo rendition is available for local playback. Files are uploaded with the tus resumable upload protocol, processing is followed by polling a status endpoint, and masters are downloaded when they are ready.

This page is for developers who embed immersive audio in their own product or pipeline. It documents the base URL, authentication, the catalog endpoints, music creation, resumable uploads, status polling, downloads and HTTP error codes. The REST API is separate from the MCP server and the A2A agent: it uses its own key and its own endpoints.

Databricks accelerator routing tracks to the MCP server, the A2A agent and the Spatializer REST API
The REST API is one of three routes to Spatial9, used when you already have stems and need delivery masters.

Base URL and versioning

ItemValue
Base URLhttps://api.spatializer.spatial9.ai/api/v0.0.1
Versionv0.0.1, part of the path
FormatJSON for requests and responses, binary for uploads and downloads

All paths on this page are relative to the base URL.

Authentication

Send your API key in the Authorization header exactly as issued, with no Bearer prefix.

HeaderValue
AuthorizationYOUR_API_KEY

The REST API key is not the s9_ key used by MCP and A2A. Integrations such as the Databricks accelerator store it as spatializer_api_key. Request access with Get API Access on the API page.

curl -H "Authorization: YOUR_API_KEY" https://api.spatializer.spatial9.ai/api/v0.0.1/profile

Workflow

  1. Read the catalog with GET /instruments and, optionally, GET /presets.
  2. Create a music with POST /musics, choosing the output formats.
  3. Upload every stem, the optional stereo reference and any ADM file with tus.
  4. Poll GET /musics/{id}/status until processing completes.
  5. Download each master with GET /musics/{id}/download.

Endpoint summary

MethodPathBehaviourResponses
GET/instrumentsInstruments as a JSON array, each with its UUID200
GET/presetsPresets as a JSON array200
GET/presets/{preset_id}/instrumentsInstruments of a preset, only those with bus=false200; 404 Preset not found
GET/profileProfile of the authenticated account200
GET/musicsMusics created by the user200
POST/musics?formats=atmos,iamfCreate a music and return the created music object200
POST/musics/{id}/{kind}Start a tus upload of a stem, stereo or ADM file201; 400; 413; 415
HEAD/musics/{music_id}/{kind}/{id}Current offset of an upload200; 403; 404
PATCH/musics/{music_id}/{kind}/{id}Send a chunk204; 200; 409
GET/musics/{id}/statusProcessing status200
GET/musics/{id}/download?format=Master file or demo MP4200

Catalog endpoints

GET /instruments

Returns every instrument as a JSON array. Each entry carries the UUID you use as a key in POST /musics. Read this list at run time rather than hard-coding UUIDs.

curl -H "Authorization: YOUR_API_KEY" https://api.spatializer.spatial9.ai/api/v0.0.1/instruments

GET /presets

Returns the presets as a JSON array.

GET /presets/{preset_id}/instruments

ParameterInDescription
preset_idpathId of a preset from GET /presets

Returns the instruments of the preset, limited to entries with bus=false. An unknown preset returns 404 with the message Preset not found.

GET /profile and GET /musics

GET /profile returns the profile of the account that owns the key. GET /musics returns the musics that account has created. Use GET /profile as a cheap check that a key is valid.

Creating a music

POST /musics

ParameterInTypeDescription
formatsquerystringatmos, iamf or both, comma-separated
namebodystringName of the music
stereobodystringOptional file name of a stereo reference
instrumentsbodyobjectKeys are instrument UUIDs from /instruments; values are arrays of stem file names
{"name":"Sample Music","stereo":"Sample Music.wav","instruments":{"1e9d541b-7286-4023-be7b-5f943644842c":["BASS.wav"],"0409683b-3bbd-419c-8db4-579f7cc6b22c":["DRUMS.wav"],"57a7464e-fe2e-41b5-aa78-215ea8fc8785":["LEAD VOCALS.wav"]}}
curl -X POST "https://api.spatializer.spatial9.ai/api/v0.0.1/musics?formats=atmos,iamf" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @music.json

The response is the created music object. Store its id; every later call uses it. The UUIDs above are examples only.

The stereo reference keeps the spatial version in sync with the original mix. If you name a stereo file, you must upload it. Every file name listed in instruments must also be uploaded, and only those names are accepted.

Resumable uploads

Stems, the stereo reference and ADM files are uploaded with the tus protocol. The {kind} path segment is stems, stereo or adm.

Upload headers

HeaderUsed onValue
Tus-ResumableAll tus requestsProtocol version, for example 1.0.0
Upload-LengthPOSTTotal file size in bytes
Upload-MetadataPOSTfilename <base64 file name>
Upload-OffsetPATCHByte offset of this chunk
Content-TypePATCHapplication/offset+octet-stream

Start an upload

POST /musics/{id}/{kind} creates the upload and returns 201 with a Location header. The Location may be relative; if it is, prefix it with the base URL.

curl -i -X POST "https://api.spatializer.spatial9.ai/api/v0.0.1/musics/MUSIC_ID/stems" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Tus-Resumable: 1.0.0" \
  -H "Upload-Length: 52428800" \
  -H "Upload-Metadata: filename QkFTUy53YXY="
StatusMeaning
201Upload created; read the Location header
400The filename is missing from Upload-Metadata or is not part of this music
413The chunk exceeds the server Tus-Max-Size
415Content-Type must be application/offset+octet-stream

Send chunks

PATCH /musics/{music_id}/{kind}/{id} sends the next chunk at the current offset.

curl -X PATCH "$UPLOAD_URL" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Tus-Resumable: 1.0.0" \
  -H "Upload-Offset: 0" \
  -H "Content-Type: application/offset+octet-stream" \
  --data-binary @chunk-000.bin
StatusMeaning
204Chunk accepted and more remain; the offset is updated
200Final chunk accepted; the body is the music object
409Upload-Offset does not match the server offset

The Databricks accelerator sends 32 MB chunks. Choose a chunk size that stays under the server Tus-Max-Size.

Resume an upload

HEAD /musics/{music_id}/{kind}/{id} returns the current offset in the Upload-Offset header. After a network failure or a 409, read the offset and continue from it.

StatusMeaning
200Upload-Offset holds the bytes received so far
403No access to this upload
404The upload does not exist

Python upload helper

import base64, os, requests

BASE = "https://api.spatializer.spatial9.ai/api/v0.0.1"
HEADERS = {"Authorization": os.environ["SPATIALIZER_API_KEY"], "Tus-Resumable": "1.0.0"}
CHUNK = 32 * 1024 * 1024

def upload(music_id: str, kind: str, path: str) -> None:
    name = os.path.basename(path)
    size = os.path.getsize(path)
    meta = "filename " + base64.b64encode(name.encode()).decode()
    r = requests.post(f"{BASE}/musics/{music_id}/{kind}",
                      headers={**HEADERS, "Upload-Length": str(size), "Upload-Metadata": meta})
    r.raise_for_status()
    location = r.headers["Location"]
    url = location if location.startswith("http") else BASE + location
    offset = 0
    with open(path, "rb") as f:
        while offset < size:
            f.seek(offset)
            chunk = f.read(CHUNK)
            r = requests.patch(url, data=chunk, headers={**HEADERS, "Upload-Offset": str(offset),
                               "Content-Type": "application/offset+octet-stream"})
            if r.status_code == 409:
                offset = int(requests.head(url, headers=HEADERS).headers["Upload-Offset"])
                continue
            r.raise_for_status()
            offset += len(chunk)

This helper is a sketch. Add retries with backoff for network errors and log progress without logging the key.

Status polling

GET /musics/{id}/status

Returns the processing status of a music.

curl -H "Authorization: YOUR_API_KEY" https://api.spatializer.spatial9.ai/api/v0.0.1/musics/MUSIC_ID/status

Poll every 30-60 seconds. Pipelines that run on a schedule, every 10-15 minutes, can instead check status once per run. The Databricks accelerator treats a master as ready when the download endpoint answers 200.

Downloads

GET /musics/{id}/download

ParameterInValuesDefault
formatqueryatmos, iamf or demoatmos
FormatContent
atmosDolby Atmos master
iamfEclipsa Audio master in IAMF
demo5.1 MP4 rendition of the Atmos master for local playback
curl -L -o master-iamf.bin -H "Authorization: YOUR_API_KEY" "https://api.spatializer.spatial9.ai/api/v0.0.1/musics/MUSIC_ID/download?format=iamf"

Download only the formats you requested in POST /musics. Store masters in governed storage and record the music id alongside them so you can trace every file back to its request.

Error handling

StatusTypical causeAction
400Upload filename missing or not part of the musicCheck Upload-Metadata and the instruments list
401 or 403Missing, wrong or unauthorized keyCheck the Authorization header; do not add Bearer
404Unknown preset, music or uploadCheck the id
409Upload offset mismatchSend HEAD, then resume from the returned offset
413Chunk too largeUse smaller chunks
415Wrong Content-Type on PATCHUse application/offset+octet-stream

Retry network errors and 5xx responses with exponential backoff. Do not retry 4xx responses unchanged; fix the request first. For shared rules on retries, idempotency and logging, see Limits, quotas and errors.

When to use the REST API

You haveUse
Stems and need Dolby Atmos and IAMF mastersREST API
A stereo master and want the full Spatial9 render with binaural and YouTube MP4MCP server
An agent that hands over long tasksA2A agent
A product embedding audio for its own usersREST API

Next steps

Go deeper on the blog