Work with localized metadata
Titles, names, credits and copyright notices can each exist in several variants. How to select the one your user should see.
The convenience fields, and when they are not enough#
Release.title, Resource.title and
Party.name each give you one value, preferring the variant the
sender marked as default. That is fine for a first pass. It is not fine when
the catalog carries the same title in more than one script — a Japanese
release routinely has both 夢のララバイ and Yume no Lullaby, and often
neither is marked default.
For those, ask for the full set and choose.
List every variant#
query {
release(upc: "4988006702236") {
titles {
value
type
language
script
territory
isDefault
}
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n release(upc: \"4988006702236\") {\n titles {\n value\n type\n language\n script\n territory\n isDefault\n }\n }\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query {
release(upc: "4988006702236") {
titles {
value
type
language
script
territory
isDefault
}
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"release": {
"titles": [
{ "value": "夢のララバイ", "type": "DisplayTitle", "language": "ja-Jpan", "script": "Jpan", "territory": null, "isDefault": false },
{ "value": "Yume no Lullaby", "type": "DisplayTitle", "language": "ja-Latn", "script": "Latn", "territory": null, "isDefault": false }
]
}
}
}Select by script or language#
To show the native-script title:
query {
release(upc: "4988006702236") {
titles(type: "DisplayTitle", script: "Jpan") { value }
}
}language matches the whole tag. language: "ja" does not match
ja-Jpan; that is deliberate, because a prefix match could not tell
ja-Jpan from ja-Latn — the very distinction you are trying to make. Use
script to choose a writing system, and language when you know the exact
tag.
The same filters are on Resource.titles and Party.names:
query {
release(upc: "4988006702236") {
contributors(role: "MainArtist") {
party {
name
romanized: names(script: "Latn") { value }
native: names(script: "Jpan") { value }
}
}
}
}Select by territory#
Pass a territory to get what applies there. The rule is:
- a variant scoped to that territory, if there is one; otherwise
- the unqualified variant (the sender did not restrict it, so it applies everywhere).
A variant scoped to a different territory is never returned — and neither
is one explicitly scoped to Worldwide unless you ask for Worldwide.
query {
release(upc: "0196871402293") {
titles(territory: "DE") { value territory }
}
}If the sender delivered a German title scoped to DE and an unqualified
title, you get the German one. For territory: "FR" you get the unqualified
one.
Credits by territory#
Credits follow the same rule. This returns the credits that apply in the US — US-specific ones, plus every credit the sender did not restrict:
query {
release(upc: "0196871402293") {
contributors(territory: "US") {
party { name }
role
roleKind
}
}
}Tell billing from personnel#
MainArtist and FeaturedArtist are billing roles
(roleKind: "DisplayArtistRole"); Producer, Mixer and
AssociatedPerformer describe people who worked on the recording
(roleKind: "ResourceContributorRole"). Filter on roleKind rather than
guessing from the role's name — the contributor vocabulary also contains
FoleyArtist and MakeUpArtist, which are not performers.
Copyright notices#
℗ notices (the recording) and © notices (the composition or artwork) are separate fields with the same filters:
query {
release(upc: "0196871402293") {
plines(territory: "US") { value year }
clines { value year }
resources {
title
plines { value year }
}
}
}A track's ℗ can differ from the release's — typically on a compilation, where each licensed track keeps its own owner's notice.
year is a string, exactly as delivered. Senders do not always send a bare
year, so parse it defensively.