> 14_API_V1.MD

everysong API.

Partner-tier API for audio similarity matching. POST an audio file, get back a 13-trait fingerprint and 20 ranked Creative-Commons matches. JSON in, JSON out. Bearer-token auth. Same engine that runs the consumer site at everysong.app, available against the public CC catalogue or a custom catalogue you bring.

Quick start

Once you have an API key from [email protected], every call uses the same auth header:

curl -X POST https://everysong-api.fly.dev/api/v1/match \
  -H "Authorization: Bearer es_live_YOUR_KEY_HERE" \
  -F "[email protected]"

Sanity-check your key first:

curl https://everysong-api.fly.dev/api/v1/me \
  -H "Authorization: Bearer es_live_YOUR_KEY_HERE"

That returns your label, scopes, daily limit, and usage today. If the key is valid and active, you're ready.

Authentication

Every request to /api/v1/* requires an Authorization header:

Authorization: Bearer es_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are partnership-issued: no self-serve signup. Request a key by emailing [email protected] with your use case, expected request volume, and whether you want to match against the public CC catalogue or bring your own.

Raw keys are shown once at issue time. The server only stores a SHA-256 hash. If you lose the key, request a new one (we will revoke the old). If you suspect a key has leaked, email immediately and we will revoke within minutes.

Endpoints

POST/api/v1/match
Upload an audio file, get a 13-trait fingerprint plus 20 ranked Creative-Commons matches.

Request

multipart/form-data with a file field. Max 30 MB. Supported formats: MP3, WAV, FLAC, M4A, OGG.

curl -X POST https://everysong-api.fly.dev/api/v1/match \
  -H "Authorization: Bearer es_live_YOUR_KEY_HERE" \
  -F "[email protected]"

Response (200)

{
  "fingerprint": {
    "duration_sec": 215.4,
    "traits": {
      "tempo_bpm": 128,
      "key": "Em",
      "mode": "minor",
      "loudness_lufs": -8.2,
      "energy": 0.78,
      "valence": 0.55,
      "danceability": 0.88,
      "acousticness": 0.05,
      "instrumentalness": 0.92,
      "spectral_centroid_hz": 2950,
      "spectral_rolloff_hz": 9200,
      "stereo_width": 0.32,
      "zero_crossing_rate": 2400,
      "vocal_instrumental": "instrumental"
    },
    "reliability": {
      "green": ["tempo_bpm", "key", "mode", "loudness_lufs",
                "spectral_centroid_hz", "spectral_rolloff_hz",
                "stereo_width", "zero_crossing_rate", "vocal_instrumental"],
      "amber": ["energy", "valence", "danceability",
                "acousticness", "instrumentalness"]
    }
  },
  "matches": [
    {
      "rank": 1,
      "title": "Track Name",
      "artist": "Artist Name",
      "license": "CC BY 4.0",
      "source_url": "https://freemusicarchive.org/...",
      "preview_url": "https://files.freemusicarchive.org/...",
      "duration_sec": 198.2,
      "distance": 0.0823
    }
    /* + 19 more */
  ],
  "request": {
    "id": "req_a1b2c3d4e5f60718",
    "duration_ms": 11240
  }
}

Trait reliability

Eight GREEN traits are signal-processing measurements with decades of established research. Trust them for downstream decisions.

Five AMBER traits are ML-classifier outputs. Use as a directional second opinion. We do not publish accuracy numbers we have not benchmarked; see how it works for the full methodology.

GET/api/v1/catalogue/info
Metadata about the catalogue your key matches against.

Response (200)

{
  "name": "everysong public CC catalogue",
  "track_count": 3382,
  "sources": ["Free Music Archive", "ccMixter", "Jamendo"],
  "licenses": ["CC0", "CC BY 4.0", "CC BY-SA 4.0"],
  "excluded_licenses": ["CC BY-NC", "CC BY-NC-SA",
                        "CC BY-ND", "CC BY-NC-ND"],
  "notes": "Custom catalogue ingest (bring your own tracks, dedicated
            index, private to your key) is available via partnership
            engagement: [email protected]."
}

If your key is provisioned against a custom catalogue (private to you, ingested per partnership), this endpoint returns metadata for that catalogue instead.

GET/api/v1/me
Information about the calling API key: label, scopes, rate limits, usage today.

Response (200)

{
  "label": "Epidemic Sound evaluation",
  "partner_email": "[email protected]",
  "scopes": ["match.read", "catalogue.read"],
  "rate_limit": {
    "daily": 1000,
    "used_today": 12,
    "remaining_today": 988
  },
  "lifetime_usage": 47,
  "created_at": "2026-05-26 14:00:00",
  "last_used_at": "2026-05-26 15:42:33"
}

Rate limits

Limits are per-key, reset at 00:00 UTC. The tier is set when your key is issued and shown via /api/v1/me.

Tier Daily limit Typical use
Evaluation 1,000 requests/day Partner POC, technical evaluation, integration spike
Starter 10,000 requests/day Live integration at small scale
Production 100,000 requests/day Live integration with material traffic
Custom Negotiated Anything above 100k/day, dedicated infrastructure, on-premise

Exceeding your daily limit returns 429 with a clear error message and the time the limit resets. We do not throttle silently or surprise-bill for overage.

Error envelope

All errors return a consistent JSON shape with the appropriate HTTP status code:

{
  "error": {
    "code": "invalid_api_key",
    "message": "API key is missing, malformed, or revoked. ...",
    "status": 401
  }
}
HTTP Code When
400 invalid_audio_file File missing, empty, or could not be decoded.
401 missing_authorization Authorization header is missing.
401 invalid_api_key Key is malformed, unknown, or revoked.
413 file_too_large Audio file exceeds 30 MB.
429 daily_rate_limit_exceeded Daily request quota used up. Resets at 00:00 UTC.
500 engine_error Audio embedding or signal-extraction failed unexpectedly. Retry once; if persistent, email support.

Latency expectations

Audio analysis is compute-bound. On a warm machine (a Cloudflare Worker cron keeps the Fly instance warm 24/7), expect POST /api/v1/match to return within 10-15 seconds for a 3-5 minute track. The CLAP embedding step is the bottleneck.

The first request after a long idle period may take 30-60 seconds while the audio model loads from disk. We mitigate this with the warmer cron, so in practice this only affects requests during platform restarts.

For predictably-low latency at scale (under 2 seconds per match), the production tier runs on dedicated GPU infrastructure; ask [email protected] for the specifics.

Custom catalogue ingest

The public API matches against the everysong CC catalogue (3,382 tracks). For partnerships that want to match against their own catalogue (their label's roster, their stock library, their indie streaming catalogue), we ingest and index separately:

Order of magnitude: a 50,000-track catalogue indexes in ~14 hours on a single GPU. Subsequent adds are under 30 seconds per track.

Catalogue isolation is by architecture: separate database, separate process, separate trait vectors. Your audio never co-mingles with anyone else's.

Confidentiality and data handling

Versioning

The current major version is v1. Breaking changes will go to /api/v2; we will not change /api/v1 shapes without 90 days' notice. Bug-fix and additive changes (new optional fields, new endpoints, new trait additions) ship to v1 without notice; existing fields and endpoints stay stable.

Get an API key

Email [email protected] with a short note covering: what you want to use it for, expected request volume, and whether you want the public CC catalogue or a custom one ingested. Replies within 48 hours (Netherlands timezone, CET/CEST).

See also

everysong