Releases
A release is one product: an album, a single, an EP, a video. It carries its identifiers (UPC, GRid), its titles in every language it was delivered in, its credits, its labels, and the tracks and artwork that make it up.
Releases reach your catalog two ways: delivered as DDEX ERN messages (over SFTP or through the API), or authored through the API as a draft and then published. Both produce the same object.
Only published, deliverable releases appear in releases and release. Drafts and blocked deliveries have their own queries — see Release lifecycle.
- queryreleases
- queryreleasesCount
- queryrelease
- querydraftRelease
- querydraftReleases
- mutationcreateRelease
- mutationupdateRelease
- mutationpublishRelease
- mutationwithdrawRelease
- mutationreinstateRelease
The Release object#
One product — an album, single, EP or video — as it exists in your catalog. Scalar fields are cheap; the fields that take arguments load the release's contents, batched across every release in the request.
Attributes
releasePkInt!Unique identifier within //SCHEMA.- Universal Product Code, exactly as delivered. May be
nullon a draft. - Global Release Identifier, when one was supplied.
- The default title. For every language and script, use
titles. stateString!- When the release became (or becomes) available in your catalog. Your catalog's own gate — distinct from the label's per-deal windows in
deals. updatedAtDateTime!When the release last changed.- When the release was last edited through the API after being delivered.
nullif it still matches what the label sent. A redelivery overwrites local edits. - When the release was withdrawn from your catalog — by a DDEX purge or by withdrawRelease.
nullunlessstateiswithdrawn; reinstating clears it. resources[Resource!]!Every resource on the release — tracks, artwork and anything else — flattened in disc/side order. Usegroupswhen that structure matters.Arguments
kindMediaKindOnly resources of this kind —AUDIOfor the tracks,IMAGEfor the artwork. Measured once a file is analyzed, read from the resource type until then.
contributors[Credit!]!Parties credited on the release as a whole — display artists, the label, album-level credits. Track-level credits are on Resource.contributors.Arguments
roleStringOnly credits in this DDEX role, e.g.MainArtistorProducer. Case-insensitive.territoryStringOnly credits that apply in this territory, e.g.US: credits scoped to it, plus unqualified credits where nothing more specific exists. An explicitWorldwidecredit matches onlyterritory: "Worldwide".
titles[LocalizedText!]!Every title of the release, in every language, script and territory it was delivered with.Arguments
typeStringOnly variants of this text type, e.g.DisplayTitleorFormalTitle. Case-insensitive.languageStringOnly variants whose language tag is exactly this, e.g.ja-Jpanorja-Latn. The whole tag, not a prefix:jadoes not matchja-Jpan. Usescriptto select by script alone.scriptStringOnly variants in this ISO 15924 script, e.g.JpanorLatn.territoryStringOnly variants that apply in this territory, e.g.US: variants scoped to it, plus unqualified variants where nothing more specific exists. See Territories and languages.isDefaultBooleanOnly variants whose default flag matches. Many senders flag none as default, sotruecan legitimately return an empty list.
plines[Pline!]!℗ notices for the release as a whole.Arguments
languageStringOnly notices whose language tag is exactly this, e.g.enorja-Jpan.scriptStringOnly notices in this ISO 15924 script, e.g.Latn.territoryStringOnly notices that apply in this territory: those scoped to it, plus unqualified notices where nothing more specific exists.isDefaultBooleanOnly notices whose default flag matches.
clines[Cline!]!© notices — the composition or artwork right, not the recording.Arguments
languageStringOnly notices whose language tag is exactly this, e.g.enorja-Jpan.scriptStringOnly notices in this ISO 15924 script, e.g.Latn.territoryStringOnly notices that apply in this territory: those scoped to it, plus unqualified notices where nothing more specific exists.isDefaultBooleanOnly notices whose default flag matches.
labels[Label!]!The label(s) the release came out on, default first. Several is normal — an original label and a licensor, or a different label per territory.groups[ResourceGroup!]!The disc/side structure, as a tree. A two-disc album has two top-level groups.The release's front cover at one of your organization's artwork sizes — the same answer as Resource.artwork on its
FrontCoverImage, without finding the resource first:coverArt(size: "tile-600") { url width height }.nullwhen the release has no front cover, or its file has not arrived. An unknown label is anUNKNOWN_ARTWORK_SIZEerror.Arguments
- A label from artworkSizes, e.g.
tile-600.
dates[ReleaseDate!]!Dates the delivery asserted, such asReleaseDateandOriginalReleaseDate.deals[Deal!]!The availability windows the label asserted per commercial model and use type.
{
"releasePk": 48213,
"upc": "0196871402293",
"grid": null,
"title": "Paper Radio",
"state": "active",
"availableFrom": "2025-03-14T00:00:00+00:00",
"updatedAt": "2026-09-17T09:14:04.771520+00:00",
"locallyModifiedAt": null,
"withdrawnAt": null
}The ReleaseState enum#
A release's availability state in your catalog, as a filter for releases. The state field on a release is the same value in lowercase.
Values
DRAFTBeing authored; not yet published. Listing drafts needscatalog_write.PENDINGDelivered, waiting for its files.ACTIVELive.WITHDRAWNTaken down, by a DDEX purge or withdrawRelease.
The ResourceGroup object#
One node of a release's disc/side tree. Groups nest, so a box set can hold discs that hold sides.
Attributes
groupPkInt!Unique identifier.sequenceInt!Position among its siblings, from 1.- The group's title, e.g.
Disc 2, when one was given. resources[Resource!]!The resources directly in this group, in order.children[ResourceGroup!]!Nested groups.
{ "dateType": "OriginalReleaseDate", "territory": null, "value": "1994-11-02" }The Deal object#
One availability window the label asserted: when a commercial model and use type may sell this release. A release can carry several.
Attributes
- The DDEX commercial model, e.g.
SubscriptionModelorAdvertisementSupportedModel. - The DDEX use type, e.g.
StreamorPermanentDownload. - Window start, or
nullif open-ended. - Window end, or
nullif open-ended.
{
"commercialModel": "SubscriptionModel",
"useType": "Stream",
"start": "2025-03-14T00:00:00+00:00",
"end": null
}The PublishResult object#
The outcome of publishRelease. Validation problems come back here as data, not as GraphQL errors.
Attributes
{
"published": false,
"problems": ["a UPC or GRid is required to publish", "no cover art"],
"release": { "releasePk": 48290, "state": "draft" }
}The CreateReleaseInput input object#
Release fields you can set when creating or updating a release. Blank strings are treated as absent.
Fields
upcStringUniversal Product Code. Optional while drafting; a UPC or GRid is required to publish.gridStringGlobal Release Identifier.titleStringThe release title.releaseTypeStringThe DDEX release type, e.g.Album,Single,EP. Values outside the DDEX set are accepted and flagged.plines[CopyrightLineInput!]The release's ℗ notices — who owns the recordings. Omit to keep what is there; a list replaces them all;[]clears. Not required to publish. See CopyrightLineInput.clines[CopyrightLineInput!]The release's © notices — who owns the compositions and artwork. Same rule asplines.labels[LabelInput!]The label(s) the release came out on, as parties. Same rule asplines. See LabelInput.
List releases#
Returns releases in your catalog, most recently updated first, optionally narrowed by a search string.
By default only active and withdrawn releases are listed — the
published catalog. Pass states to choose: [WITHDRAWN] for
takedowns, [PENDING] for deliveries still waiting for files, or
[DRAFT] for unpublished work, which needs the catalog_write
scope, as draftReleases does. To find out
why a pending release is waiting, see
blockedReleases.
Page with limit and offset, and use
releasesCount with the same q and
states to know when to stop. See
Paginate and search.
Arguments
- Maximum number of releases to return. Clamped to 1–200.
- Number of releases to skip. Negative values are treated as 0.
- Case- and accent-insensitive partial match against the release title, a release-level display artist, or a label name. A release matches if any of the three matches. Accents fold on both sides, so
sineadfindsSinéad. states[ReleaseState!]Only releases in these states. Omitted,ACTIVEandWITHDRAWN. An empty list matches nothing. IncludingDRAFTneedscatalog_write.
Returns
A list of Release objects. Empty when nothing matches.
query ListReleases($q: String) {
releases(q: $q, limit: 2) {
releasePk
upc
title
state
availableFrom
}
}{
"q": "Halfway Ghosts"
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query ListReleases($q: String) {\n releases(q: $q, limit: 2) {\n releasePk\n upc\n title\n state\n availableFrom\n }\n}",
"variables": {
"q": "Halfway Ghosts"
}
}
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 ListReleases($q: String) {
releases(q: $q, limit: 2) {
releasePk
upc
title
state
availableFrom
}
}
`,
variables: {
"q": "Halfway Ghosts"
},
}),
});
const { data, errors } = await res.json();{
"data": {
"releases": [
{
"releasePk": 48213,
"upc": "0196871402293",
"title": "Paper Radio",
"state": "active",
"availableFrom": "2025-03-14T00:00:00+00:00"
},
{
"releasePk": 47102,
"upc": "0196871118736",
"title": "Slow Exit",
"state": "active",
"availableFrom": "2023-09-01T00:00:00+00:00"
}
]
}
}Count releases#
The total number of releases releases can page
through for the same q and states. A page that comes back full
is not proof there is another; this is.
Arguments
- The same search string you pass to
releases. states[ReleaseState!]The same states you pass toreleases. IncludingDRAFTneedscatalog_write.
Returns
An Int.
query {
releasesCount(q: "Halfway Ghosts")
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n releasesCount(q: \"Halfway Ghosts\")\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 {
releasesCount(q: "Halfway Ghosts")
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"releasesCount": 7
}
}Retrieve a release#
Fetch one release by UPC, with as much of its tree as you select — tracks, credits, titles, artwork URLs.
Returns null both when no release has that UPC and when one exists
but not in your catalog; the two are deliberately indistinguishable.
Drafts are not returned — use draftRelease.
Arguments
- The release's UPC, exactly as delivered (leading zeros included).
Returns
A Release, or null.
query GetRelease($upc: String!) {
release(upc: $upc) {
title
contributors(role: "MainArtist") {
party { name }
}
resources {
sequence
isrc
title
durationSeconds
state
}
}
}{
"upc": "0196871402293"
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query GetRelease($upc: String!) {\n release(upc: $upc) {\n title\n contributors(role: \"MainArtist\") {\n party { name }\n }\n resources {\n sequence\n isrc\n title\n durationSeconds\n state\n }\n }\n}",
"variables": {
"upc": "0196871402293"
}
}
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 GetRelease($upc: String!) {
release(upc: $upc) {
title
contributors(role: "MainArtist") {
party { name }
}
resources {
sequence
isrc
title
durationSeconds
state
}
}
}
`,
variables: {
"upc": "0196871402293"
},
}),
});
const { data, errors } = await res.json();{
"data": {
"release": {
"title": "Paper Radio",
"contributors": [
{ "party": { "name": "Halfway Ghosts" } }
],
"resources": [
{
"sequence": 1,
"isrc": "JPTO09404900",
"title": "Signal Fire",
"durationSeconds": 214,
"state": "stored"
},
{
"sequence": 2,
"isrc": "JPTO09404910",
"title": "Paper Radio",
"durationSeconds": 187,
"state": "stored"
},
{
"sequence": 3,
"isrc": null,
"title": null,
"durationSeconds": null,
"state": "stored"
}
]
}
}
}Retrieve a draft#
Fetch one release by releasePk, including drafts. This is how
an authoring client reads back its own unpublished work.
Requires catalog_write rather than catalog_read: unpublished work
is visible only to credentials that can author.
Arguments
- The release's primary key, as returned by createRelease.
Returns
A Release in any state, or null if it is not in your catalog.
query {
draftRelease(releasePk: 48290) {
releasePk
title
state
upc
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n draftRelease(releasePk: 48290) {\n releasePk\n title\n state\n upc\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 {
draftRelease(releasePk: 48290) {
releasePk
title
state
upc
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"draftRelease": {
"releasePk": 48290,
"title": "Night Ferry",
"state": "draft",
"upc": null
}
}
}List drafts#
Releases still being authored, most recently updated first.
Arguments
- Maximum number to return. Clamped to 1–200.
Returns
A list of Release objects in state draft.
query {
draftReleases(limit: 10) {
releasePk
title
updatedAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n draftReleases(limit: 10) {\n releasePk\n title\n updatedAt\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 {
draftReleases(limit: 10) {
releasePk
title
updatedAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"draftReleases": [
{
"releasePk": 48290,
"title": "Night Ferry",
"updatedAt": "2026-09-17T16:02:11.482913+00:00"
}
]
}
}Create a draft release#
Start a release. It is created in state draft and is private to
your catalog until you publish it — it
does not appear in releases or release(upc:).
Every input field is optional while drafting. A UPC or GRid is required to publish, unless your organization is exempt.
One call can carry the whole release's metadata: the ℗ and ©
notices (plines, clines) and the label (labels, a party from
createParty) go in the same input. None of
them is required to publish.
Arguments
- What you know about the release so far.
Show child parameters
upcStringUniversal Product Code. Optional while drafting; a UPC or GRid is required to publish.gridStringGlobal Release Identifier.titleStringThe release title.releaseTypeStringThe DDEX release type, e.g.Album,Single,EP. Values outside the DDEX set are accepted and flagged.plines[CopyrightLineInput!]The release's ℗ notices — who owns the recordings. Omit to keep what is there; a list replaces them all;[]clears. Not required to publish. See CopyrightLineInput.clines[CopyrightLineInput!]The release's © notices — who owns the compositions and artwork. Same rule asplines.labels[LabelInput!]The label(s) the release came out on, as parties. Same rule asplines. See LabelInput.
Returns
The new Release. Keep its releasePk.
mutation CreateRelease($input: CreateReleaseInput!) {
createRelease(input: $input) {
releasePk
state
title
plines { value }
labels { partyPk name }
}
}{
"input": {
"title": "Night Ferry",
"releaseType": "Album",
"plines": [
{
"text": "(P) 2026 Lanternfish Records",
"year": "2026"
}
],
"labels": [
{
"partyPk": 90211
}
]
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation CreateRelease($input: CreateReleaseInput!) {\n createRelease(input: $input) {\n releasePk\n state\n title\n plines { value }\n labels { partyPk name }\n }\n}",
"variables": {
"input": {
"title": "Night Ferry",
"releaseType": "Album",
"plines": [
{
"text": "(P) 2026 Lanternfish Records",
"year": "2026"
}
],
"labels": [
{
"partyPk": 90211
}
]
}
}
}
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: `
mutation CreateRelease($input: CreateReleaseInput!) {
createRelease(input: $input) {
releasePk
state
title
plines { value }
labels { partyPk name }
}
}
`,
variables: {
"input": {
"title": "Night Ferry",
"releaseType": "Album",
"plines": [
{
"text": "(P) 2026 Lanternfish Records",
"year": "2026"
}
],
"labels": [
{
"partyPk": 90211
}
]
}
},
}),
});
const { data, errors } = await res.json();{
"data": {
"createRelease": {
"releasePk": 48290,
"state": "draft",
"title": "Night Ferry",
"plines": [
{
"value": "(P) 2026 Lanternfish Records"
}
],
"labels": [
{
"partyPk": 90211,
"name": "Lanternfish Records"
}
]
}
}
}Update a release#
Change a release's UPC, GRid, title, type, ℗ and © notices or label. Only the fields you pass are changed; omitted fields keep their current value. Blank strings are treated as omitted.
The lists — plines, clines, labels — replace: passing one
sets exactly those entries, and [] removes them all. That is the
only way to clear something here.
Works on published and delivered releases too, so a typo in a
delivered release can be fixed without a redelivery. Editing a
delivered release sets locallyModifiedAt — and a later redelivery
from the label will overwrite your correction.
Arguments
- The release to change.
- The fields to change.
Show child parameters
upcStringUniversal Product Code. Optional while drafting; a UPC or GRid is required to publish.gridStringGlobal Release Identifier.titleStringThe release title.releaseTypeStringThe DDEX release type, e.g.Album,Single,EP. Values outside the DDEX set are accepted and flagged.plines[CopyrightLineInput!]The release's ℗ notices — who owns the recordings. Omit to keep what is there; a list replaces them all;[]clears. Not required to publish. See CopyrightLineInput.clines[CopyrightLineInput!]The release's © notices — who owns the compositions and artwork. Same rule asplines.labels[LabelInput!]The label(s) the release came out on, as parties. Same rule asplines. See LabelInput.
Returns
The updated Release. Errors with no such release in this catalog if it is not yours.
mutation {
updateRelease(releasePk: 48290, input: { upc: "0196871555012" }) {
releasePk
upc
locallyModifiedAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n updateRelease(releasePk: 48290, input: { upc: \"0196871555012\" }) {\n releasePk\n upc\n locallyModifiedAt\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: `
mutation {
updateRelease(releasePk: 48290, input: { upc: "0196871555012" }) {
releasePk
upc
locallyModifiedAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"updateRelease": {
"releasePk": 48290,
"upc": "0196871555012",
"locallyModifiedAt": null
}
}
}Publish a release#
Put a draft into the catalog. On success the release becomes
active, gets an availableFrom, and appears in releases.
A release can be published when it has:
- a UPC or a GRid,
- at least one resource,
- uploaded bytes for every resource, and
- a front cover image (
FrontCoverImage) with uploaded bytes.
If anything is missing, nothing changes and every problem comes
back in problems — as data, not as a GraphQL error — so you can show
a checklist and fix everything in one pass.
Idempotent: publishing an already-published release returns
published: true with no problems.
Arguments
- The draft to publish.
Returns
mutation {
publishRelease(releasePk: 48290) {
published
problems
release { state availableFrom }
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n publishRelease(releasePk: 48290) {\n published\n problems\n release { state availableFrom }\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: `
mutation {
publishRelease(releasePk: 48290) {
published
problems
release { state availableFrom }
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"publishRelease": {
"published": false,
"problems": [
"1 resource(s) have no uploaded bytes; complete their uploads before publishing"
],
"release": { "state": "draft", "availableFrom": null }
}
}
}Withdraw a release#
Take a release out of your catalog — a takedown. The release becomes
withdrawn, gets a withdrawnAt, and a release.state_changed
webhook announces it with to: "withdrawn".
This is the manual counterpart of a DDEX PurgeReleaseMessage, for
a takedown that reached you some other way: an email from the label,
a rights dispute, a mistake. A purge delivered over SFTP or through
deliverMessage does the same thing on
its own.
Withdrawal is a state, not a delete. The release, its tracks and its
files stay, it is still listed by releases with
state: "withdrawn", and reinstateRelease
undoes it. Media URLs are not refused for a withdrawn release; what you
do with its files is up to your agreement with the label.
Works on active releases and on pending ones still waiting for
files — a withdrawn release does not go live when its files arrive.
Withdrawing a release that is already withdrawn returns it unchanged.
A draft cannot be withdrawn: it was never published.
Arguments
- The release to withdraw.
Returns
The Release as it now stands. Errors with no release … in this catalog if it is not yours, and when the release is still a draft.
mutation {
withdrawRelease(releasePk: 48290) {
releasePk
state
withdrawnAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n withdrawRelease(releasePk: 48290) {\n releasePk\n state\n withdrawnAt\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: `
mutation {
withdrawRelease(releasePk: 48290) {
releasePk
state
withdrawnAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"withdrawRelease": {
"releasePk": 48290,
"state": "withdrawn",
"withdrawnAt": "2026-10-31T14:02:11.504193+00:00"
}
}
}Reinstate a release#
Put a withdrawn release back. It returns to the state it was
withdrawn from: active if it was live; pending if it was still
waiting for files, going live when they arrive — or at once, if they
arrived while it was withdrawn.
This is the only way back. Redelivering a withdrawn release updates its metadata but leaves it withdrawn, so a label resending an old message cannot undo a takedown.
A release that is not withdrawn is returned unchanged.
Arguments
- The release to reinstate.
Returns
The Release as it now stands. Errors with no release … in this catalog if it is not yours.
mutation {
reinstateRelease(releasePk: 48290) {
releasePk
state
withdrawnAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n reinstateRelease(releasePk: 48290) {\n releasePk\n state\n withdrawnAt\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: `
mutation {
reinstateRelease(releasePk: 48290) {
releasePk
state
withdrawnAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"reinstateRelease": {
"releasePk": 48290,
"state": "active",
"withdrawnAt": null
}
}
}