Skip to main content

API Reference

Complete reference documentation for the DDEX Builder API across all supported languages.

DdexBuilder Class​

The main builder class for generating deterministic DDEX XML from structured data.

Constructor​

JavaScript / TypeScript​

import { DdexBuilder } from 'ddex-builder';

const builder = new DdexBuilder(options?: BuilderOptions);

Python​

from ddex_builder import DdexBuilder

builder = DdexBuilder(**options)

Configuration Options​

BuilderOptions (TypeScript)​

interface BuilderOptions {
// Validation settings
validate?: boolean; // Enable/disable validation (default: true)
validationLevel?: 'strict' | 'permissive' | 'none';

// Output format
canonical?: boolean; // Enable DB-C14N/1.0 (default: true)
prettyPrint?: boolean; // Format XML with indentation (default: false)
encoding?: string; // XML encoding (default: 'UTF-8')

// Performance options
parallel?: boolean; // Enable parallel processing (default: false)
streaming?: boolean; // Enable streaming mode (default: false)
maxMemoryMB?: number; // Memory limit in MB (default: 512)

// Preset configuration
preset?: string; // Apply preset ('youtube_album', 'generic_audio_album', etc.)

// Advanced options
deterministicIds?: boolean; // Generate content-based IDs (default: true)
preserveOrder?: boolean; // Preserve input element order (default: true)
includeMetadata?: boolean; // Include builder metadata (default: false)
}

BuilderOptions (Python)​

from ddex_builder import DdexBuilder, BuilderOptions

options = BuilderOptions(
validate=True, # Enable validation
validation_level='strict', # 'strict' | 'permissive' | 'none'
canonical=True, # Enable DB-C14N/1.0
pretty_print=False, # Format output
encoding='UTF-8', # XML encoding
parallel=False, # Parallel processing
streaming=False, # Streaming mode
max_memory_mb=512, # Memory limit
preset=None, # Apply preset
deterministic_ids=True, # Content-based IDs
preserve_order=True, # Preserve order
include_metadata=False # Include metadata
)

Core Building Methods​

build()​

Generate DDEX XML from structured data.

JavaScript / TypeScript​

async build(data: BuildRequest): Promise<string>

Parameters:

  • data: Structured data containing message header, releases, resources, etc.

Returns: Promise resolving to DDEX XML string

Example:

const xml = await builder.build({
messageHeader: {
messageId: 'MSG_001',
messageSenderName: 'My Label'
},
releases: [{
releaseId: 'REL_001',
title: 'My Album',
artist: 'Artist Name'
}],
resources: [{
resourceId: 'SR_001',
resourceType: 'SoundRecording',
title: 'Track Title'
}]
});

Python​

def build(self, data: Dict[str, Any]) -> str
async def build_async(self, data: Dict[str, Any]) -> str

Parameters:

  • data: Dictionary containing structured DDEX data

Returns: DDEX XML string

Example:

xml = builder.build({
'message_header': {
'message_id': 'MSG_001',
'message_sender_name': 'My Label'
},
'releases': [{
'release_id': 'REL_001',
'title': 'My Album',
'artist': 'Artist Name'
}]
})

validate()​

Validate structured data without building XML.

JavaScript / TypeScript​

async validate(data?: BuildRequest): Promise<ValidationResult>

Returns: ValidationResult with validation status and errors

Example:

const result = await builder.validate(data);
if (!result.isValid) {
console.log('Errors:', result.errors);
console.log('Warnings:', result.warnings);
}

Python​

def validate(self, data: Dict[str, Any]) -> ValidationResult

Example:

result = builder.validate(data)
if not result.is_valid:
print('Errors:', result.errors)
print('Warnings:', result.warnings)

Streaming Methods​

StreamingDdexBuilder Class​

For building large DDEX files with minimal memory usage.

JavaScript / TypeScript​

import { StreamingDdexBuilder } from 'ddex-builder';

const streamBuilder = new StreamingDdexBuilder(config?: StreamingConfig);

StreamingConfig​

interface StreamingConfig {
maxBufferSize: number; // Buffer size in bytes (default: 8192)
deterministic: boolean; // Enable deterministic output (default: true)
validateDuringStream: boolean; // Validate while streaming (default: true)
progressCallbackFrequency: number; // Progress callback frequency (default: 1000)
}

Streaming Methods​

// Start building a message
startMessage(header: MessageHeader, version: string): void

// Write a sound recording resource
writeResource(
resourceId: string,
title: string,
artist: string,
isrc?: string,
duration?: string,
filePath?: string
): string

// Finish resources section and start releases
finishResourcesStartReleases(): void

// Write a release
writeRelease(
releaseId: string,
title: string,
artist: string,
label: string,
upc?: string,
releaseDate?: string,
genre?: string,
resourceReferences: string[]
): string

// Finish the message and get final stats
finishMessage(): StreamingStats

// Get the complete XML
getXml(): string

// Reset for new message
reset(): void

Streaming Example​

const streamBuilder = new StreamingDdexBuilder({
maxBufferSize: 16384,
validateDuringStream: true
});

// Set progress callback
streamBuilder.setProgressCallback((progress: StreamingProgress) => {
console.log(`Progress: ${progress.estimatedCompletionPercent}%`);
});

// Start message
streamBuilder.startMessage({
messageId: 'STREAM_001',
messageSenderName: 'My Label',
messageRecipientName: 'Platform'
}, '4.3');

// Add resources
const resourceIds = [];
for (const track of largeTrackList) {
const resourceId = streamBuilder.writeResource(
track.id,
track.title,
track.artist,
track.isrc,
track.duration
);
resourceIds.push(resourceId);
}

// Switch to releases section
streamBuilder.finishResourcesStartReleases();

// Add releases
streamBuilder.writeRelease(
'REL_001',
'Large Album',
'Artist Name',
'Label Name',
'123456789012',
'2024-01-01',
'Pop',
resourceIds
);

// Finish and get results
const stats = streamBuilder.finishMessage();
const xml = streamBuilder.getXml();

console.log(`Generated ${stats.bytesWritten} bytes with ${stats.releasesWritten} releases`);

Batch Processing​

batchBuild()​

Build multiple DDEX messages in parallel.

JavaScript / TypeScript​

import { batchBuild } from 'ddex-builder';

async function batchBuild(
requests: BuildRequest[],
options?: BatchBuildOptions
): Promise<BatchBuildResult[]>

BatchBuildOptions​

interface BatchBuildOptions {
preset?: string; // Apply preset to all builds
parallel?: boolean; // Enable parallel processing (default: true)
maxConcurrency?: number; // Max concurrent builds (default: 4)
stopOnError?: boolean; // Stop on first error (default: false)
progressCallback?: (progress: BatchProgress) => void;
}

Example​

const requests = [
{ messageHeader: {...}, releases: [...], resources: [...] },
{ messageHeader: {...}, releases: [...], resources: [...] },
{ messageHeader: {...}, releases: [...], resources: [...] }
];

const results = await batchBuild(requests, {
preset: 'youtube_album',
parallel: true,
maxConcurrency: 10,
progressCallback: (progress) => {
console.log(`${progress.completed}/${progress.total} completed`);
}
});

// Process results
results.forEach((result, index) => {
if (result.success) {
console.log(`✅ Built request ${index}: ${result.xml.length} bytes`);
} else {
console.error(`❌ Failed request ${index}: ${result.error}`);
}
});

Preset System​

Managing Presets​

JavaScript / TypeScript​

// Get available presets
getAvailablePresets(): string[]

// Get preset information
getPresetInfo(presetName: string): PresetInfo

// Apply a preset
applyPreset(presetName: string): void

// Get preset validation rules
getPresetValidationRules(presetName: string): ValidationRule[]

Python​

# Get available presets
def get_available_presets(self) -> List[str]

# Get preset information
def get_preset_info(self, preset_name: str) -> PresetInfo

# Apply a preset
def apply_preset(self, preset_name: str) -> None

# Get preset validation rules
def get_preset_validation_rules(self, preset_name: str) -> List[ValidationRule]

PresetInfo Structure​

interface PresetInfo {
name: string; // Preset identifier
description: string; // Human-readable description
version: string; // Preset version
profile: string; // Target platform/profile
requiredFields: string[]; // Required data fields
disclaimer: string; // Usage disclaimer
}

ValidationRule Structure​

interface ValidationRule {
fieldName: string; // Field path (e.g., 'releases.0.title')
ruleType: string; // Rule type (required, format, length, etc.)
message: string; // Human-readable error message
parameters?: Record<string, string>; // Rule parameters
}

Example​

// Explore available presets
const presets = builder.getAvailablePresets();
console.log('Available presets:', presets);

// Get Spotify preset details
const youtubeInfo = builder.getPresetInfo('youtube_album');
console.log('YouTube preset:', youtubeInfo.description);
console.log('Required fields:', youtubeInfo.requiredFields);
console.log('Specification:', youtubeInfo.specification);

// Apply preset and see rules
builder.applyPreset('youtube_album');
const rules = builder.getPresetValidationRules('youtube_album');
rules.forEach(rule => {
console.log(`${rule.fieldName}: ${rule.message}`);
});

Data Structures​

BuildRequest​

The main data structure for building DDEX XML.

JavaScript / TypeScript​

interface BuildRequest {
messageHeader: MessageHeader;
releases: Release[];
resources: Resource[];
deals?: Deal[];
parties?: Party[];
metadata?: Record<string, any>;
}

interface MessageHeader {
messageId?: string; // Auto-generated if not provided
messageSenderName: string; // Required: Sender identification
messageRecipientName: string; // Required: Recipient identification
messageCreatedDateTime?: string; // Auto-generated if not provided
messageControlType?: string; // Default: 'LiveMessage'
sentOnBehalfOf?: string; // Party ID if sending on behalf
}

interface Release {
releaseId: string; // Unique release identifier
releaseType: string; // 'Album', 'Single', 'EP', etc.
title: string; // Release title
artist: string; // Main artist name
label?: string; // Record label name
catalogNumber?: string; // Catalog number
upc?: string; // Universal Product Code
releaseDate?: string; // Release date (YYYY-MM-DD)
originalReleaseDate?: string; // Original release date
genre?: string; // Primary genre
genres?: string[]; // Multiple genres
territories?: string[]; // Available territories
parentalWarning?: boolean; // Explicit content flag
trackIds: string[]; // References to resources
metadata?: Record<string, any>; // Additional metadata
}

interface Resource {
resourceId: string; // Unique resource identifier
resourceType: string; // 'SoundRecording', 'Image', 'Video', etc.
title: string; // Resource title
artist: string; // Performing artist
isrc?: string; // International Standard Recording Code
duration?: string; // Duration in ISO 8601 format
trackNumber?: number; // Position on release
volumeNumber?: number; // Volume/disc number
languageOfPerformance?: string; // Language code (ISO 639-1)
filePath?: string; // File path for streaming
metadata?: Record<string, any>; // Additional metadata
}

interface Deal {
dealId: string; // Unique deal identifier
releaseId?: string; // Associated release
territories: string[]; // Deal territories
useTypes: string[]; // Usage types (Stream, Download, etc.)
commercialModelType: string; // Business model
dealStartDate?: string; // Deal start date
dealEndDate?: string; // Deal end date
priceInformation?: PriceInfo; // Pricing details
conditions?: string[]; // Deal conditions
}

interface Party {
partyId: string; // Unique party identifier
partyName: string; // Party name
partyType: string; // 'Label', 'Artist', 'Publisher', etc.
contactInfo?: ContactInfo; // Contact information
roles?: string[]; // Party roles
}

ValidationResult​

Result of validation operations.

JavaScript / TypeScript​

interface ValidationResult {
isValid: boolean; // Overall validation status
errors: string[]; // Validation errors (blocking)
warnings: string[]; // Validation warnings (non-blocking)
fieldErrors?: FieldError[]; // Detailed field errors
}

interface FieldError {
field: string; // Field path
message: string; // Error message
value?: any; // Invalid value
suggestions?: string[]; // Suggested corrections
}

Python​

from ddex_builder import ValidationResult

class ValidationResult:
is_valid: bool # Overall validation status
errors: List[str] # Validation errors
warnings: List[str] # Validation warnings
field_errors: List[FieldError] # Detailed field errors

StreamingStats​

Statistics from streaming operations.

interface StreamingStats {
releasesWritten: number; # Number of releases written
resourcesWritten: number; # Number of resources written
dealsWritten: number; # Number of deals written
bytesWritten: number; # Total bytes written
warnings: string[]; # Warnings encountered
peakMemoryUsage: number; # Peak memory usage in bytes
}

DataFrame Integration (Python Only)​

from_dataframes()​

Build DDEX XML directly from pandas DataFrames.

def from_dataframes(
self,
dataframes: Dict[str, pd.DataFrame],
message_header: Dict[str, Any],
version: str = '4.3'
) -> str

Parameters:

  • dataframes: Dictionary mapping entity types to DataFrames
  • message_header: Message header information
  • version: DDEX version to generate

Example:

import pandas as pd

# Create DataFrames
releases_df = pd.DataFrame([{
'release_id': 'REL_001',
'title': 'My Album',
'artist': 'Artist Name',
'upc': '123456789012'
}])

resources_df = pd.DataFrame([{
'resource_id': 'SR_001',
'resource_type': 'SoundRecording',
'title': 'Track 1',
'isrc': 'US1234567890'
}])

# Build DDEX
xml = builder.from_dataframes({
'releases': releases_df,
'resources': resources_df
}, message_header={
'message_id': 'MSG_001',
'message_sender_name': 'My Label'
})

Utility Functions​

validateStructure()​

Validate DDEX XML structure without building.

JavaScript / TypeScript​

import { validateStructure } from 'ddex-builder';

async function validateStructure(xml: string): Promise<ValidationResult>

Example:

const validation = await validateStructure(existingXml);
if (!validation.isValid) {
console.log('XML validation errors:', validation.errors);
}

Error Handling​

Error Types​

JavaScript / TypeScript​

class BuilderError extends Error {
code: string; // Error code
field?: string; // Related field
value?: any; // Related value
}

class ValidationError extends BuilderError {
details: FieldError[]; // Detailed validation errors
}

class PresetError extends BuilderError {
presetName: string; // Related preset name
}

class StreamingError extends BuilderError {
streamPosition: number; // Position in stream where error occurred
}

Python​

from ddex_builder import BuilderError, ValidationError, PresetError

class BuilderError(Exception):
"""Base exception for builder errors."""
def __init__(self, message: str, code: str = None, field: str = None):
super().__init__(message)
self.code = code
self.field = field

class ValidationError(BuilderError):
"""DDEX validation error."""
def __init__(self, message: str, details: List[FieldError] = None):
super().__init__(message)
self.details = details or []

class PresetError(BuilderError):
"""Preset configuration error."""
def __init__(self, message: str, preset_name: str):
super().__init__(message)
self.preset_name = preset_name

Error Handling Example​

import { DdexBuilder, ValidationError, BuilderError } from 'ddex-builder';

try {
const xml = await builder.build(data);
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
error.details.forEach(detail => {
console.error(` ${detail.field}: ${detail.message}`);
if (detail.suggestions) {
console.log(` Suggestions: ${detail.suggestions.join(', ')}`);
}
});
} else if (error instanceof BuilderError) {
console.error('Build failed:', error.message);
if (error.field) {
console.error(` Field: ${error.field}`);
}
} else {
console.error('Unexpected error:', error.message);
}
}

Performance Monitoring​

getStats()​

Get builder performance statistics.

JavaScript / TypeScript​

getStats(): BuilderStats

BuilderStats​

interface BuilderStats {
releasesCount: number; // Total releases built
resourcesCount: number; // Total resources built
totalBuildTimeMs: number; // Cumulative build time
lastBuildSizeBytes: number; // Size of last build
validationErrors: number; // Total validation errors
validationWarnings: number; // Total validation warnings
}

Example​

const stats = builder.getStats();
console.log(`Built ${stats.releasesCount} releases`);
console.log(`Average build time: ${stats.totalBuildTimeMs / stats.releasesCount}ms`);
console.log(`Last build: ${stats.lastBuildSizeBytes} bytes`);

This comprehensive API reference covers all major features and methods available in the DDEX Builder. For implementation examples and advanced usage patterns, see the Advanced Usage guide.