Credits.fm

Music Credits API

Free REST API for songwriter credits, publisher chains, recording metadata, and music identifier lookups. No signup required.

ISRCISWCIPIISNIUPC

Quick start

Terminal
# Look up songwriter credits for any ISRC (snake_case JSON)
curl https://api.credits.fm/v1/isrc/GBAYE0601498

# Search across all identifier types
curl "https://api.credits.fm/v1/search?q=bohemian+rhapsody"

# Batch lookup — up to 100 identifiers at once
curl -X POST https://api.credits.fm/v1/batch
  -H "Content-Type: application/json"
  -d '{"isrcs":["GBAYE0601498","USUM71922944"]}'

# Resolve a Spotify URL to identifiers
curl "https://api.credits.fm/v1/lookup?url=https://open.spotify.com/track/5eIDxmWYxRA0HJBYM9bIIS"

Base URL: https://api.credits.fm — All endpoints return JSON with CORS enabled.

Authentication

Pass your API key via the x-api-key header:

curl -H "x-api-key: cfm_your_key_here" \
  https://api.credits.fm/v1/isrc/GBAYE0601498

No key? The API still works — just with lower rate limits.

Rate limits

TierLookupSearchMCPContribute
No key (per IP)30/min10/min20/minNot available
Free API key300/min60/min60/min10/min

Rate limit info is returned in X-RateLimit-Remaining and X-RateLimit-Limit response headers.

Get an API key

Generate a free API key instantly. No credit card or approval needed.

Optional — for contributor attribution

Max 3 keys per email. No credit card required.

Error responses

All errors return JSON with an error field:

StatusMeaningExample
400Missing or invalid parameter{"error": "ISRC is required"}
401API key required{"error": "API key required for contributions"}
404Identifier not found{"error": "ISRC not found"}
429Rate limit exceeded{"error": "Rate limit exceeded", "retryAfter": 42}
503Service unavailable{"error": "Service unavailable"}

All endpoints

Complete public /v1/* inventory from the live OpenAPI spec. Parameter schemas and Try-it live in the interactive reference (api.credits.fm/docs). Showing 80 operations.

API keys

Account & Claims

Audit

  • POST/v1/audit/catalogPublisher-catalog audit (two-file classification)Open in docs
  • POST/v1/audit/classifyClassify one ISRC (audit)Open in docs
  • POST/v1/audit/sharesShare audit (batch) — not currently available (returns 403 while MLC ownership shares are withheld pending licensing)Open in docs
  • POST/v1/audit/unmatchedUnmatched audit (batch)Open in docs

Batch

Billing

Catalog

  • POST/v1/catalog/analyzeAnalyze an ISRC catalog (publisher → writer-IPI → ISWC graph)Open in docs
  • POST/v1/catalog/enrichEnrich a catalog of ISRCs (queue graph-link + fetch MLC songwriters)Open in docs
  • POST/v1/publishersFind publishers for a writer across recordingsOpen in docs
  • POST/v1/songwritersAggregate songwriters across recordingsOpen in docs

Compositions

  • GET/v1/iswc/{iswc}/related-worksGet related-works group for ISWCOpen in docs
  • GET/v1/mlc/{code}/related-worksGet related-works group for MLC Song CodeOpen in docs
  • GET/v1/related-works/{id}Get related-works group by IDOpen in docs

Contributions

Cover art

Credits Compute

  • POST/v1/compute/resultSubmit a Credits Compute work-unit resultOpen in docs
  • GET/v1/compute/unitGet a Credits Compute work unitOpen in docs

Crowd verification

  • GET/v1/crowd/taskGet a crowd verification taskOpen in docs
  • POST/v1/crowd/voteVote on a crowd verification taskOpen in docs

Data contributions

Discovery

Enrich

Health

Lookup

  • GET/v1/lookupResolve URL (Spotify / Apple Music)Open in docs

Lookups

  • GET/v1/contributorsPublic contributors leaderboardOpen in docs
  • GET/v1/ipi-group/summaryCatalog verify summary for a group of IPIsOpen in docs
  • POST/v1/ipi-group/summaryCatalog verify summary for an IPI group (body variant)Open in docs
  • GET/v1/ipi/{ipi}Get IPIOpen in docs
  • GET/v1/ipi/{ipi}/publisher-linksPublisher links for a songwriter IPIOpen in docs
  • GET/v1/ipi/{ipi}/publishersGet publishers for songwriter IPIOpen in docs
  • GET/v1/ipi/{ipi}/registration-eligibilityRegistration eligibility for a songwriter IPIOpen in docs
  • GET/v1/ipi/{ipi}/summaryCatalog verify summary for an IPIOpen in docs
  • GET/v1/ipi/{ipi}/worksRanked works (ISWCs) for an IPIOpen in docs
  • GET/v1/isni/{isni}Get ISNIOpen in docs
  • GET/v1/isni/{isni}/recordingsGet recordings for an ISNIOpen in docs
  • GET/v1/isrc/{isrc}Get ISRCOpen in docs
  • GET/v1/isrc/{isrc}/mlc-liveLive MLC Public Work Search by ISRCOpen in docs
  • GET/v1/iswc/{iswc}Get ISWCOpen in docs
  • GET/v1/musician/{mbid}/publisher-linksPublisher links for a musician (MBID)Open in docs
  • GET/v1/musician/{mbid}/registration-eligibilityRegistration eligibility for a musician (MBID)Open in docs
  • GET/v1/publishers/{ipi}/catalogGet publisher catalog with optional audit flagsOpen in docs
  • GET/v1/publishers/{ipi}/musiciansMusicians administered by a publisherOpen in docs
  • GET/v1/publishers/searchSearch publishers by nameOpen in docs
  • GET/v1/upc/{upc}Get UPCOpen in docs

Music Identity

Ownership

  • POST/v1/ownership/analyzeSongwriter analysis across ISRCsOpen in docs
  • POST/v1/ownership/analyze-dataSongwriter analysis on caller-supplied matched_songs (no fetch)Open in docs
  • POST/v1/ownership/ip-chainsBroken IP-chain detection for a writer across ISRCsOpen in docs
  • POST/v1/ownership/ip-chains-dataBroken IP-chain detection on caller-supplied matched_songs (no fetch)Open in docs
  • POST/v1/ownership/representationSongwriter representation check across ISRCsOpen in docs
  • POST/v1/ownership/representation-dataRepresentation verdict on caller-supplied matched_songs (no fetch)Open in docs
  • POST/v1/ownership/searchSongwriter name search with representation analysisOpen in docs
  • POST/v1/ownership/search-dataSongwriter name search on caller-supplied matched_songs (no fetch)Open in docs

Relationships

  • GET/v1/isrc/{isrc}/relationshipsGet typed relationships for an ISRCOpen in docs
  • GET/v1/iswc/{iswc}/relationshipsGet typed relationships for an ISWCOpen in docs

Resolve

  • POST/v1/resolve/batchBatch resolve tracks to ISRCsOpen in docs
  • POST/v1/resolve/songwriterResolve songwriter name to IPIOpen in docs
  • POST/v1/resolve/trackResolve single track to ISRC and creditsOpen in docs

Search

Validate

Verify

  • GET/v1/verify/{type}/{code}Multi-source identifier verificationOpen in docs
  • POST/v1/verify/batchBatch multi-source verificationOpen in docs

Credits ID

Every entity in Credits.fm has a deterministic Credits ID — a UUIDv5 derived from its external identifier. The same input always produces the same UUID, so you can use it as a stable reference across systems.

EntityInputExample ID
Recordingisrc:GBAYE06014989b033599-8a5e-565a-b6b6-2dafbb91939c
Workiswc:T-070237966-1359586ff-b848-502f-98aa-8d33b7dba9fd
Songwriteripi:005085308615f8f3def-adf3-5f8e-b81f-db45093bf8c6
Contributorisni:0000000000012571c4d5e6f7-a8b9-5012-3456-789abcdef012
Albumupc:602445790098e5f6a7b8-c9d0-5123-4567-89abcdef0123
Musicianmusician:0383dadf-...a1b2c3d4-e5f6-5789-abcd-ef0123456789
Artistartist:1dfeR4HaWD...b2c3d4e5-f6a7-5890-bcde-f01234567890

Responses include credits_id. Response-only — you cannot yet query by Credits ID.

Credits Graph

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/graph/{type}/{id}

Credits Graph network — identifier nodes (isrc, iswc, ipi, isni, upc) plus musician (people) nodes, and connections around one code, with per-connection source provenance and verification status (verified = 2+ independent sources, single = one). Node no_match lists directions checked with no counterpart (verified absence); typed ISRC↔ISRC relationships (cover, sample, remix, …) appear as kind: relation connections, people credits as kind: credit. Every node carries a credits_id. Explore third-order by re-querying any node at depth=1 and merging.

ParameterTypeDescription
typerequiredstringisrc | iswc | ipi | isni | upc | musician (path; musician takes a MusicBrainz MBID — responses use Credits IDs as musician identity)
idrequiredstringIdentifier code (path)
depthnumber1–2 hops (default 2)
per_hopnumberConnection cap per node + neighbor type (default 12, max 25)
max_nodesnumberTotal node budget (default 200, max 300)
peoplestring0 to skip musician (people) nodes (default on)
/v1/graph/isrc/GBCEE9800022?depth=2
GET/v1/graph/activity

Credits Graph status feed — recent changes of every type across the index, newest first: link_found, link_verified (connection crossed 2+ independent sources), relation_found (cover/sample/remix), no_match_recorded (verified absence). Poll with since set to the previous response as_of for deltas (clamped to 24h).

ParameterTypeDescription
limitnumberMax events (default 60, max 150)
sincestringISO timestamp — only newer events
/v1/graph/activity?limit=60

Search & Discovery

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/identity

Music Identity discovery JSON (path templates, links). Same payload as GET /v1/. Full interactive reference: api.credits.fm/docs.

/v1/identity
GET/v1/suggest?q={query}

Fast autocomplete across identifier types. q optional; min 2 characters when provided. limit/offset window ≤ 1000.

ParameterTypeDescription
qstringPrefix (min 2 characters when provided)
limitnumberMax suggestions (default 10; 0 = bounded window)
offsetnumberSkip suggestions
nocachestringSkip CDN cache
/v1/suggest?q=taylor&limit=10
GET/v1/typeahead?q={query}

Cross-collection typeahead (Typesense-backed). Prefix + typo-tolerant autocomplete across recordings, songs, releases, publishers/writers, and artists. Response shape matches /v1/suggest so clients can share a parser. Falls back to PG /v1/suggest when Typesense is not configured.

ParameterTypeDescription
qstringSearch string (min 2 chars after trim)
limitnumberMax suggestions after interleaving (default 10)
nocachestringSkip CDN cache (aliases: no_cache, fresh)
/v1/typeahead?q=bohem&limit=10
GET/v1/samples

Up to ten example identifiers per type from the live index (ISRC, ISWC, IPI, ISNI, UPC, MBID). Use to build working detail URLs against your deployment.

/v1/samples
GET/v1/health

Service health: database reachability and critical table row thresholds. 503 when unavailable or below threshold. Same checks as GET /healthz on api.credits.fm.

/v1/health

Identifier Lookups

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/isrc/{isrc}

Recording by ISRC (snake_case). Flat document by default; graph query keys return Music Identity graph (human-readable /v1/recordings/{isrc} 308s here). See api.credits.fm/docs for the full parameter matrix.

ParameterTypeDescription
isrcrequiredstring12-character ISRC (dashes/spaces stripped)
contributestring | booleanFlat JSON only: pass false to omit missing_fields and contribute_url. Ignored for graph responses.
graphstringTruthy (1 / true / yes): default Music Identity graph when no other graph keys are present.
identity_graphstringAlias for graph (same semantics).
includestringComma-separated relationship keys; merged with relationships / relationship. Use all to expand every connection.
relationshipsstringLuminate-style alias for include (values merged).
relationshipstringSingular alias; merged with include.
depthnumberGraph expansion depth 1–5 (default 1).
limitnumberPer-relationship page size (default 50, max 10000; -1 = all). On ISNI flat (no graph keys), paginates isrcs / iswcs with total_isrcs / total_iswcs.
offsetnumberSkip N items for each expanded list (or ISNI flat isrcs/iswcs slices).
/v1/isrc/GBAYE0601498?graph=1
GET/v1/isrc/{isrc}/mlc-live

Authoritative live MLC Public Work Search by ISRC — work(s) with writer chains, ISWCs, publishers, and alternative titles. Cached 14 days server-side; pass ?refresh=true to force a fresh MLC fetch. source is cache | live | stale | unavailable. Empty works means no MLC registration (or temporary unavailability when source is unavailable).

ParameterTypeDescription
isrcrequiredstring12-character ISRC (path)
refreshbooleanBypass the 14-day cache and force a fresh MLC API call
/v1/isrc/GBAYE0601498/mlc-live
GET/v1/iswc/{iswc}

Musical work by ISWC. Flat work row or Music Identity graph (/v1/songs/{iswc} 308s here). For large recording lists use graph + include / pagination — not the old credits.fm-only complete query.

ParameterTypeDescription
iswcrequiredstringISWC (T-#########-# or compact)
contributestring | booleanFlat JSON only: pass false to omit missing_fields and contribute_url. Ignored for graph responses.
graphstringTruthy (1 / true / yes): default Music Identity graph when no other graph keys are present.
identity_graphstringAlias for graph (same semantics).
includestringComma-separated relationship keys; merged with relationships / relationship. Use all to expand every connection.
relationshipsstringLuminate-style alias for include (values merged).
relationshipstringSingular alias; merged with include.
depthnumberGraph expansion depth 1–5 (default 1).
limitnumberPer-relationship page size (default 50, max 10000; -1 = all). On ISNI flat (no graph keys), paginates isrcs / iswcs with total_isrcs / total_iswcs.
offsetnumberSkip N items for each expanded list (or ISNI flat isrcs/iswcs slices).
/v1/iswc/T-070237966-1?include=recordings&limit=100
GET/v1/ipi/{ipi}

Songwriter or publisher by IPI. represent=musician|publisher drives graph shape; older /v1/musicians/… / /v1/publishers/… paths 308 here.

ParameterTypeDescription
ipirequiredstring9–11 digit IPI
graphstringTruthy (1 / true / yes): default Music Identity graph when no other graph keys are present.
identity_graphstringAlias for graph (same semantics).
representstringGraph mode: musician | publisher (forces graph; inferred from entity_type when omitted)
contributestring | booleanFlat JSON only: pass false to omit missing_fields and contribute_url. Ignored for graph responses.
includestringComma-separated relationship keys; merged with relationships / relationship. Use all to expand every connection.
relationshipsstringLuminate-style alias for include (values merged).
relationshipstringSingular alias; merged with include.
depthnumberGraph expansion depth 1–5 (default 1).
limitnumberPer-relationship page size (default 50, max 10000; -1 = all). On ISNI flat (no graph keys), paginates isrcs / iswcs with total_isrcs / total_iswcs.
offsetnumberSkip N items for each expanded list (or ISNI flat isrcs/iswcs slices).
/v1/ipi/00508530861?graph=1
GET/v1/ipi/{ipi}/publishers

All publishers that co-occur with this songwriter IPI. Optional include=isrcs for shared ISRC lists per publisher.

ParameterTypeDescription
ipirequiredstringSongwriter IPI
includestringisrcs — attach shared ISRC arrays per publisher
/v1/ipi/00508530861/publishers?include=isrcs
GET/v1/isni/{isni}

Creative contributor by ISNI. Flat document, optional isrcs/iswcs pagination, or graph mode. Includes recordings_urlGET /v1/isni/{isni}/recordings.

ParameterTypeDescription
isnirequiredstring16-character ISNI
contributestring | booleanFlat JSON only: pass false to omit missing_fields and contribute_url. Ignored for graph responses.
graphstringTruthy (1 / true / yes): default Music Identity graph when no other graph keys are present.
identity_graphstringAlias for graph (same semantics).
includestringComma-separated relationship keys; merged with relationships / relationship. Use all to expand every connection.
relationshipsstringLuminate-style alias for include (values merged).
relationshipstringSingular alias; merged with include.
depthnumberGraph expansion depth 1–5 (default 1).
limitnumberPer-relationship page size (default 50, max 10000; -1 = all). On ISNI flat (no graph keys), paginates isrcs / iswcs with total_isrcs / total_iswcs.
offsetnumberSkip N items for each expanded list (or ISNI flat isrcs/iswcs slices).
/v1/isni/0000000000012571
GET/v1/upc/{upc}

Release by UPC/EAN (snake_case flat row or graph). Older /v1/releases/{upc} paths 308 here. No contribution hints on flat rows.

ParameterTypeDescription
upcrequiredstring12–14 digit UPC
graphstringTruthy (1 / true / yes): default Music Identity graph when no other graph keys are present.
identity_graphstringAlias for graph (same semantics).
includestringComma-separated relationship keys; merged with relationships / relationship. Use all to expand every connection.
relationshipsstringLuminate-style alias for include (values merged).
relationshipstringSingular alias; merged with include.
depthnumberGraph expansion depth 1–5 (default 1).
limitnumberPer-relationship page size (default 50, max 10000; -1 = all). On ISNI flat (no graph keys), paginates isrcs / iswcs with total_isrcs / total_iswcs.
offsetnumberSkip N items for each expanded list (or ISNI flat isrcs/iswcs slices).
/v1/upc/602445790098?graph=1

People

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/musician/{mbid}

Musician profile (MusicBrainz MBID) — songwriter + performer credits, groups, identifiers. Fields are snake_case where emitted.

ParameterTypeDescription
mbidrequiredstringMusicBrainz artist UUID
/v1/musician/0383dadf-2a4e-4d10-a46a-e9e041da8eb3
GET/v1/artist/{id}

DSP release-artist discography (snake_case).

ParameterTypeDescription
idrequiredstringSpotify-style artist id (22 chars)
/v1/artist/1dfeR4HaWDbWqFHLkxsg1d

Resolution

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/lookup?url={url}

Resolve Spotify or Apple Music URLs to identifiers and metadata (snake_case).

ParameterTypeDescription
urlrequiredstringSpotify or Apple Music URL
/v1/lookup?url=https://open.spotify.com/track/5eIDxmWYxRA0HJBYM9bIIS
POST/v1/resolve/track

Resolve a track to ISRC + credits (name/artist and/or platform URLs). Optional contribute in JSON body.

ParameterTypeDescription
namestringTrack title
artiststringArtist name
spotify_urlstringSpotify track URL
apple_music_urlstringApple Music track URL
contributebooleanContribution hints on success (default true)
POST {"name":"Bohemian Rhapsody","artist":"Queen","contribute":true}
POST/v1/resolve/songwriter

Resolve songwriter name to IPI using ISRC/ISWC context (snake_case response fields).

ParameterTypeDescription
namerequiredstringSongwriter name
isrcsstring[]Context ISRCs
iswcsstring[]Context ISWCs
POST {"name":"Rowe","isrcs":["GBAYE0601498"]}
POST/v1/resolve/batch

Batch-resolve tracks (up to 50 {name, artist} pairs) to ISRCs.

ParameterTypeDescription
tracksrequiredarray{name, artist} pairs (max 50)
POST {"tracks":[{"name":"Bohemian Rhapsody","artist":"Queen"}]}

Data

Curated examples — full parameter matrix: api.credits.fm/docs

POST/v1/batch

Batch lookup — up to 100 identifiers per type per request (snake_case maps). MusicBrainz fallback where configured. Public: does not validate x-api-key (header ignored). A 200 here does not prove an API key is valid — use POST /v1/contribute to test credentials.

ParameterTypeDescription
isrcsstring[]Up to 100 ISRCs
iswcsstring[]Up to 100 ISWCs
ipisstring[]Up to 100 IPIs
isnisstring[]Up to 100 ISNIs
upcsstring[]Up to 100 UPCs
contributebooleanTop-level contribute_url nudges (default on)
POST {"isrcs":["GBAYE0601498"]}
POST/v1/catalog/analyze

Analyze an ISRC catalog into a publisher → writer-IPI → ISWC graph. Pass a flat isrcs list for ad-hoc lookups, or a pre-grouped songs array to reproduce a publisher catalog structure. Powers catalog tooling and POST /v1/catalog/analyze clients.

ParameterTypeDescription
isrcsstring[]Flat ISRC list (each becomes a 1-row song)
songsarrayPre-grouped song structure (writers + ISRC variants per song)
POST {"isrcs":["GBAYE0601498","USUM71922944"]}
POST/v1/contribute

Submit index improvements. Requires cfm_… key registered in api_keys (same Supabase project as lookups). Request/response use snake_case (e.g. target_id in results). If batch works with the same header but this returns 401, the key is invalid or not cfm_-prefixed — not a separate database.

ParameterTypeDescription
contributionsrequiredarrayContribution objects (max 25)
.targetrequiredstringisrc | iswc | ipi | isni | upc
.idrequiredstringIdentifier value
.fieldrequiredstringField key (snake_case)
.valuerequiredstringNew value
.typestringfill_null | correction | append
.citationstringProvenance string
POST {"contributions":[{"target":"isrc","id":"GBAYE0601498","field":"iswc","value":"T-070237966-1"}]}
GET/v1/coverage

Index row counts / coverage metrics (snake_case nested keys).

/v1/coverage

Validation & Audit

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/verify/{type}/{code}

Multi-source verification for one identifier (type: isrc | iswc | ipi | isni | upc). Per-field agreement across Notes Credits, MusicBrainz, DSPs, CISAC, ISNI.org as applicable. Optional ?raw=1 for adapter debug payloads.

ParameterTypeDescription
typerequiredstringisrc | iswc | ipi | isni | upc
coderequiredstringIdentifier value (normalized server-side)
rawstringPass 1 to include raw per-adapter results
/v1/verify/isrc/GBAYE0601498
POST/v1/verify/batch

Batch verify up to 100 { type, code } items. Invalid rows return inline { error, input }; order preserved.

ParameterTypeDescription
itemsrequiredarrayObjects with type + code (max 100)
POST {"items":[{"type":"isrc","code":"GBAYE0601498"}]}
POST/v1/validate/batch

Validate ISRCs against MLC (+ optional DSP cross-check). ?format=csv supported. Results use snake_case.

ParameterTypeDescription
isrcsrequiredstring[]Up to 100 ISRCs
include_dsp_checkbooleanSpotify + Apple cross-check
POST {"isrcs":["GBAYE0601498"],"include_dsp_check":true}
POST/v1/audit/shares

Songwriter share-ownership audit. Not currently available on the public API — ownership share percentages are withheld pending licensing, so this endpoint returns 403. Songwriter/publisher names, roles, IPIs and relationships remain available on the lookup endpoints.

ParameterTypeDescription
isrcsrequiredstring[]Up to 100 ISRCs
POST {"isrcs":["GBAYE0601498"]}
POST/v1/audit/unmatched

MLC match status audit. ?format=csv supported.

ParameterTypeDescription
isrcsrequiredstring[]Up to 100 ISRCs
POST {"isrcs":["GBAYE0601498"]}

API keys & operator hooks

Curated examples — full parameter matrix: api.credits.fm/docs

POST/v1/keys

Create a free cfm_… API key (name + email). Returns the secret once. Max 3 active keys per email. Same flow as the key form at credits.fm/api.

ParameterTypeDescription
namerequiredstring2–100 characters
emailrequiredstringValid email
contributor_namestringDisplay name for contributions
contributor_urlstringContributor URL
POST {"name":"CI","email":"you@example.com"}
POST/v1/enrich

Batch ISWC titles + ISRC metadata (title, artists) for lazy UI loads. Public; capped per array server-side.

ParameterTypeDescription
iswcsstring[]ISWC codes
isrcsstring[]ISRC codes
POST {"iswcs":["T-070237966-1"],"isrcs":["GBAYE0601498"]}
POST/v1/cover-art

Cover art URLs for up to 10 ISRCs (cache + Spotify when configured).

ParameterTypeDescription
isrcsrequiredstring[]Max 10 ISRCs
POST {"isrcs":["GBAYE0601498"]}

Crowd verification (anonymous)

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/crowd/task?target={type}&id={code}&session_id={uuid}

One one-tap verification microtask for a record — a real source disagreement (kind: conflict) or a known-answer control item (kind: credit). No API key. Pass a client-generated session_id (UUID) so voted tasks are not re-served. Returns { task: null } when there is nothing to verify.

ParameterTypeDescription
targetrequiredstringisrc | iswc | ipi | isni | upc
idrequiredstringThe identifier code
session_idstringClient-generated UUID (first-party cookie)
GET /v1/crowd/task?target=isrc&id=GBAYE0601498&session_id=…
POST/v1/crowd/vote

Record an anonymous vote on a microtask. No API key. value must be one of the task options’ values, or { "not_sure": true }. Credit tasks score the session’s trust weight; conflict tasks evaluate weighted consensus. A field flips to verified only when enough trusted, independent sessions confirm the live value — anonymous votes never overwrite a canonical value.

ParameterTypeDescription
task_idrequiredstringFrom GET /v1/crowd/task
session_idrequiredstringSame UUID used to fetch the task
valuerequiredanyChosen option value, or { not_sure: true }
POST {"task_id":"isrc:GBCEE9800022:recording_title:conflict","session_id":"…","value":"Bohemian Rhapsody"}

Credits Compute

Curated examples — full parameter matrix: api.credits.fm/docs

GET/v1/compute/unit

Request a Credits Compute work unit — rank the candidate compositions by similarity to the anchor and submit the best to earn access credits. No API key; identify with a session_id. Returns { unit: { unit_token, anchor, candidates[] } }, or { unit: null } when none is available. Results are verified server-side.

ParameterTypeDescription
session_idrequiredstringClient-generated UUID (reuse it across requests)
/v1/compute/unit?session_id=2b1f…-uuid
POST/v1/compute/result

Submit a work-unit result. No API key. The server re-verifies the ranking before it counts; verified contributions are staged additively (never overwriting canonical data) and accrue an access-credit balance that raises your tier (base → contributor → partner).

ParameterTypeDescription
session_idrequiredstringSame UUID used to fetch the unit
unit_tokenrequiredstringFrom GET /v1/compute/unit
winner_idrequiredstringChosen candidate's identifier
scorerequirednumberYour computed similarity (0–1)
POST {"session_id":"…","unit_token":"…","winner_id":"T-070237966-1","score":0.82}
GET/v1/me

Your earned Credits Compute status. Identify with an API key (x-api-key) and/or a compute session_id. Returns your effective tier, contribution totals, your claimed identifiers (claims), and whether the optional email account layer is available on this deployment (account_sign_in).

ParameterTypeDescription
session_idstringCompute session UUID (optional if using an API key)
/v1/me?session_id=2b1f…-uuid

Your Credits Graph (claims & accounts)

Curated examples — full parameter matrix: api.credits.fm/docs

POST/v1/me/claims

Claim an identifier for your personal Credits Graph. No API key — identify with your compute session_id (body, query, or x-compute-session header). The code must exist in the Credits index; up to 24 claims per session (the personal graph’s one-traversal budget). Idempotent — re-claiming answers 200. Claiming is open and never gates anything; verification (unverified | compute_verified | owner_verified) is a separate trust signal derived from your earned Credits Compute tier.

ParameterTypeDescription
session_idrequiredstringClient-generated UUID (the compute session)
typerequiredstringisrc | iswc | ipi | isni | upc | musician (MBID)
coderequiredstringThe identifier code to claim
POST {"session_id":"…","type":"ipi","code":"00052210040"}
GET/v1/me/claims?session_id={uuid}

List your claimed identifiers, each with its verification trust signal.

ParameterTypeDescription
session_idrequiredstringCompute session UUID
/v1/me/claims?session_id=2b1f…-uuid
DELETE/v1/me/claims/{code}?type={type}&session_id={uuid}

Remove a claim. Idempotent — removing a code you never claimed answers 200 with removed: 0.

ParameterTypeDescription
coderequiredstringThe claimed code (path)
typestringDisambiguate the claim type (recommended)
session_idrequiredstringCompute session UUID
DELETE /v1/me/claims/00052210040?type=ipi&session_id=…
GET/v1/me/graph?session_id={uuid}&depth=1

Your personal Credits Graph: one seeded traversal across every claimed code, a synthetic you root node (hop 0) with kind: claim connections to your codes, and a per-claim gaps summary — verified, single_source, verifiable (fixable right now via Credits Compute), and no_match (verified absences). Zero claims still answers 200 with the you node and a hint. depth 1–2 (default 1). Musician claims expand to their IPI/ISNI/ISRC codes.

ParameterTypeDescription
session_idrequiredstringCompute session UUID
depthnumberHops beyond your claimed codes (1–2, default 1)
/v1/me/graph?session_id=2b1f…-uuid&depth=1
POST/v1/account/verify

Exchange the emailed token for a 90-day bearer account_token (send it as Authorization: Bearer …). Verifying adopts your session onto the account; a session already on a different account reports session_conflict: true and login still succeeds. Links are single-use — used, expired, or superseded links answer 401.

ParameterTypeDescription
tokenrequiredstringThe token from the emailed link
session_idstringSession to adopt (falls back to the one that requested the link)
POST {"token":"…from the email…","session_id":"…"}
GET/v1/account/me

The signed-in account: adopted sessions, the best earned Credits Compute tier across them, and the deduped union of their claims. Authorization: Bearer <account_token> — header-only transport, no cookies.

GET /v1/account/me (Authorization: Bearer …)

Verify and improve data

These endpoints solve different jobs. Choose by what your integration already knows:

Verify

GET /v1/verify/{type}/{code}

Inspect what independent sources say about an identifier. No API key.

Contribute

POST /v1/contribute

Submit sourced metadata or links your integration already has. API key required.

Crowd

GET /v1/crowd/task → POST /v1/crowd/vote

Ask a person or agent one field-choice question. Anonymous session UUID.

Compute

GET /v1/compute/unit → POST /v1/compute/result

Let software rank a server-issued candidate set. Anonymous session UUID.

Verify inspects evidence; Contribute submits evidence. Crowd and Compute never blindly overwrite canonical data.

Contribute data

Submit sourced data your integration already has. Every item is validated and may be applied, verified against existing evidence, queued for review, recorded as negative evidence, or rejected. Requires a free API key.

What you can contribute

TargetFieldsTypes
isrcrecording_title, song_title, artist_names, iswc, songwriters, cover_art_url, mlc_song_codefill_null, correction
iswcsong_title, alternative_titles, songwriter_names, artist_namesfill_null, append, correction
ipifull_name, alternative_names, roles, entity_typefill_null, append
isnifull_name, roles, linked_ipisfill_null, append
upcalbum_title, artist_namesfill_null, correction
Example: Add a missing ISWC to an ISRC
curl -X POST https://api.credits.fm/v1/contribute \
  -H "Content-Type: application/json" \
  -H "x-api-key: cfm_your_key_here" \
  -d '{
    "contributions": [{
      "target": "isrc",
      "id": "GBAYE0601498",
      "field": "iswc",
      "value": "T-070237966-1",
      "citation": "CISAC registry"
    }]
  }'

How contributions are verified

  • Inspect every results[].status; HTTP 201 means the batch was processed, not that every item was applied
  • fill_null only applies if the field is currently empty — it won't overwrite existing data
  • append adds to array fields (e.g., alternative names, roles) and skips duplicates
  • correction overwrites existing data — requires a high trust score (50+)
  • Unknown identifiers can receive sparse fill/append records; corrections still require an existing record
  • Accepted ISRC↔ISWC links update both ISRC→ISWC and ISWC→ISRC reads before the response returns
  • Field-level risk assessment: low-risk fields (titles, URLs) auto-accept at trust 1+, medium-risk (artist names, ISWCs) at 10+, high-risk (songwriters) at 50+
  • New API keys start with manual review; accepted contributions increase your trust score for auto-acceptance

Auto-contribute on lookup

On v1, lookups that support contribution hints (/v1/isrc, /v1/iswc, /v1/ipi, /v1/isni, /v1/batch, /v1/resolve/track, …) may include missing_fields and contribute_url unless you pass ?contribute=false (GET) or "contribute": false (POST body) where applicable.

What you get

Songwriter credits

Names, roles (lyricist, composer, arranger), and publisher relationships from MLC data

Publisher chains

Full publisher hierarchy — original publishers, sub-publishers, and administrator relationships

Recording metadata

Titles, artist names, ISWC connections, match status, and platform links (Spotify, Apple Music)

Musician profiles

The real person behind the music — songwriter + performer credits, group memberships, IPI/ISNI identifiers

Artist discographies

Full DSP catalog for any release artist — albums, tracks with ISRCs, UPCs, and streaming links

Cross-references

ISRC to ISWC, IPI to ISNI, recording to work — every identifier linked to every other

URL resolution

Paste a Spotify or Apple Music link, get back ISRCs, UPCs, and full track listings

Data sources

Every response aggregates data from multiple authoritative sources in parallel:

MLCSongwriter names, publisher chains, roles
MusicBrainzRecording metadata, artist credits, ISWCs, group memberships (CC0)
CISACAuthoritative ISWC registry with redirect resolution
ISNI.orgCreative contributor identities, name variants, cross-industry linking
SpotifyNavigation links + factual metadata gap-fill (titles, artist names); cover art not redistributed
Apple MusicNavigation links + factual metadata gap-fill (titles, artist names); cover art not redistributed

Apple Music and Spotify are link sources: we link out so listeners can open a recording, and use their factual metadata (recording/album titles, artist names) to fill records the open sources don’t cover. Those platform-origin fields are attributed to the platform and are not claimed under Credits.fm’s CC-BY 4.0 license; their cover art is governed by their own developer terms and is not redistributed. Cover art returned by the API (e.g. /v1/cover-art) is limited to open-licensed artwork from the MusicBrainz Cover Art Archive.

Identifier types

CodeFull nameIdentifiesFormat
ISRCInternational Standard Recording CodeSound recordings & music videosGBAYE0601498
ISWCInternational Standard Musical Work CodeMusical compositionsT-070237966-1
IPIInterested Parties InformationSongwriters & publishers00508530861
ISNIInternational Standard Name IdentifierCreative contributors0000000000012571
UPCUniversal Product CodeAlbum releases602445790098

Use with AI

Credits.fm is designed to work with AI assistants. Use the MCP server for native tool access, the OpenAPI spec for one-click setup, or copy a system prompt for any AI tool.

Claude Code, Cursor, Windsurf (MCP)

Connect directly via the Credits.fm MCP server — 8 tools, no auth required.

See credits.fm/mcp/docs for setup configs.

ChatGPT Custom GPTs

  1. Go to ChatGPT → Explore GPTs → Create
  2. Under “Actions”, click “Create new action”
  3. Click “Import from URL”
  4. Paste: https://api.credits.fm/_openapi.json (or https://api.credits.fm/openapi.json — redirects to the same spec)
  5. Done — your GPT can now call all Credits.fm endpoints

Optional: under Authentication, select “API Key”, header name x-api-key, and paste your key for higher rate limits.

Cursor

  1. Add an MCP server in Cursor Settings → MCP
  2. Or add a .cursor/mcp.json to your project with a fetch-based tool pointing to https://api.credits.fm/v1/
  3. Alternatively, paste the system prompt below into your project's .cursorrules file so the agent knows how to call the API via curl

System prompt for ChatGPT, Claude, Cursor, or any AI assistant

Paste this into your Custom GPT instructions, Claude Project instructions, Cursor rules, or any system prompt:

System prompt
You are a music credits research assistant powered by the Credits.fm API (https://credits.fm). You help users find songwriter credits, music identifiers, and music metadata.

Primary base URL: https://api.credits.fm/v1 — **snake_case** JSON. Full parameter matrix: https://api.credits.fm/docs (Scalar OpenAPI).

Core endpoints:
- GET /v1/identity — Music Identity discovery (same as GET /v1/)
- GET /v1/graph/search?q={query} — Bucketed Music Identity search
- GET /v1/search?q={query} — Unified search (nested buckets, snake_case pagination)
- GET /v1/suggest?q={query} — Autocomplete
- GET /v1/isrc/{isrc}, /v1/iswc/{iswc}, /v1/ipi/{ipi}, /v1/isni/{isni}, /v1/upc/{upc} — Identifier lookups (+ graph query keys: graph, identity_graph, include, depth, limit, offset, …)
- GET /v1/ipi/{ipi}/publishers — Publishers for a songwriter IPI
- GET /v1/musician/{mbid}, GET /v1/artist/{id} — Musician (MBID) vs DSP artist discography
- GET /v1/lookup?url={url} — Spotify / Apple Music URL resolution
- POST /v1/resolve/track, /v1/resolve/songwriter, /v1/resolve/batch — Resolution helpers
- POST /v1/batch — Batch lookup (up to 100 per type)
- GET /v1/verify/{type}/{code}, POST /v1/verify/batch — INSPECT independent source agreement; does not accept caller-supplied values
- POST /v1/contribute — SUBMIT sourced values you already have (requires x-api-key; inspect every per-item status)
- GET /v1/crowd/task, POST /v1/crowd/vote — Human/agent field-choice loop (anonymous session UUID)
- GET /v1/compute/unit?session_id={uuid}, POST /v1/compute/result, GET /v1/me?session_id={uuid} — Software candidate-matching loop. Always follow the returned task_type; identity, crosslink_verify, writer_ipi, and composition_similarity are supported. No API key.
- GET /v1/coverage — Index coverage metrics
- POST /v1/validate/batch, /v1/audit/shares, /v1/audit/unmatched — Validation & audit (CSV via ?format=csv where supported)

Workflow:
1. Start with GET /v1/search?q={query} or /v1/graph/search as appropriate
2. Use returned identifiers for GET /v1/isrc/{isrc}, /v1/iswc/{iswc}, /v1/ipi/{ipi}, etc.
3. Inspect evidence with GET /v1/verify/{type}/{code}
4. Submit sourced missing data with POST /v1/contribute
5. Use Crowd for one field choice or Compute for software candidate matching
6. Coverage gaps: GET /v1/coverage

Key concepts:
- **credits_id** = deterministic UUIDv5 for every entity.
- ISRC = recording; ISWC = composition; IPI = songwriter/publisher; ISNI = contributor; UPC = album.
- Artist = DSP release artist (/v1/artist/{id}); Musician = person profile (/v1/musician/{mbid}).

Always present songwriter credits with roles and publisher relationships when available. Link to credits.fm pages for exploration.

Crowd verification

Put one source disagreement in front of a person or agent. No API key is required; generate one UUID and reuse it as the session ID.

How it works

  1. Call GET /v1/crowd/task with target, ID, and session UUID
  2. Render the returned field and options without guessing whether it is a hidden control
  3. Submit one exact option value, or { "not_sure": true }, to POST /v1/crowd/vote

A session has zero voting weight until it answers at least three hidden controls correctly. Consensus requires three distinct voters, trusted weight ≥2, and a winning margin ≥1. Anonymous votes can confirm the live value or flag a competing value for review; they never replace a canonical scalar.

Credits Compute

Let software rank a small, server-issued candidate set. No API key is required; reuse one session UUID so trust and access credits accumulate.

Two-step protocol

  1. Call GET /v1/compute/unit?session_id=…
  2. Branch on the returned task_type and choose one candidate
  3. Submit the opaque token and winner to POST /v1/compute/result
composition_similarity

Same musical work; real units require a local score

identity

Same person or organization: IPI ↔ ISNI

crosslink_verify

Recording belongs to work: ISRC ↔ ISWC

writer_ipi

Writer name belongs to IPI

Always use the returned task type: hidden composition controls can be interleaved even when identity work was requested. staged means server-checked and awaiting consensus; it does not mean the link is already public.

Verified compute raises access Base → Contributor → Partner. See Credits API pricing for tier details.

Powered by Notes.fm