Schema
Here’s the data contract for submitting a release. The MVP fields below remain the hard runtime requirements for backwards compatibility. New REST/MCP clients should also provide DSP selection, label, C/P copyright credits, track type, and role credits when collecting metadata.
You can fetch the schema in two ways (after MCP authentication):
get_release_schematoolresources/readformcp://schemas/release-required
Before building payloads, agents should also read mcp://docs/metadata-rules-hitlist (or call get_metadata_rules) for policy rules that are not all expressed in the JSON schema: generic artist names, UPC, AI disclosure, cover songs, and more.
Most clients load resources automatically after resources/list, but you can always call them directly if you need a fresh copy.
Release Fields
| Field | Required | Notes |
|---|---|---|
title | Yes | Release title |
primary_artist_name | Yes | Main artist |
primary_artists | No | Every primary artist in credit order, each with their own store profile links. See Collaborations |
genre | Yes | Music genre |
release_date | Yes | Format: YYYY-MM-DD |
cover_art_file_url | Yes | From upload endpoint |
distribution_store_ids | New clients | Non-empty supported DSP store IDs, or null for all supported stores |
label | New clients | Record label name |
sub_genre | No | Optional second genre |
audio_language | No | Release audio language ISO code, e.g. en |
metadata_language | No | Release metadata language ISO code, e.g. en |
pline_year / pline_owner | New clients | P-line copyright credit |
cline_year / cline_owner | New clients | C-line copyright credit |
contributors | New clients | Role credits such as Producer and Engineer |
artist_locals | No | Localized artist names using Revelator languageId |
Track Fields
| Field | Required | Notes |
|---|---|---|
title | Yes | No placeholders |
primary_artists | No | Primary artists for this track when they differ from the release. Same shape as the release field |
audio_file_url | Yes | From upload endpoint |
explicit_flag | Yes | Boolean |
writers | Yes | Array, at least one |
track_type | New clients | original, cover, or public_domain |
isrc | No | Optional valid ISRC |
language | No | Track language ISO code, e.g. en |
lyrics | No | Plain text lyrics |
preview_start_seconds | No | Preview/clip start time in seconds. Defaults to 15 |
pline_year / pline_owner | New clients | Track-level P-line copyright credit |
cline_year / cline_owner | New clients | Track-level C-line copyright credit |
contributors | New clients | Role credits such as Producer and Engineer |
artist_locals | No | Localized artist names using Revelator languageId |
Validation Rules
- Single tracks:
track.titlemust matchrelease.title, andtrack.title_versionmust matchrelease.title_version - Writers: Each
writer.namemust be a full legal name (first + last). See Name validation for the exact rule. - Contributors:
contributor.namemust be a full legal name only whencontributor.roleis in the songwriter family (Songwriter,Composer,Lyricist,Writer). Other roles (Producer,Engineer,Remixer,Featuring) are professional credits rather than publishing registrations and may use a mononym or stage name. - Explicit flag: Must be boolean
trueorfalse - Primary artist: Must be a real artist/band name, not generic labels like “Christmas Music” or “Yoga Music” (see Agent Setup /
mcp://docs/metadata-rules-hitlist) - UPC: Never user-supplied, ONCE generates at distribution
- DSP selection: New clients should set
release.distribution_store_idsfromget_distribution_stores; usenullfor all supported stores and never send an empty array - Remix: Do not send
remixastrack_type; usetitle_version: "Remix"and aRemixercontributor - Collaborations: Send every primary artist in
primary_artists, in credit order, each with their own profile links (see below) - Localization:
artist_localsis supported for artist names; localized release/track title and version fields are not persisted yet
Name validation
The “full legal name” rule applied to tracks[].writers[].name and to songwriter-role
contributors[].name is script-agnostic. A name passes when either:
- It has two or more parts separated by whitespace (ASCII space or
U+3000ideographic space) or by a katakana middle dot (・,・). Each part must contain a letter. Parts in Latin, Cyrillic, Greek, Arabic, and other alphabetic scripts need at least 2 characters, so initials such asJ Smithare rejected. Parts in Han, Hiragana, Katakana, or Hangul may be a single character, because single-character given and family names are ordinary there (林 明). - Or it is written entirely in Han, Hiragana, Katakana, or Hangul with no separator and is
at least 2 characters long. These scripts conventionally write a full name unspaced
(
山田太郎), so requiring a separator would reject correct metadata.
Send names in the script the rightsholder uses. Do not romanize a songwriter’s name to satisfy validation.
Failed validation returns 422 with a details array naming each offending field:
{
"type": "validation_error",
"code": "validation_failed",
"message": "Track 1: writer \"Madonna\" must be a full legal name (first and last) (tracks[0].writers[0].name).",
"details": [
"Track 1: writer \"Madonna\" must be a full legal name (first and last) (tracks[0].writers[0].name)."
]
}Collaborations: one profile link per artist
A release credits one main primary artist plus any number of co-primary artists. Send them
together in primary_artists, in credit order, and give each artist their own store profile
links so every artist maps to their existing Spotify and Apple Music page:
{
"release": {
"title": "Collab",
"primary_artist_name": "FussyCraft",
"primary_artists": [
{
"name": "FussyCraft",
"spotify_artist_url": "https://open.spotify.com/artist/SPOTIFY_ARTIST_ID",
"apple_music_artist_url": "https://music.apple.com/us/artist/fussycraft/1234567890"
},
{
"name": "Michal - Mad Max",
"spotify_artist_url": "https://open.spotify.com/artist/SPOTIFY_ARTIST_ID",
"apple_music_artist_url": "https://music.apple.com/us/artist/michal-mad-max/987654321"
}
]
}
}- The first entry is the main primary artist. When you also send
primary_artist_name, it must match that first entry, and a mismatch is rejected rather than silently reordered. - Every following entry is added as a
Primary Artistcontributor, in the order you send them. - Links must be artist profile URLs:
https://open.spotify.com/artist/…andhttps://music.apple.com/<storefront>/artist/<slug>/<id>. Album, song, and playlist links are rejected with a422naming the field. A bare Spotify artist ID or aspotify:artist:URI works too. - Omit any link you don’t have. An artist with no links is still credited, ONCE just matches them by name as before.
soundcloud_artist_urlandmeta_artist_urlare accepted on the same entries.- Tracks accept
primary_artistswith the same shape, for releases where tracks are credited to different artists.
If you already keep your links in parallel lists, send them positionally instead. Entry N maps
to primary artist N, and null holds a position for an artist you have no link for:
{
"release": {
"primary_artist_name": "FussyCraft",
"contributors": [{ "name": "Michal - Mad Max", "role": "Primary Artist" }],
"spotify_artist_urls": ["https://open.spotify.com/artist/…", "https://open.spotify.com/artist/…"],
"apple_music_artist_urls": ["https://music.apple.com/us/artist/…", null]
}
}Sending more links than there are primary artists is rejected, so a miscounted list fails loudly
instead of silently crediting the wrong artist. Single-artist releases can keep using the flat
spotify_artist_url / apple_music_artist_url fields, and nothing changes for them.
AI Content & Billing
Every audio upload is run through the Vobile/Pex AI Song Detector. You can also declare AI content explicitly on a track:
| Field | Type | Notes |
|---|---|---|
contains_ai | boolean | Set to true if the track contains AI-generated content. Maps to Revelator track property 8 (Includes AI). |
Use the detect_audio_ai tool to read the cached detection result (predicted model + confidence) before submission.
Billing is 1 credit per human song and 2 credits per AI-detected song on every surface (regular MCP, AIMD, in-app upload). Provenance is recorded for analytics but does not change the rate.
Example Payload
{
"release": {
"title": "My Release",
"primary_artist_name": "Artist Name",
"genre": "Pop",
"sub_genre": "Dance Pop",
"release_date": "2026-02-01",
"label": "Artist Name Records",
"audio_language": "en",
"metadata_language": "en",
"distribution_store_ids": [1, 9, 13, 319],
"pline_year": "2026",
"pline_owner": "Artist Name Records",
"cline_year": "2026",
"cline_owner": "Artist Name Records",
"cover_art_file_url": "/api/files/cover-art/USER_ID/cover.jpg",
"contributors": [
{ "name": "First Producer", "role": "Producer" },
{ "name": "First Engineer", "role": "Engineer" }
]
},
"tracks": [
{
"title": "My Release",
"primary_artist_name": "Artist Name",
"audio_file_url": "/api/files/audio/USER_ID/track.wav",
"explicit_flag": false,
"track_type": "original",
"language": "en",
"pline_year": "2026",
"pline_owner": "Artist Name Records",
"cline_year": "2026",
"cline_owner": "Artist Name Records",
"writers": [{ "name": "First Last" }],
"contributors": [
{ "name": "First Producer", "role": "Producer" },
{ "name": "First Engineer", "role": "Engineer" }
]
}
]
}