Overview
DDEX (Digital Data Exchange) is the industry-standard XML format for communicating music metadata and rights information to Digital Service Providers (DSPs). The Royalti.io API supports generating ERN, MEAD, and PIE messages.
Authentication
DDEX endpoints require authentication. Some providers also use additional DDEX-specific authentication.
 
Message Types
ERN (Electronic Release Notification)
Used for delivering release metadata to DSPs:
const response = await fetch('https://api.royalti.io/ddex/ern/generate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    productId: 'prod-123',
    providerId: 'spotify',
    messageType: 'NewReleaseMessage'
  })
});
 
MEAD (Music Enrichment and Description)
Rich metadata for enhanced discovery:
const response = await fetch('https://api.royalti.io/ddex/mead/generate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    assetId: 'asset-123',
    providerId: 'apple-music',
    includeCredits: true
  })
});
 
Rights holder information:
const response = await fetch('https://api.royalti.io/ddex/pie/generate', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    artistId: 'artist-123',
    providerId: 'universal'
  })
});
 
DDEX Workflow
Configure Provider
Set up delivery credentials and preferences for each DSP.const response = await fetch('https://api.royalti.io/ddex/providers/', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Spotify',
    deliveryMethod: 'SFTP',
    credentials: {
      host: 'sftp.spotify.com',
      username: 'your-username',
      // Store password in environment
    }
  })
});
 Generate Message
Create DDEX XML from your release data.The system automatically validates against XSD schemas and applies business rules.
 Validate Message
Ensure compliance with DDEX standards.const response = await fetch(`https://api.royalti.io/ddex/messages/${messageId}/validate`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`
  }
});
 Deliver to Provider
Send via SFTP, API, or HTTP depending on provider requirements.const response = await fetch(`https://api.royalti.io/ddex/messages/${messageId}/deliver`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`
  }
});
  
Provider-Specific Configuration
Different DSPs have different requirements:
const providerConfigs = {
  spotify: {
    deliveryMethod: 'SFTP',
    ernProfile: 'ERN-4',
    territories: ['Worldwide']
  },
  appleMusic: {
    deliveryMethod: 'API',
    ernProfile: 'ERN-4.1',
    requiresPreview: true
  },
  tidal: {
    deliveryMethod: 'HTTP',
    ernProfile: 'ERN-3.8.2',
    audioQuality: 'lossless'
  }
};
 
Best Practices
Territory Management
Ensure territory configurations don’t overlap and cover 100% of intended distribution.
 
Deal Configuration
Set up usage rights and release dates:
const dealConfig = {
  territories: ['US', 'CA', 'GB'],
  usageType: 'PermanentDownload',
  startDate: '2024-06-01',
  priceCategory: 'Mid'
};
 
Error Handling
Implement comprehensive validation:
async function generateAndValidateDDEX(productId, providerId) {
  try {
    // Generate message
    const message = await generateERN(productId, providerId);
    // Validate
    const validation = await validateMessage(message.id);
    if (!validation.isValid) {
      console.error('Validation errors:', validation.errors);
      return { success: false, errors: validation.errors };
    }
    // Deliver
    await deliverMessage(message.id);
    return { success: true, messageId: message.id };
  } catch (error) {
    console.error('DDEX generation failed:', error);
    throw error;
  }
}