Tutorial·

Building a Claude Skill for DDEX Validation: Automate Music Metadata Checks with AI

A step-by-step guide to creating a Claude Code skill that validates DDEX ERN XML files against official schemas - catching metadata errors before they reach distributors.
Building a Claude Skill for DDEX Validation: Automate Music Metadata Checks with AI

If you distribute music digitally, you've dealt with DDEX. The Electronic Release Notification (ERN) standard is how labels and distributors exchange release metadata - track titles, ISRC codes, territory rights, audio file references, and more. Get it wrong, and your release gets rejected. Get it right, and it flows seamlessly to Spotify, Apple Music, and hundreds of other platforms.

The problem? DDEX XML files are complex, deeply nested, and easy to break. Validation usually means uploading files to web tools, running CLI scripts, or waiting for your distributor to reject your submission.

In this tutorial, we'll build a Claude skill that validates DDEX ERN files on demand - right inside Claude Code or Claude.ai. Type /ddex-validate, paste your XML, and get instant feedback with actionable error messages.

This is a proof of concept - an experiment in using AI to streamline daily routines when working with music industry data. The full skill is open source on GitHub.

What is a Claude skill?

A skill is a folder with a SKILL.md file that teaches Claude how to handle a specific workflow. Think of it as a reusable prompt template with structure:

ddex-validate/
├── SKILL.md                    # Instructions + YAML frontmatter
├── references/
│   └── ern-structure.md        # DDEX domain knowledge
└── assets/
    └── ern382-sample.xml       # Example file for testing

Skills use progressive disclosure - Claude loads the frontmatter first (to decide if the skill is relevant), then the full instructions only when triggered. This keeps token usage low while maintaining deep domain expertise.

Prerequisites

  • Claude Code installed (or Claude.ai with skills support)
  • Basic familiarity with XML and DDEX concepts
  • About 15–30 minutes

Step 1: Plan the use cases

Before writing any code, define what the skill should handle:

Full XML Validation

Parse XML, detect ERN version, fetch XSD schema, validate, and report errors with line numbers.

Quick Structure Check

Verify required elements exist and check ISRC/UPC format without full schema validation.

Fix Suggestions

Analyze each error, suggest a specific fix, and show corrected XML snippets the user can copy-paste.

Step 2: Create the skill folder

Create the skill directory in your Claude Code skills location:

mkdir -p ~/.claude/skills/ddex-validate/references
mkdir -p ~/.claude/skills/ddex-validate/assets

Step 3: Write the SKILL.md

This is the core of the skill. The YAML frontmatter tells Claude when to load it, and the Markdown body tells Claude what to do.

Create ~/.claude/skills/ddex-validate/SKILL.md:

The frontmatter

The frontmatter is the most important part - it's how Claude decides whether to load your skill:

name: ddex-validate
description: Validates DDEX ERN XML files against official schemas.
  Checks structure, required fields (ISRC, UPC, MessageHeader), and
  schema conformance. Use when user uploads .xml files, mentions
  "DDEX", "ERN", "validate release", "check metadata", or
  "release notification".
A good description follows the pattern: What it does + When to use it + Key capabilities. Include specific trigger phrases users might say - Claude uses these to decide if the skill is relevant.

The validation workflow

The body of SKILL.md contains step-by-step instructions. Here's the core - the Python validation function that fetches the official DDEX XSD and validates against it:

from lxml import etree
import requests

def validate_ddex(xml_content: str, version: str) -> dict:
    """Validate DDEX XML against official ERN schema."""
    xsd_url = (
        f"https://service.ddex.net/xml/ern/"
        f"{version}/release-notification.xsd"
    )

    # Fetch and compile schema
    response = requests.get(xsd_url, timeout=10)
    response.raise_for_status()
    schema_root = etree.fromstring(response.content)
    schema = etree.XMLSchema(schema_root)

    # Parse and validate
    xml_tree = etree.fromstring(xml_content.encode())
    is_valid = schema.validate(xml_tree)

    errors = []
    if not is_valid:
        for error in schema.error_log:
            errors.append({
                "line": error.line,
                "column": error.column,
                "message": error.message,
                "level": error.level_name,
            })

    return {"valid": is_valid, "errors": errors, "version": version}

Music industry checks

Beyond schema validation, the skill checks for issues that cause real distributor rejections:

CheckRuleExample
ISRCExactly 12 alphanumeric chars, no hyphensUSSM12345678
UPC/EAN12 or 13 digits123456789012
TerritoryISO 3166-1 alpha-2 or WorldwideUS, GB, Worldwide
DurationISO 8601 formatPT3M30S
Resource refsEvery ReleaseResourceReference must match a ResourceReferenceA1 links to A1
ParentalWarningMust be presentNotExplicit, Explicit
ISRC codes use hyphens for display (US-SM1-23-45678) but never in XML. This is one of the most common validation errors we see.

Output format

The skill defines exactly how Claude should present results:

DDEX ERN 382 - Valid

Summary:
- Releases: 1
- Sound Recordings: 3
- Images: 1
- Territory: Worldwide
- Message Type: LiveMessage

And when errors are found:

DDEX ERN 382 - 2 error(s) found

| # | Line | Error                           | Suggested Fix                    |
|---|------|---------------------------------|----------------------------------|
| 1 | 36   | Element 'ISRC': '' is not valid | Add 12-char ISRC: CCXXXYYNNNNN   |
| 2 | 45   | Missing element 'TerritoryCode' | Add <TerritoryCode>Worldwide</…> |
The full SKILL.md also includes a Common Issues section with pre-documented fixes for namespace errors, resource reference mismatches, and territory code problems. See the complete file in the GitHub repo.

Step 4: Add supporting files

The skill needs two more pieces:

references/ern-structure.md - the complete ERN element hierarchy (MessageHeader, ResourceList, ReleaseList, DealList), field format rules, and version differences between ERN 3.8.2 and 4.1.1+. Claude loads this on demand when it needs deeper context during validation.

assets/ern382-sample.xml - a minimal but valid ERN 3.8.2 file with a MessageHeader, one SoundRecording (ISRC, artist, genre, technical details), one Image, and one Release.

You don't need to write these from scratch. Clone the GitHub repo and the full skill is ready to use:
git clone https://github.com/musictechlab/ddex-validate.git ~/.claude/skills/ddex-validate

Step 5: Test the skill

Once installed, test it from three angles:

Should trigger - try prompts like these:

"Validate this DDEX file"
"Check my ERN XML for errors"
"Is this release metadata valid?"

Error detection - introduce common mistakes and verify the skill catches them:

<!-- Missing ISRC -->
<SoundRecordingId>
  <CatalogNumber Namespace="PADPIDA2023001">CAT001</CatalogNumber>
</SoundRecordingId>

<!-- Invalid territory code -->
<TerritoryCode>United States</TerritoryCode>

<!-- Mismatched resource reference -->
<ReleaseResourceReference>A99</ReleaseResourceReference>
<!-- when ResourceReference is "A1" -->

Should NOT trigger - prompts like "Write a Python function" or "Help me with CSS" should not activate the skill.

How it works under the hood

When you type a prompt that matches the skill's description triggers, Claude's progressive disclosure system kicks in:

Loading diagram...

This three-level system keeps token usage minimal for non-DDEX conversations while providing deep expertise when needed:

Level 1 - Frontmatter

Claude reads name and description. Just enough to decide: "is this a DDEX request?"

Level 2 - Instructions

The full 5-step workflow: parse, validate, check industry rules, report results.

Level 3 - References

Deep ERN structure docs, field formats, version differences. Loaded only when needed.

What's next

This skill covers standalone validation - no external services required. But there are natural extensions:

  • MCP integration - connect to your distributor's API to validate and submit in one workflow
  • Batch validation - process an entire directory of ERN files before a bulk delivery
  • DSRF support - extend to Digital Sales Report Format flat files (tab-separated, not XML)
  • Auto-fix mode - instead of just reporting errors, have Claude rewrite the XML with fixes applied

You could also combine this with an AudioSalad or Revelator delivery skill - validate the DDEX, then push it to your distributor, all from one conversation.

Wrapping up

DDEX validation is a perfect fit for a Claude skill: it's a well-defined workflow, requires domain knowledge that doesn't change often, and benefits from consistent execution. Instead of context-switching to a web tool or remembering CLI flags, you type /ddex-validate and get expert-level feedback in seconds.

The full skill is open source - clone it and start validating:

git clone https://github.com/musictechlab/ddex-validate.git ~/.claude/skills/ddex-validate

Music Tech Lab builds tools for the music industry - from metadata validation to streaming analytics. If you're working with DDEX, audio fingerprinting, or distribution pipelines, get in touch.

Let's Build Something Together

Have a similar project in mind? We'd love to hear about it.

Get in touch to discuss how we can help bring your vision to life.