//SCHEMADocs
Console
Tutorials

Quickstart

By the end of this tutorial you will have an API key, have confirmed it works, and have read a release from your catalog with its tracks and credits.

You need a //SCHEMA account with the owner or admin role, and a terminal with curl. Nothing else.

1. Create an API key#

Sign in to the console, open API Access, and create a key named Quickstart with these scopes:

  • catalog_read — to read releases
  • media_read — to get links to the audio

Copy the key when it is shown. It begins sk_, and it is shown once: //SCHEMA keeps only a hash of it.

Put it in an environment variable so the examples below can use it:

export SCHEMA_API_KEY=sk_...

2. Check that the key works#

Ask the API who you are. viewer needs no particular scope, so it is the simplest possible request:

curl https://api.schema.fm/graphql \
  -H "Authorization: Bearer $SCHEMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "{ viewer { actorType catalogPk scopes } }"}'

You should see:

{"data":{"viewer":{"actorType":"api_key","catalogPk":31,"scopes":["CatalogRead","MediaRead"]}}}

catalogPk is the catalog this key is bound to. Every request you make with it acts on that catalog — there is no catalog argument anywhere in the API.

If you see "code": "UNAUTHENTICATED" instead, the key was not sent or was mistyped. Check the header reads Authorization: Bearer sk_….

3. List your releases#

Everything is one endpoint; only the query changes. Ask for the three most recently updated releases:

Request
query {
  releases(limit: 3) {
    releasePk
    upc
    title
    state
  }
}
Response
{
  "data": {
    "releases": [
      { "releasePk": 48213, "upc": "0196871402293", "title": "Paper Radio", "state": "active" },
      { "releasePk": 48190, "upc": "0196871377720", "title": "Low Orbit", "state": "active" },
      { "releasePk": 47102, "upc": "0196871118736", "title": "Slow Exit", "state": "active" }
    ]
  }
}

If the list is empty, your catalog has no published releases yet. Either deliver one, or follow Publish a release and come back.

4. Read one release in depth#

Pick a UPC from the list and ask for its tracks, the main artist, and everyone credited on each track, with their role. You select exactly the fields you want, at every level:

Request
query Release($upc: String!) {
  release(upc: $upc) {
    title
    contributors(role: "MainArtist") {
      party { name }
    }
    resources {
      sequence
      title
      isrc
      durationSeconds
      contributors {
        role
        party { name }
      }
    }
  }
}
Variables
{
  "upc": "0196871402293"
}
Response
{
  "data": {
    "release": {
      "title": "Paper Radio",
      "contributors": [{ "party": { "name": "Halfway Ghosts" } }],
      "resources": [
        {
          "sequence": 1,
          "title": "Signal Fire",
          "isrc": "JPTO09404900",
          "durationSeconds": 214,
          "contributors": [
            { "role": "Composer", "party": { "name": "Ada Reyes" } },
            { "role": "Composer", "party": { "name": "Tom Vance" } },
            { "role": "Producer", "party": { "name": "Mika Sato" } }
          ]
        }
      ]
    }
  }
}

Two things to notice:

  • Credits live at two levels. Release.contributors is who the release is billed to; Resource.contributors is who worked on each recording. DDEX keeps them apart, and so does the API.
  • Role names are DDEX's. MainArtist, Composer, Producer — the values the label delivered, verbatim. To narrow a list to one role, pass it as an argument, as the release does with contributors(role: "MainArtist"); the match is case-insensitive.

Add url to a resource, naming the encoding you want. It returns a signed link to the file that expires after five minutes — this is what media_read is for:

Request
query {
  release(upc: "0196871402293") {
    resources(kind: AUDIO) {
      title
      url(encoding: "aac-256")
    }
  }
}

aac-256 is the stream //SCHEMA makes of every track; encodings lists the rest. See Stream media.

Try the same query with a key that lacks media_read: the titles still come back, and each url is null with an error beside it. Authorization in this API is per field.

What you have learned#

  • One endpoint, one POST, one header.
  • The catalog comes from the key; scopes decide what the key can read.
  • You shape the response by choosing fields, at every level of the tree.

Next#