Validations
Validation endpoints let you check whether a release, track, or video is ready for distribution or whether a release is eligible for takedown.
They are read-only GET requests that run the same validation rules used by the corresponding distribution or takedown
workflow. They report errors and warnings without submitting anything or changing state.
| Endpoint | Purpose |
|---|---|
| Validate Delivery | Checks whether a release is ready to be delivered to the selected stores. |
| Validate Track | Checks a track’s own metadata without release context. |
| Validate Video | Checks a video’s own metadata without release context. |
| Validate Takedown | Checks whether a release can be taken down from the selected stores. |
Delivery and takedown are validated separately because they answer different questions: delivery checks whether a release is complete and configured for distribution, while takedown checks whether it can be removed from its current stores.
Track and video validation is narrower and checks only the asset’s own metadata. See Validating a Single Asset.
Catalog endpoints deliberately perform less validation when saving data so that incomplete records can be created and finished later. A record that saves successfully can still fail validation.
Reading the Response
Every validation endpoint on this page returns the same three-part shape.
hasBlockingErrors is the short answer. It is true when any result—in metadataErrors or in any store’s bucket
under perDistributorStoreErrors—has severity: error. Warnings never set it, so a response full of warnings and no
errors still reports false.
hasBlockingErrors is an aggregate result. It is true when blocking errors exist anywhere in the validation
response, including under perDistributorStoreErrors.
This does not necessarily mean that every workflow will be rejected. If validation is scoped to specific stores, check the errors reported for those stores to determine whether the intended operation can proceed.
metadataErrors holds the common results—rules that apply regardless of where the asset is going. An empty array
means the asset passed every common rule.
perDistributorStoreErrors holds the per-DSP results, one entry per store, each with its own errors array. A
store that appears with an empty errors array was checked and passed, which is meaningfully different from a store
that does not appear at all because it was never checked.
Where a result sits also tells you how much it blocks:
- An
errorinmetadataErrorsblocks every destination. There is no delivery to be had until it is fixed. - An
errorunder a single store blocks that store only. You can deliver to the stores that came back clean and come back to the rest, so a store you cannot satisfy today does not hold up the others.
A rule that applies to several destinations may appear under each affected store. An error repeated across multiple stores therefore does not necessarily represent multiple underlying problems.
Reading an Error
| Field | Meaning |
|---|---|
objectId | ID of the specific object that failed. On a release this is often a track, video, or artist ID, not the release ID—see Errors Cascade below. |
objectType | What objectId refers to: release, track, video, artist, or unspecified. |
errorMessage | The human-readable message. Some messages contain HTML markup such as <b>. |
severity | error blocks distribution. warning never blocks—it is surfaced for acknowledgement. |
category | metadata for content problems, distributionConfiguration for setup problems. See Fixing What Comes Back. |
Selecting Stores
Pass distributorStoreIds to check specific stores:
GET /supply-chain/v1/releases/8801/deliver/validate?distributorStoreIds=1&distributorStoreIds=9
Omit the parameter entirely and every DSP enabled for your organization is checked. This is the simplest way to answer “is this ready?” without needing to know which stores your organization has enabled.
Store IDs come from the V1.0 store lookup. Call it with activeOnly=true, which restricts the response to stores that
are currently active:
GET /common/lookup/stores?activeOnly=true
From that response, use only entries where both isActive and display are true. An entry missing either flag is
not fully available to your organization.
Validation treats an unavailable or unrecognised store ID leniently: it is silently skipped rather than rejected, so it
simply will not appear in perDistributorStoreErrors, and the call returns a 200 with an empty array instead of an
error. Verify your store IDs rather than reading an empty result as a pass—Deliver and Takedown
are not lenient about this and reject the entire request over one unavailable store.
Validating a Single Asset
Single-asset validation checks whether a track or video has the metadata required by the common validation rules and the selected stores. It does not evaluate the asset as part of a release; use delivery validation to validate the release in its full context.
Fixing What Comes Back
The category field indicates where the problem needs to be fixed:
metadata— update the affected object through the Catalog API.distributionConfiguration— update the relevant Supply Chain configuration.
See Releases, Tracks, Videos, Artists, or the relevant Supply Chain configuration page.
Warnings
A warning never blocks distribution. Warnings identify conditions worth reviewing before distribution, but the release
can still be delivered while warnings are present.
Treat warnings as informational results rather than failures.
Validate Delivery
Delivery validation is a dry run of everything that would block distribution. It loads the full release graph— tracks, videos, artist, contributors, prices, territory clearances, cover image—resolves which stores are in scope, and runs the release-wide rules and then the per-store rules against it. Nothing is created or updated.
Results arrive in two tiers:
metadataErrors— release-wide problems, identical regardless of destination. This is the largest rule set.perDistributorStoreErrors— evaluated separately for each store in scope.
/supply-chain/v1/releases/{releaseId}/deliver/validate Dry run of the delivery checks. Reports everything that would block or warn if the release were delivered—release-wide first, then per store.
Path Parameters
| Parameter | Description |
|---|---|
releaseId * integer | The ID of the release to validate. |
Query Parameters
| Parameter | Description |
|---|---|
distributorStoreIds integer[] | Stores to check, repeated once per ID. Omit to check every store available to your organization that accepts this release type. Naming stores explicitly validates exactly those, including ones that would not normally accept the release. Retrieved from GET /common/lookup/stores on the V1.0 API—see Selecting Stores above. |
Responses
object metadataErrors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to.release, track, video, artist, unspecified errorMessage string <b>. severity DistributionSeverityLevels error blocks distribution; warning does not.error, warning category ValidationCategory metadata for content problems, distributionConfiguration for setup problems such as missing prices or monetization policies.metadata, distributionConfiguration perDistributorStoreErrors DistributorStoreValidationItemModel[] errors array was checked and passed. distributorStoreId integer errors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to.release, track, video, artist, unspecified errorMessage string severity DistributionSeverityLevels error, warning category ValidationCategory metadata, distributionConfiguration hasBlockingErrors boolean true when any result in either array has severity: error; warnings never set it. false guarantees delivery will not be rejected by validation—it is the same flag the deliver call checks before it does anything./supply-chain/v1/releases/{releaseId}/deliver/validate curl -X GET "https://platform.revelator.com/supply-chain/v1/releases/8801/deliver/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/supply-chain/v1/releases/8801/deliver/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track level: The ISRC for the track 'Night Lights' is in the wrong format.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track level: <b>Stereo audio file</b> is required for distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Release level: The cover image for this release is missing.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4402,
"objectType": "artist",
"errorMessage": "Track level: Each artist field must contain only 1 artist name.",
"severity": "warning",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 1,
"errors": [
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Please define Standard track prices for this distributor store: iTunes.",
"severity": "error",
"category": "distributionConfiguration"
}
]
},
{
"distributorStoreId": 9,
"errors": []
},
{
"distributorStoreId": 307,
"errors": [
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Tracks monetization is required.",
"severity": "error",
"category": "distributionConfiguration"
}
]
}
]
} {
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track level: The ISRC for the track 'Night Lights' is in the wrong format.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track level: <b>Stereo audio file</b> is required for distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Release level: The cover image for this release is missing.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4402,
"objectType": "artist",
"errorMessage": "Track level: Each artist field must contain only 1 artist name.",
"severity": "warning",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 1,
"errors": [
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Please define Standard track prices for this distributor store: iTunes.",
"severity": "error",
"category": "distributionConfiguration"
}
]
},
{
"distributorStoreId": 9,
"errors": []
},
{
"distributorStoreId": 307,
"errors": [
{
"objectId": 8801,
"objectType": "release",
"errorMessage": "Tracks monetization is required.",
"severity": "error",
"category": "distributionConfiguration"
}
]
}
]
} Validate Track
Checks a single track’s own metadata against the common rules and then against each store in scope—identifiers, language, audio, artwork, and contributor requirements, plus any store-specific rules that apply to a track.
Release context is not evaluated; see Validating a Single Asset.
Stores are selected exactly as they are for delivery validation: omit distributorStoreIds to check every store
available to your organization that accepts tracks.
/supply-chain/v1/tracks/{trackId}/validate Dry run of the track-level checks. Reports everything on this track that would block or warn, without touching the release it belongs to.
Path Parameters
| Parameter | Description |
|---|---|
trackId * integer | The ID of the track to validate. |
Query Parameters
| Parameter | Description |
|---|---|
distributorStoreIds integer[] | Stores to check, repeated once per ID. Omit to check every store available to your organization that accepts tracks. Retrieved from GET /common/lookup/stores on the V1.0 API—see Selecting Stores above. |
Responses
object metadataErrors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to. Always track on this endpoint.track errorMessage string <b>. severity DistributionSeverityLevels error blocks distribution; warning does not.error, warning category ValidationCategory metadata on this endpoint—configuration rules are evaluated only at release level.metadata perDistributorStoreErrors DistributorStoreValidationItemModel[] errors array was checked and passed. distributorStoreId integer errors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to.track errorMessage string severity DistributionSeverityLevels error, warning category ValidationCategory metadata hasBlockingErrors boolean true when any result in either array has severity: error; warnings never set it./supply-chain/v1/tracks/{trackId}/validate curl -X GET "https://platform.revelator.com/supply-chain/v1/tracks/7701/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/supply-chain/v1/tracks/7701/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track Level: Providing a language is required for all tracks.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Some DSPs don't support emojis in metadata. Emojis will be removed automatically for those DSPs during delivery.",
"severity": "warning",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 1,
"errors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track that is used in audio release must have contributor from Producers & Engineers group as required by Apple.",
"severity": "error",
"category": "metadata"
}
]
},
{ "distributorStoreId": 9, "errors": [] },
{
"distributorStoreId": 307,
"errors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track does not have a minimum audio length of 20 sec that YouTube Content Id (307) requires.",
"severity": "error",
"category": "metadata"
}
]
}
]
} {
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track Level: Providing a language is required for all tracks.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Some DSPs don't support emojis in metadata. Emojis will be removed automatically for those DSPs during delivery.",
"severity": "warning",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 1,
"errors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track that is used in audio release must have contributor from Producers & Engineers group as required by Apple.",
"severity": "error",
"category": "metadata"
}
]
},
{ "distributorStoreId": 9, "errors": [] },
{
"distributorStoreId": 307,
"errors": [
{
"objectId": 7701,
"objectType": "track",
"errorMessage": "Track does not have a minimum audio length of 20 sec that YouTube Content Id (307) requires.",
"severity": "error",
"category": "metadata"
}
]
}
]
} Validate Video
Checks a single video’s own metadata against the common rules and then against each store in scope, including any store-specific rules that apply to a video.
Release context is not evaluated; see Validating a Single Asset.
Omitting distributorStoreIds checks every store available to your organization that accepts video.
/supply-chain/v1/videos/{videoId}/validate Dry run of the video-level checks. Reports everything on this video that would block or warn, without touching the release it belongs to.
Path Parameters
| Parameter | Description |
|---|---|
videoId * integer | The ID of the video to validate. |
Query Parameters
| Parameter | Description |
|---|---|
distributorStoreIds integer[] | Stores to check, repeated once per ID. Omit to check every store available to your organization that accepts video. Retrieved from GET /common/lookup/stores on the V1.0 API—see Selecting Stores above. |
Responses
object metadataErrors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to. Always video on this endpoint.video errorMessage string <b>. severity DistributionSeverityLevels error blocks distribution; warning does not.error, warning category ValidationCategory metadata on this endpoint—configuration rules are evaluated only at release level.metadata perDistributorStoreErrors DistributorStoreValidationItemModel[] errors array was checked and passed. distributorStoreId integer errors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to.video errorMessage string severity DistributionSeverityLevels error, warning category ValidationCategory metadata hasBlockingErrors boolean true when any result in either array has severity: error; warnings never set it./supply-chain/v1/videos/{videoId}/validate curl -X GET "https://platform.revelator.com/supply-chain/v1/videos/4501/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/supply-chain/v1/videos/4501/validate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: The video genre is missing. Select a genre before distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: No video file is linked. Link a video file before distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: The thumbnail is missing. Upload or generate a thumbnail before distribution.",
"severity": "error",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 9,
"errors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "This Official Music Video is not linked to an audio track. Link an audio track.",
"severity": "error",
"category": "metadata"
}
]
},
{ "distributorStoreId": 13, "errors": [] }
]
} {
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: The video genre is missing. Select a genre before distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: No video file is linked. Link a video file before distribution.",
"severity": "error",
"category": "metadata"
},
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: The thumbnail is missing. Upload or generate a thumbnail before distribution.",
"severity": "error",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{
"distributorStoreId": 9,
"errors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "This Official Music Video is not linked to an audio track. Link an audio track.",
"severity": "error",
"category": "metadata"
}
]
},
{ "distributorStoreId": 13, "errors": [] }
]
} Validate Takedown
Takedown validation is a dry run of the checks the takedown itself applies. A clean result means the takedown will not be rejected by validation. It matters because takedown is all-or-nothing: one ineligible store rejects the whole request, so checking first is the only way to find out which store is the problem without losing the call.
It asks a different question from delivery validation—not “is this release complete?” but “is it actually live on these stores, and does it carry what a takedown notice needs?”
Three things are checked, in order:
- The request itself.
releaseIdmust be1or greater,distributorStoreIdsmust contain no duplicates, and every ID must be a store the platform recognises. A release with no distributions at all fails here—there is nothing to take down. - That each requested store was actually delivered to. A store the release was never distributed to is reported with “Cannot takedown release … for store … if it was never distributed.”
- The per-store rules, below.
What Is Checked Per Store
| Check | Requirement |
|---|---|
| DSP-specific rules | Some stores add their own takedown requirements. Most do not. |
| UPC | Must be present and at most 13 digits. |
| Track audio | Every track needs a stereo audio file. An ISRC is required too. |
| Current store status | The release must be live and settled on that store—see below. |
A store fails the status check when the release:
- was never live there,
- is in the inspection queue—licence failed, hidden, or pending approval. It has to pass or fail inspection first,
- is still uploading,
- is already being taken down, or has been,
- is on a DSP no longer available to your organization, and is not in one of the in-flight states above.
/supply-chain/v1/releases/{releaseId}/takedown/validate Dry run of the takedown checks. Reports, per store, exactly why a takedown would be rejected—without queueing anything.
Path Parameters
| Parameter | Description |
|---|---|
releaseId * integer | The ID of the release to check. |
Query Parameters
| Parameter | Description |
|---|---|
distributorStoreIds integer[] | Stores to check, repeated once per ID. Omit to check every DSP enabled for your organization. Retrieved from GET /common/lookup/stores on the V1.0 API—see Selecting Stores above. |
Responses
object metadataErrors ValidationErrorModel[] perDistributorStoreErrors instead, repeated for each store they affect. objectId integer | null objectType ObjectTypes objectId refers to.release, track, video, artist, unspecified errorMessage string severity DistributionSeverityLevels error blocks the takedown; warning does not.error, warning category ValidationCategory metadata, distributionConfiguration perDistributorStoreErrors DistributorStoreValidationItemModel[] errors array means that store is clear to take down. Everything from the per-store table above is reported here, so a release-wide problem such as a missing UPC appears once under every store it blocks. distributorStoreId integer errors ValidationErrorModel[] objectId integer | null objectType ObjectTypes objectId refers to.release, track, video, artist, unspecified errorMessage string severity DistributionSeverityLevels error, warning category ValidationCategory metadata, distributionConfiguration hasBlockingErrors boolean true when any result in either array has severity: error; warnings never set it. false guarantees the takedown will not be rejected by validation—it is the same flag the takedown call checks before it does anything./supply-chain/v1/releases/{releaseId}/takedown/validate curl -X GET "https://platform.revelator.com/supply-chain/v1/releases/8801/takedown/validate?distributorStoreIds=1" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/supply-chain/v1/releases/8801/takedown/validate?distributorStoreIds=1" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"hasBlockingErrors": false,
"metadataErrors": [],
"perDistributorStoreErrors": [
{ "distributorStoreId": 1, "errors": [] }
]
} {
"hasBlockingErrors": false,
"metadataErrors": [],
"perDistributorStoreErrors": [
{ "distributorStoreId": 1, "errors": [] }
]
}