API Documentation
Build powerful music applications with TrackID.dev's free API. No registration required, unlimited usage.
→Quick Start
Get started with basic API usage, examples, and key concepts.
Continue reading below
APIAPI Reference
Detailed endpoint documentation, schemas, and advanced features.
View Reference →DEVDeveloper Guide
Step-by-step tutorial for building music apps with code examples.
Start Building →CASECase Study
See how we identified 47 tracks in a techno mix with 94.2% accuracy.
Read Study →Try Live Demo
Test the API interactively with your own YouTube URLs.
Try Now →HELPCommunity
Join GitHub discussions, contribute, and get developer support.
Join GitHub →Quick Start
Get started with TrackID.dev API in under 5 minutes. No API keys needed.
// 1. Submit a URL for analysis
const response = await fetch('https://trackid.dev/api/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://youtu.be/your-video-id' })
});
const { jobId } = await response.json();
// 2. Check processing status
const statusResponse = await fetch(`https://trackid.dev/api/job/${jobId}`);
const jobStatus = await statusResponse.json();
// 3. Get results when completed
if (jobStatus.status === 'completed') {
console.log('Tracks:', jobStatus.tracks);
}Base URL
https://trackid.dev/apiAll API requests should be made to this base URL
Authentication
✅ No Authentication Required
TrackID.dev API is completely free and open. No API keys, no registration, no limits.
Rate Limiting
10 requests per 15 minutes per IP address to ensure fair usage.
API Endpoints
/api/analyzeSubmit a YouTube URL for track identification
Request Body:
{
"url": "https://youtu.be/VIDEO_ID"
}Response:
{
"jobId": "job_1640995200000_abc123",
"status": "queued",
"message": "Processing job created successfully",
"estimatedTime": 300
}Supported URLs:
- •
https://youtube.com/watch?v=VIDEO_ID - •
https://youtu.be/VIDEO_ID - •
https://youtube.com/embed/VIDEO_ID
/api/job/{jobId}Check the status and get results of a processing job
Response (Processing):
{
"id": "job_1640995200000_abc123",
"status": "fingerprinting",
"progress": 60,
"currentStep": "Generating audio fingerprints...",
"estimatedTimeRemaining": 120,
"youtubeUrl": "https://youtu.be/VIDEO_ID",
"createdAt": "2025-12-23T08:00:00.000Z",
"updatedAt": "2025-12-23T08:02:30.000Z"
}Response (Completed):
{
"id": "job_1640995200000_abc123",
"status": "completed",
"progress": 100,
"currentStep": "Analysis complete!",
"tracks": [
{
"id": "track_1",
"timestamp": 0,
"duration": 180,
"artist": "Pendulum",
"title": "Propane Nightmares",
"confidence": 0.89,
"acoustidId": "pendulum_propane_123",
"youtubeUrl": "https://youtube.com/watch?v=example"
}
]
}Job Status Values:
- •
queued- Job is waiting to be processed - •
downloading- Downloading audio from YouTube - •
segmenting- Splitting audio into segments - •
fingerprinting- Generating audio fingerprints - •
matching- Identifying tracks with AcoustID - •
completed- Processing finished successfully - •
failed- Processing failed with error
/api/healthCheck API service health and status
Response:
{
"status": "ok",
"timestamp": "2025-12-23T08:00:00.000Z",
"version": "1.0.0",
"uptime": 3600
}Error Handling
TrackID.dev API uses conventional HTTP response codes to indicate success or failure.
{
"error": "Invalid YouTube URL format"
}{
"error": "Rate limit exceeded. Try again later."
}{
"error": "Internal server error"
}💻 Code Examples
JavaScript / Node.js
async function identifyTracks(youtubeUrl) {
try {
// Start analysis
const response = await fetch('https://trackid.dev/api/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: youtubeUrl })
});
if (!response.ok) throw new Error('Failed to start analysis');
const { jobId } = await response.json();
console.log('Job started:', jobId);
// Poll for completion
let job;
do {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5s
const statusResponse = await fetch(`https://trackid.dev/api/job/${jobId}`);
job = await statusResponse.json();
console.log(`Progress: ${job.progress}% - ${job.currentStep}`);
} while (job.status !== 'completed' && job.status !== 'failed');
if (job.status === 'completed') {
console.log('Found tracks:', job.tracks);
return job.tracks;
} else {
throw new Error('Processing failed');
}
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// Usage
identifyTracks('https://youtu.be/LlIBWVxZLpc')
.then(tracks => console.log('Success!', tracks))
.catch(error => console.error('Failed:', error));Python
import requests
import time
import json
def identify_tracks(youtube_url):
"""Identify tracks in a YouTube video using TrackID.dev API"""
# Start analysis
response = requests.post('https://trackid.dev/api/analyze',
json={'url': youtube_url})
response.raise_for_status()
job_id = response.json()['jobId']
print(f"Job started: {job_id}")
# Poll for completion
while True:
time.sleep(5) # Wait 5 seconds
status_response = requests.get(f'https://trackid.dev/api/job/{job_id}')
status_response.raise_for_status()
job = status_response.json()
print(f"Progress: {job['progress']}% - {job['currentStep']}")
if job['status'] == 'completed':
print(f"Found {len(job['tracks'])} tracks")
return job['tracks']
elif job['status'] == 'failed':
raise Exception(f"Processing failed: {job.get('error', 'Unknown error')}")
# Usage
try:
tracks = identify_tracks('https://youtu.be/LlIBWVxZLpc')
for track in tracks:
if track.get('artist') and track.get('title'):
print(f"{track['timestamp']}s - {track['artist']} - {track['title']}")
except Exception as e:
print(f"Error: {e}")cURL
# Start analysis
curl -X POST https://trackid.dev/api/analyze \
-H "Content-Type: application/json" \
-d '{"url": "https://youtu.be/LlIBWVxZLpc"}'
# Response: {"jobId": "job_123", "status": "queued", ...}
# Check status (replace job_123 with actual jobId)
curl https://trackid.dev/api/job/job_123
# Response: {"status": "completed", "tracks": [...], ...}Best Practices
✅ Do
- • Poll job status every 5-10 seconds
- • Handle rate limiting gracefully
- • Check for both 'completed' and 'failed' status
- • Validate YouTube URLs before submission
- • Cache results to avoid reprocessing
- • Use HTTPS for all API calls
❌ Don't
- • Poll more frequently than every 3 seconds
- • Submit the same URL multiple times
- • Ignore rate limiting responses
- • Assume processing always succeeds
- • Submit non-YouTube URLs
- • Block UI while waiting for results
📊 Track Object Schema
{
"id": "string", // Unique track identifier
"timestamp": 0, // Start time in seconds
"duration": 180, // Track length in seconds
"artist": "Artist Name", // Track artist (empty if unknown)
"title": "Track Title", // Track title (empty if unknown)
"confidence": 0.89, // Confidence score (0.0-1.0)
"acoustidId": "string", // AcoustID identifier (if available)
"youtubeUrl": "string", // YouTube URL for track (if available)
"isUnknown": false // True if track couldn't be identified
}🆘 Support & Community
Need help? Join our developer community or contribute to the project.