Validations
Validation endpoints answer, on demand, whether an asset is ready to move—out to stores, or back off them. They read the asset by ID, run the same rules the corresponding pipeline runs, and return everything that would block or warn, without submitting anything or changing any state.
These are read-only GET calls. Nothing is queued, locked, delivered, or taken down by validating.
| Endpoint | Answers |
|---|---|
| Validate Delivery | Can this release be delivered to these stores? |
| Validate Takedown | Can this release be taken down from these stores? |
Delivery and takedown are validated separately because they check different things: delivery checks that the release is complete and configured, takedown checks that it is actually live somewhere and carries what a takedown notice needs.
Catalog endpoints deliberately validate far less on save than these endpoints do, so that incomplete records can be drafted and finished later. A release or video that saves successfully can still fail validation. Treat saving and distribution-readiness as two separate bars.
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.
This is the same flag the platform checks internally. Delivery, takedown, and inspection approval each re-run the
matching validation before doing anything and refuse the request when hasBlockingErrors is true. So a validation
that comes back false is a guarantee: that action will not be rejected by validation. Warnings may still be present
in the response—they do not block.
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 simply repeats under each of them—Apple’s Producers & Engineers requirement,
for instance, appears under both store 1 and store 459. So an error you see under every store is effectively global
even though it arrives per store.
{
"hasBlockingErrors": true,
"metadataErrors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Video level: The genre of your video is missing.",
"severity": "error",
"category": "metadata"
}
],
"perDistributorStoreErrors": [
{ "distributorStoreId": 1, "errors": [] },
{
"distributorStoreId": 9,
"errors": [
{
"objectId": 4501,
"objectType": "video",
"errorMessage": "Spotify requires an Official Music Video to be linked to an audio track.",
"severity": "error",
"category": "metadata"
}
]
}
]
}
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.
A store ID that your organization does not have enabled is silently skipped rather than rejected—it simply will not
appear in perDistributorStoreErrors. An unrecognised ID therefore returns a 200 with an empty array, not an error,
so verify your store IDs rather than reading an empty result as a pass.
Errors Cascade
Validating a release also validates everything it contains. A single call against a release can return errors whose
objectType is track, video, or artist, each carrying the ID of the offending object.
This means a release-level call is the complete pre-distribution check: there is no need to validate the contained tracks or videos separately, and problems on them are reported with their own IDs so you can go straight to the object that needs fixing.
Fixing What Comes Back
The category field tells you where the fix lives:
metadata— the asset’s own content is wrong or incomplete. Fix it through the Catalog API: Releases, Tracks, Videos, or Artists.distributionConfiguration— the content is fine but the distribution setup is incomplete. Fix it through the Supply Chain configuration endpoints: Pricing Tiers, Monetization Policies, or Territories Clearances.
Messages in the second category read like “Please define Standard track prices for this distributor store: iTunes.” or “Tracks monetization is required.”—they are configuration gaps, not content problems.
Warnings
A warning never blocks distribution. Warnings flag things worth a second look before you commit—a title that appears
to contain version information, an artist field that looks like it holds two artists, or a caption file that a DSP will
strip on ingestion.
You can distribute with warnings outstanding. Surface them for acknowledgement rather than treating them as 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.
Which Stores Are Checked
Omit distributorStoreIds and the check covers every store available to your organization that accepts this release
type—a video-only release is routed only to video-capable stores, for example.
Naming stores explicitly overrides that filter. Requested IDs are validated exactly as given, including stores that would never accept the release type in the first place. The errors this produces are real, but they are about the pairing rather than the release, so prefer omitting the parameter when you want the honest “is this ready?” answer.
Release-Wide Rules
metadataErrors holds the checks that apply to the release itself, identically regardless of destination—identifiers
and copyright lines, dates, cover artwork, tracklist structure and completeness, genre and language, artist and title
conventions, and asset rights. An error here blocks every store, so these are the ones to clear first.
Not every finding blocks. Some checks return warning severity instead—a title that looks like it carries version or
featured-artist information, for example—and are surfaced for acknowledgement rather than treated as failures. Warnings
never set hasBlockingErrors.
Per-Store Rules
Each store is checked in two stages, and the first stage short-circuits the second.
Stage 1 — eligibility. If any of these fail, the delivery rules below are skipped entirely for that store and only the eligibility failure comes back:
- The store is not available to your organization.
- Environment mismatch—a sandbox organization can only deliver to sandbox DSPs, and a live organization only to live ones.
- Video releases to Spotify, unless your organization is Spotify-approved for video.
Because eligibility short-circuits, a store showing a single eligibility error may be hiding further problems. Fix that error and validate again to see the rest.
Stage 2 — delivery rules, for stores that passed:
| Area | Checked |
|---|---|
| Store fit | The release type must be supported by the store, and at least one track must be eligible for it. |
| Prices | Standard track and album prices defined; Hi-Res and HD2 only where the DSP expects them. The album price cannot exceed the sum of its track prices. See Pricing Tiers. |
| Monetization | A policy per track, for stores where monetization applies. See Monetization Policies. |
| Territories | Release- and track-level clearances must resolve to known countries. Worldwide clearance is skipped. See Territories Clearances. |
| Cover image | A delivery-sized version must exist and fit the store’s requirements. Images over 10 MB are flagged. |
| Artist profiles | External profile IDs required by that specific store. Meta additionally cross-checks that the Facebook Audio Library and Rights Manager IDs match. |
| Genre | Required for stores that validate genre. |
| Rights | Asset rights must permit distribution to that store. |
Any videos on the release are validated against the same stores, excluding those that failed eligibility.
/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—see Which Stores Are Checked above. Retrieved from GET /common/lookup/stores on the V1.0 API. |
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 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. |
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=13" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/supply-chain/v1/releases/8801/takedown/validate?distributorStoreIds=13" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"hasBlockingErrors": false,
"metadataErrors": [],
"perDistributorStoreErrors": [
{ "distributorStoreId": 13, "errors": [] }
]
} {
"hasBlockingErrors": false,
"metadataErrors": [],
"perDistributorStoreErrors": [
{ "distributorStoreId": 13, "errors": [] }
]
}