- gRPC service with MusicBrainz provider - PostgreSQL schema with migrations - Service layer with database-first caching - Repository pattern for data access - YAML configuration support - Research documentation for 17 music metadata projects
17 KiB
AcoustID API Reference
API Overview
The AcoustID API provides fingerprint-based music identification services. The API is RESTful, supports multiple response formats (JSON, XML, JSONP), and requires API key authentication for most operations.
Base URL: https://api.acoustid.org
Protocol: HTTPS only
Authentication: API key (application key + user key for submissions)
Rate Limiting: Multi-tier (global, application, IP-based)
Public API Endpoints
Fingerprint Lookup
Identify recordings by audio fingerprint.
/v2/lookup
Methods: GET, POST
Authentication: Required (client key)
Rate Limit: 3 requests/second (IP), 10 requests/second (application)
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
duration |
integer | Track duration in seconds (if using fingerprint) |
trackid |
string | AcoustID track ID (alternative to fingerprint) |
Optional Parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
fingerprint |
string | Chromaprint fingerprint (base64 or compressed) | - |
format |
string | Response format: json, xml, jsonp |
json |
jsoncallback |
string | JSONP callback function name | - |
meta |
string | Metadata to include (see below) | - |
Metadata Options (comma-separated):
recordings: Include MusicBrainz recording metadatarecordingids: Include only recording MBIDs (faster)releases: Include release metadatareleaseids: Include only release MBIDsreleasegroups: Include release group metadatareleasegroupids: Include only release group MBIDstracks: Include track metadatacompress: Compress response with gzipusermeta: Include user-submitted metadatasources: Include submission source information
Batch Lookup:
Submit multiple fingerprints in a single request using indexed parameters:
duration.0=240&fingerprint.0=AQADtN...
duration.1=180&fingerprint.1=AQABtK...
Limits:
- Maximum 20 fingerprints per batch request
- Maximum 100 track IDs per request
Example Request (GET):
GET /v2/lookup?client=8XaBELgH&duration=240&fingerprint=AQADtNGiJE...&meta=recordings
Example Request (POST):
POST /v2/lookup
Content-Type: application/x-www-form-urlencoded
client=8XaBELgH&duration=240&fingerprint=AQADtNGiJE...&meta=recordings
Example Response (JSON):
{
"status": "ok",
"results": [
{
"id": "7e8b1234-5678-90ab-cdef-1234567890ab",
"score": 0.95,
"recordings": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Example Song",
"duration": 240,
"artists": [
{
"id": "12345678-90ab-cdef-1234-567890abcdef",
"name": "Example Artist"
}
],
"releases": [
{
"id": "abcdef12-3456-7890-abcd-ef1234567890",
"title": "Example Album",
"country": "US",
"date": {
"year": 2020,
"month": 5,
"day": 15
},
"track_count": 12,
"medium_count": 1
}
]
}
]
}
]
}
Response Fields:
| Field | Type | Description |
|---|---|---|
status |
string | ok or error |
results |
array | Array of match results |
results[].id |
string | AcoustID track ID |
results[].score |
float | Match confidence (0.0-1.0) |
results[].recordings |
array | MusicBrainz recordings (if requested) |
Fingerprint Submission
Submit audio fingerprints with optional metadata.
/v2/submit
Method: POST
Authentication: Required (client key + user key)
Rate Limit: 3 requests/second (IP), 10 requests/second (application)
Required Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
user |
string | User API key |
duration.# |
integer | Track duration in seconds |
fingerprint.# |
string | Chromaprint fingerprint |
Optional Parameters:
| Parameter | Type | Description |
|---|---|---|
clientversion |
string | Client application version |
bitrate.# |
integer | Audio bitrate in kbps |
fileformat.# |
string | Audio file format (mp3, flac, etc.) |
mbid.# |
string | MusicBrainz recording MBID |
track.# |
string | Track title |
artist.# |
string | Artist name |
album.# |
string | Album title |
albumartist.# |
string | Album artist name |
year.# |
integer | Release year |
trackno.# |
integer | Track number |
discno.# |
integer | Disc number |
Batch Submission:
Use indexed parameters (.0, .1, .2, etc.) to submit multiple fingerprints:
duration.0=240&fingerprint.0=AQADtN...&mbid.0=a1b2c3d4...
duration.1=180&fingerprint.1=AQABtK...&mbid.1=e5f67890...
Example Request:
POST /v2/submit
Content-Type: application/x-www-form-urlencoded
client=8XaBELgH&user=AbCdEfGh&duration.0=240&fingerprint.0=AQADtNGiJE...&mbid.0=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Example Response:
{
"status": "ok",
"submissions": [
{
"id": 12345678,
"status": "pending"
}
]
}
Response Fields:
| Field | Type | Description |
|---|---|---|
status |
string | ok or error |
submissions |
array | Array of submission results |
submissions[].id |
integer | Submission ID |
submissions[].status |
string | pending, imported, or error |
Submission Status
Check the processing status of submitted fingerprints.
/v2/submission_status
Method: GET
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
id |
integer | Submission ID (from submit response) |
format |
string | Response format: json, xml, jsonp |
Example Request:
GET /v2/submission_status?client=8XaBELgH&id=12345678
Example Response:
{
"status": "ok",
"submission": {
"id": 12345678,
"status": "imported",
"result": {
"id": "7e8b1234-5678-90ab-cdef-1234567890ab"
}
}
}
Status Values:
pending: Queued for processingimported: Successfully processederror: Processing failed
Fingerprint Retrieval
Retrieve stored fingerprint data.
/v2/fingerprint
Method: GET
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
id |
string | AcoustID track ID |
format |
string | Response format: json, xml, jsonp |
Example Request:
GET /v2/fingerprint?client=8XaBELgH&id=7e8b1234-5678-90ab-cdef-1234567890ab
Example Response:
{
"status": "ok",
"fingerprints": [
{
"id": 987654321,
"fingerprint": "AQADtNGiJE...",
"duration": 240,
"submission_count": 5
}
]
}
Track Listing by MBID
List AcoustID tracks linked to a MusicBrainz recording.
/v2/track/list_by_mbid
Method: GET
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
mbid |
string | MusicBrainz recording MBID |
format |
string | Response format: json, xml, jsonp |
Example Request:
GET /v2/track/list_by_mbid?client=8XaBELgH&mbid=a1b2c3d4-e5f6-7890-abcd-ef1234567890
Example Response:
{
"status": "ok",
"tracks": [
{
"id": "7e8b1234-5678-90ab-cdef-1234567890ab",
"disabled": false
}
]
}
Track Listing by PUID
List AcoustID tracks linked to a MusicIP PUID (legacy).
/v2/track/list_by_puid
Method: GET
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
puid |
string | MusicIP PUID |
format |
string | Response format: json, xml, jsonp |
User Management
/v2/user/lookup
Lookup user API key by MusicBrainz account.
Method: POST
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
musicbrainz_id |
string | MusicBrainz username |
/v2/user/create_anonymous
Create anonymous user API key.
Method: POST
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
Example Response:
{
"status": "ok",
"user": {
"apikey": "AbCdEfGh"
}
}
/v2/user/create_musicbrainz
Create user API key linked to MusicBrainz account.
Method: POST
Authentication: Required (client key)
Parameters:
| Parameter | Type | Description |
|---|---|---|
client |
string | Application API key |
access_token |
string | MusicBrainz OAuth access token |
Legacy API Endpoints
/lookup
Legacy lookup endpoint (API v1).
Status: Deprecated, use /v2/lookup instead
Differences: Limited metadata options, different response format
/submit
Legacy submit endpoint (API v1).
Status: Deprecated, use /v2/submit instead
Differences: Synchronous processing, no batch support
Health Check Endpoints
/_health
Full health check with database write test.
Method: GET
Authentication: None
Response:
{
"status": "ok"
}
Status Codes:
200: All systems operational503: Service unavailable
/_health_ro
Read-only health check (database read test only).
Method: GET
Authentication: None
/_health_docker
Docker-specific health check (minimal checks).
Method: GET
Authentication: None
Internal API Endpoints
These endpoints are for administrative use only and require special authentication.
/v2/internal/update_lookup_stats
Trigger lookup statistics update.
Method: POST
Authentication: Internal only
/v2/internal/update_user_agent_stats
Trigger user agent statistics update.
Method: POST
Authentication: Internal only
/v2/internal/lookup_stats
Retrieve lookup statistics.
Method: GET
Authentication: Internal only
/v2/internal/create_account
Create new user account.
Method: POST
Authentication: Internal only
/v2/internal/create_application
Create new API application.
Method: POST
Authentication: Internal only
/v2/internal/update_application_status
Update application status (active/inactive).
Method: POST
Authentication: Internal only
/v2/internal/check_application
Check application validity.
Method: GET
Authentication: Internal only
Index API Endpoints
The fingerprint index service exposes its own HTTP API (separate from the main API).
Base URL: http://index:6081 (internal)
Protocol: HTTP
Format: MessagePack
PUT /:index
Create new index.
Parameters:
:index: Index name
GET /:index
Get index information.
Response:
{
"name": "fingerprints",
"doc_count": 1234567,
"segment_count": 42,
"memory_segment_size": 1048576
}
DELETE /:index
Delete index.
POST /:index/_search
Search for fingerprints.
Request Body (MessagePack):
{
"query": [term1, term2, term3, ...],
"limit": 10,
"min_score": 0.5
}
Response (MessagePack):
{
"results": [
{"id": fpid1, "score": 0.95},
{"id": fpid2, "score": 0.87}
]
}
POST /:index/_update
Batch update fingerprints.
Request Body (MessagePack):
{
"updates": [
{"id": fpid1, "terms": [term1, term2, ...]},
{"id": fpid2, "terms": [term3, term4, ...]}
]
}
GET /:index/_segments
List index segments.
Response:
{
"segments": [
{
"id": 0,
"type": "memory",
"doc_count": 1024,
"size_bytes": 1048576
},
{
"id": 1,
"type": "file",
"doc_count": 100000,
"size_bytes": 52428800
}
]
}
GET /:index/_snapshot
Create index snapshot.
Response:
{
"snapshot_id": "snapshot_20250428_120000",
"path": "/var/lib/acoustid-index/snapshots/snapshot_20250428_120000"
}
PUT /:index/:fpid
Insert or update fingerprint.
Parameters:
:index: Index name:fpid: Fingerprint ID
Request Body (MessagePack):
{
"terms": [term1, term2, term3, ...]
}
GET /:index/:fpid
Retrieve fingerprint.
Response (MessagePack):
{
"id": fpid,
"terms": [term1, term2, term3, ...]
}
DELETE /:index/:fpid
Delete fingerprint.
GET /_health
Index health check.
Response:
{
"status": "ok"
}
GET /_metrics
Prometheus metrics.
Response (Prometheus text format):
# HELP fpindex_search_duration_seconds Search duration
# TYPE fpindex_search_duration_seconds histogram
fpindex_search_duration_seconds_bucket{le="0.005"} 1234
fpindex_search_duration_seconds_bucket{le="0.01"} 5678
...
Rate Limiting
Rate Limit Tiers
AcoustID implements a three-tier rate limiting system:
| Tier | Scope | Default Limit | Override |
|---|---|---|---|
| Global | All requests | 3 req/s | Config: cluster.rate_limiter.global_limit |
| Application | Per API key | 10 req/s | Database: application.rate_limit |
| IP Address | Per client IP | 3 req/s | Config: cluster.rate_limiter.ip_limit |
Rate Limit Algorithm
Implementation: Redis-based sliding window
Window Configuration:
- Window duration: 20 seconds
- Window steps: 4 (5-second buckets)
- Cleanup: Automatic expiration (25-second TTL)
Redis Keys:
rl:bucket:global:{timestamp}
rl:bucket:app:{api_key}:{timestamp}
rl:bucket:ip:{ip_address}:{timestamp}
Rate Limit Headers
Responses include rate limit information:
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1714305600
Rate Limit Exceeded Response
Status Code: 429 Too Many Requests
Response:
{
"status": "error",
"error": {
"code": 5,
"message": "Rate limit exceeded"
}
}
Error Handling
Error Response Format
All errors return a consistent structure:
{
"status": "error",
"error": {
"code": 1,
"message": "Invalid API key"
}
}
Error Codes
| Code | Message | Description |
|---|---|---|
| 1 | Invalid API key | Client or user key is invalid |
| 2 | Missing required parameter | Required parameter not provided |
| 3 | Invalid fingerprint | Fingerprint format is invalid |
| 4 | Internal error | Server-side error occurred |
| 5 | Rate limit exceeded | Too many requests |
| 6 | Invalid format | Unsupported response format |
| 7 | Fingerprint not found | Requested fingerprint doesn't exist |
| 8 | Too many requests | Batch size exceeds limit |
HTTP Status Codes
| Code | Meaning | Usage |
|---|---|---|
| 200 | OK | Successful request |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | API key lacks permission |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
| 503 | Service Unavailable | Service down or degraded |
Authentication
API Key Types
-
Application Key (
clientparameter):- Identifies the client application
- Required for all API calls
- Obtain from https://acoustid.org/new-application
-
User Key (
userparameter):- Identifies the end user
- Required for submissions
- Created via
/v2/user/create_*endpoints
-
Demo Key:
- Limited functionality
- For testing only
- Key:
8XaBELgH
Key Management
Application Keys:
- Created via web UI or internal API
- Can be active or inactive
- Rate limits configurable per key
- Usage statistics tracked
User Keys:
- Anonymous or MusicBrainz-linked
- Created programmatically
- Tied to application key
- Submission history tracked
Best Practices
Lookup Optimization
- Use batch lookups for multiple files (up to 20 per request)
- Request only needed metadata (use specific
metaflags) - Cache results to avoid redundant lookups
- Handle rate limits with exponential backoff
Submission Guidelines
- Include MBIDs when known (improves accuracy)
- Provide metadata (artist, album, track) for better matching
- Use batch submissions for efficiency
- Poll submission status asynchronously
Error Handling
- Retry on 5xx errors with exponential backoff
- Respect rate limits (check headers)
- Validate fingerprints before submission
- Log errors for debugging
Performance
- Use POST for large requests (avoid URL length limits)
- Enable compression (
meta=compress) - Reuse connections (HTTP keep-alive)
- Implement timeouts (30-60 seconds recommended)