Please correct the errors below.

Soundslice data API

You can use our data API to manage the slices in your account programmatically. Here’s the full documentation.

API keys

To get started, you’ll need an API key.

API keys are only available to paying Soundslice customers — either in the Teacher or Licensing plans.

A Soundslice API key consists of two strings — an application ID and associated password. You can have multiple API keys, in case you’d like to keep separate applications separate.

Client libraries

Want to save time? We provide an open-source Python client library for this API. See the code and documentation on GitHub.

Even if you don’t use Python, you might find it useful to look at our implementation.

API endpoints

This API is REST-based and works over HTTP. For each API call, you’ll need to authenticate with your API key, using HTTP Basic Authentication.

Here’s an example API call, using the open-source curl library on the Unix command line:

curl -X GET -u 'my_app_id:my_password' https://www.soundslice.com/api/v1/slices/abcde/

In our API responses, you should check the HTTP status code to determine success. The content of responses is in JSON format.

Here are all the currently implemented API endpoints:

Create slice

POST /api/v1/slices/

Creates a slice. Note this only creates the metadata for the slice, not the notation.

Use these POST parameters:

name Optional The name of the slice. Limit 255 characters. If not given, we’ll use the name “Untitled” for this slice.
artist Optional The artist/composer of the slice. Limit 255 characters.
status Optional

An integer specifying the slice’s secret URL status.

  • 1 — Secret URL disabled (default value, if not provided)
  • 3 — Secret URL enabled
embed_status Optional

An integer specifying embed options. For context, see embedding docs.

  • 1 — Disabled (default value, if not provided)
  • 2 — Enabled on any domain (option only available for certain accounts)
  • 4 — Enabled on allowlist domains
print_status Optional

Whether the slice can be printed.

  • 1 — Printing is disabled (default)
  • 3 — Printing is allowed
folder_id Optional A string specifying the ID of the folder in which to put this slice, e.g., "123". (Note that folder IDs are not necessarily always integers.) If you don’t specify this, the slice will be placed in the account’s root folder.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing these keys:

  • "scorehash" — The slice’s scorehash. This is a unique identifier with a maximum size of 6 characters.
  • "slug" — The slice’s slug. A slug is a unique identifier with a maximum size of 100 characters. (Some older API methods use this; newer API methods use the scorehash instead.)
  • "url" — The slice’s URL on soundslice.com. Note this URL will return a 404 until the slice has notation.
  • "embed_url" — Only included if the slice has embedding enabled. This is the URL to put in your <iframe>. Note this URL will return a 404 until the slice has notation.
HTTP status 403

Error. You don’t have permission to create this slice.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "errors" — An object mapping field names to lists of error message strings. Example:

{"folder_id": ["This folder ID is invalid."]}

Delete slice

DELETE /api/v1/slices/SCOREHASH/

Deletes the slice with scorehash SCOREHASH, including all its associated data such as recordings.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing these keys:

  • "name" — String. The slice’s name.
  • "artist" — String. The slice’s artist. Might be an empty string, but it will always exist in the JSON.
HTTP status 403

Error. You don’t own this slice, or your account doesn’t have permission to delete it.

List all slices

GET /api/v1/slices/

Retrieves metadata for all slices in your account.

The order of slices in the result is undefined.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON list of objects, with each object containing these keys:

  • "scorehash" — The slice’s scorehash. This is a unique identifier with a maximum size of 6 characters.
  • "slug" — String. The slice’s slug.
  • "name" — String. The slice’s name.
  • "artist" — String. The slice’s artist. Might be an empty string, but it will always exist in the JSON.
  • "status" — Integer. The slice’s view status. (See here.)
  • "embed_status" — Integer. The slice’s embed status. (See here.)
  • "can_print" — Boolean. Whether the slice can be printed.
  • "has_notation" — Boolean. Whether the slice has notation.
  • "show_notation" — Boolean. Whether the slice can show its notation. This is true except when you’ve manually disabled notation for the slice, in the slice manager.
  • "recording_count" — Integer. The number of recordings the slice has.
  • "folder_id" — Integer. The slice’s folder ID. This will be 0 if the slice is at the top level.

Get slice

GET /api/v1/slices/SCOREHASH/

Retrieves metadata for the slice with scorehash SCOREHASH.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing these keys:

  • "scorehash" — The slice’s scorehash. This is a unique identifier with a maximum size of 6 characters.
  • "url" — String. The slice’s URL on soundslice.com. Note this URL will return a 404 if the slice has no notation.
  • "name" — String. The slice’s name.
  • "artist" — String. The slice’s artist. Might be an empty string, but it will always exist in the JSON.
  • "status" — Integer. The slice’s view status. (See here.)
  • "embed_status" — Integer. The slice’s embed status. (See here.)
  • "can_print" — Boolean. Whether the slice can be printed.
  • "has_notation" — Boolean. Whether the slice has notation.
  • "show_notation" — Boolean. Whether the slice can show its notation. This is true except when you’ve manually disabled notation for the slice, in the slice manager.
  • "recording_count" — Integer. The number of recordings the slice has.
  • "folder_id" — Integer. The slice’s folder ID. This will be 0 if the slice is at the top level.
  • "embed_url" — String. The slice’s embed URL. Note this URL will return a 404 if the slice has no notation, and this key will not exist in the JSON if the slice cannot be embedded.
HTTP status 403

Error. You don’t own this slice.

Get slice’s original notation

GET /api/v1/slices/SCOREHASH/notation-file/

Retrieves the original uploaded notation file for the slice with scorehash SCOREHASH. This is a file in one of our supported formats (e.g., MusicXML, GPX, etc.). If you’ve uploaded multiple files, this returns the most recently uploaded file.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing a single key, "url". This is a URL where you can download the original notation file within the next 15 minutes.

Note "url" might be set to the empty string, for slices that don’t have an original notation file.

HTTP status 403

Error. You don’t have permission to edit this slice.

Upload a slice’s notation

This API method is only available by special permission. If you’d like access, contact us and tell us how you intend to use it.

Uploading notation is a multi-step process, because notation files can take a while to process depending on size and current server load:

  1. Initiate an upload via POST. We’ll give you a temporary URL to PUT the notation to.
  2. PUT the notation file to that URL.
  3. We’ll notify you when the upload has processed via making a POST to a callback of your choosing.

Step 1: Initiate upload

POST /api/v1/slices/SCOREHASH/notation-file/

One optional POST parameter is supported:

callback_url Optional A URL that Soundslice will POST to when the upload is processed. Should be a full path, starting with http:// or https://.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing this key:

  • "url" — A one-time, expiring URL that you should PUT the notation to. The URL expires within a few minutes, so make sure to start the PUT right away. (Once you’ve started the PUT, you don’t have to worry about the expiration.)
HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 422

Error. Your callback_url was invalid.

Step 2: PUT the notation file

PUT [put_url]

Next, make a PUT request to the URL you received in step 1. The data of this PUT request should be the raw data of the notation file, in one of our supported formats (MusicXML, Guitar Pro, PowerTab, TuxGuitar).

Do not include HTTP authentication (username and password) with this request.

Important note: This URL will expire after a few minutes. You can always regenerate a new one by doing step 1 again.

Step 3: Handle the callback (optional)

If you specified a callback_url in step 1, we’ll POST to that URL when the notation file is done processing. The POST data will include these keys:

score_slug

The slug of the slice, as a string.

success

'1' if it was successfully processed. '2' if there was an error.

error

This error string will exist in case of errors. Example:

"We couldn't parse the given file."

Export a slice as MusicXML

GET /api/v1/slices/SCOREHASH/musicxml/

Generates MusicXML for the slice with scorehash SCOREHASH.

Note this uses our own MusicXML exporting algorithm based on the slice’s current notation. If you created your slice by uploading a MusicXML file, this will not return that file; you can alternatively get the slice’s original notation.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is the slice’s notation encoded as MusicXML.

HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 404

Error. This slice does not exist, or it has no notation.

Move slice to folder

POST /api/v1/slices/SCOREHASH/move/

Moves the slice (with scorehash SCOREHASH) to a given folder, in either your own account or an organization you belong to.

Use these POST parameters:

folder_id Required The ID of the new folder. Use folder_id 0 (zero) to move the slice to your account’s root folder.
user_id Optional The ID of the user account to move this slice into. This will only work for the ID of an organization you belong to. If not provided, this value will default to the user you’re accessing the API with.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing one key:

  • "id" — The ID of the folder, or 0 (zero) for the root folder.
HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message. This will happen if you specify an invalid folder_id.

Duplicate slice

POST /api/v1/slices/SCOREHASH/duplicate/

Duplicates the slice with the scorehash SCOREHASH, which must live within your account. The newly created slice will live in the top level of your slice manager.

Here’s what’s duplicated:

  • Title and metadata (except for creation date)
  • Notation data
  • All recordings
  • All syncpoints

Slice version history is not duplicated.

Do not send any POST parameters with this request.

You’ll get an immediate response with the newly created slice’s information. Please note that the notation, recordings and syncpoints might not have been yet copied at that point; it could take a few seconds, depending on the current load of our message queue.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing the same keys as documented in the create slice endpoint.

HTTP status 403

Error. You don’t have permission to duplicate this slice.

HTTP status 422

Error. Your account doesn’t have the ability to duplicate slices.

Create recording

POST /api/v1/slices/SCOREHASH/recordings/

Creates a recording in the slice with scorehash SCOREHASH.

Use these POST parameters:

name Optional The name of the recording. Limit 100 characters. If not given, this will be “Audio” or “Video”, depending on the type of recording.
source Required

An integer specifying the type of recording.

  • 2 — MP3 uploaded to Soundslice
  • 4 — Video uploaded to Soundslice
  • 3 — Video URL
  • 8 — MP3 URL
  • 1 — YouTube video
  • 6 — Vimeo video (only allowed if your Soundslice account has been linked with Vimeo)
  • 7 — Wistia video (only allowed if your Soundslice account has been linked with Wistia)
source_data Depends

Extra data, depending on the value of source.

  • If source is 1 — The URL or ID of the YouTube video. Required.
  • If source is 3 — The URL of the video. Either this or hls_url is required. (You can also provide both.)
  • If source is 6 — The ID of the Vimeo video. Required.
  • If source is 7 — The ID of the Wistia video. Required.
  • If source is 8 — The URL of the MP3. Required.
hls_url Depends

The URL for an HLS playlist for this recording, if source is 3.

The value is not required if you provide source_data. You can provide both hls_url and source_data; in that case, our player will use the hls_url for users whose browsers support HLS and source_data otherwise.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing one key:

  • "id" — The ID of the newly created recording.
HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "errors" — An object mapping field names to lists of error message strings. Example:

{"name": ["This field is required."],
"source": ["This field is required."]}

If your recording’s source is 2 or 4 (audio/video uploaded to Soundslice), you’ll need to upload the audio/video in a separate step.

Get slice’s recordings

GET /api/v1/slices/SCOREHASH/recordings/

Gets data about all recordings in the slice with scorehash SCOREHASH.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON array, in which each element has these keys:

  • "id" — The recording’s ID.
  • "name" — The recording’s name.
  • "source" — The recording’s source (see above for details).
  • "source_data" — The recording’s source_data (see above for details).
  • "hls_url" — The recording’s HLS URL, or an empty string.
  • "cropped_duration" — The recording’s duration, in seconds, taking cropping into account. (For example, if the raw recording is 60 seconds long but you’ve cropped it to remove the first 10 seconds, cropped_duration will be 50.) This will be set to null for recordings that don’t have a duration, such as recordings that are still being processed.
  • "syncpoint_count" — The recording’s number of syncpoints.
  • "status" — The recording’s status. The possible values are:
    • waiting — waiting for media to be uploaded
    • processing — processing uploaded media
    • ready — ready
    • error — encountered processing error
HTTP status 403

Error. You don’t have permission to edit this slice.

Reorder slice’s recordings

POST /api/v1/slices/SCOREHASH/recordings/order/

Sets the order of the recordings in the slice with scorehash SCOREHASH.

Use these POST parameters:

order Required A string of recording IDs separated by commas, in your requested order, e.g. "123,124,121". The first recording ID is the top-most recording in the Soundslice UI, and so forth. The last recording ID is the default. Every recording in the slice must be included in this data.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is an empty JSON object.

HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message. This will happen if you don’t specify order or if your order is invalid.

{"error": ["Missing recording IDs."]}

Change recording

POST /api/v1/recordings/RECORDING_ID/

Changes data for the recording with ID RECORDING_ID.

Use these POST parameters. All are optional; if you don’t want to change a particular value, simply don’t send its key with the request.

name Optional The name of the recording. Limit 100 characters.
source_data Optional

Extra data, depending on the value of source. (See above for details.) Only available for video URLs (source=3) and audio URLs (source=8).

hls_url Optional

The URL for an HLS playlist for this recording, if source is 3.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing these keys:

  • "id" — The recording’s ID.
  • "name" — The recording’s name.
  • "source_data" — The recording’s source_data.
  • "hls_url" — The recording’s HLS URL.
HTTP status 403

Error. You don’t have permission to edit this slice.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "errors" — An object mapping field names to lists of error message strings. Example:

{"hls_url": ["Enter a valid URL."]}

Delete recording

DELETE /api/v1/recordings/RECORDING_ID/

Deletes the recording with the given RECORDING_ID, including all its associated data such as syncpoints and uploaded audio.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing one key:

  • "name" — String. The recording’s name.
HTTP status 403

Error. You don’t have permission to edit this recording.

Upload a recording’s audio/video

This applies to recordings with a source of either 2 (MP3 uploaded to Soundslice) or 4 (video uploaded to Soundslice).

Uploading audio/video is a multi-step process:

  1. Initiate an upload via POST. We’ll give you a temporary URL to PUT the media file to.
  2. PUT the media file to that URL.

Step 1: Initiate the upload

POST /api/v1/recordings/RECORDING_ID/media/

Make sure to replace RECORDING_ID with the recording ID.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing this key:

  • "url" — A one-time, expiring URL that you should PUT the media file to. The URL expires within a few minutes, so make sure to start the PUT right away. (Once you’ve started the PUT, you don’t have to worry about the expiration.)
HTTP status 403

Error. You don’t have permission to edit this recording.

HTTP status 422

Error. This recording’s source isn’t 2 or 4.

Step 2: PUT the media file

PUT [put_url]

Next, make a PUT request to the URL you received in step 1. The data of this PUT request should be the raw data of the media file (an MP3 or a video file). Do not include HTTP authentication (username and password) with this request. Also do not include a Content-Type header with this request (note sometimes HTTP libraries include this header automatically, so you’ll want to override that behavior if necessary).

Important note: This URL will expire after a few minutes. You can always regenerate a new one by doing step 1 again.

Get recording’s syncpoints

GET /api/v1/recordings/RECORDING_ID/syncpoints/

Retrieves the syncpoints for the recording with ID RECORDING_ID.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON list representing the syncpoints. See Syncpoint data format below.

HTTP status 403

Error. You don’t have permission to read this recording.

Set recording’s syncpoints

POST /api/v1/recordings/RECORDING_ID/syncpoints/

Sets the syncpoints for the recording with ID RECORDING_ID.

Use these POST parameters:

syncpoints Required The syncpoints, as a string in JSON format. See Syncpoint data format below.
crop_start Optional Number of seconds into the recording to start cropping (a float). For example, if this is 12, then the recording will begin playback at 12 seconds, and seconds 0-12 will be inaccessible.
crop_end Optional Number of seconds into the recording to end cropping (a float). For example, if this is 60, then the recording will end playback at the timecode 60 seconds, and any audio after timecode 60 seconds will be inaccessible. Note this is relative to the absolute recording, so crop_start has no effect on crop_end.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing these keys:

  • "id" — The recording ID, as an integer.
HTTP status 422

Error. Response is a JSON object containing one key:

  • "errors" — An object mapping field names to lists of error message strings. Example:

{"syncpoints": ["Invalid JSON"]}

Syncpoint data format

Syncpoints provide the mapping between notation and an audio/video recording. In Soundslice, syncpoints are stored as a simple JSON array. Example:

[[0, 0], [1, 0.57], [1, 0.8, 240], [2, 1.3]]

Each element in the array represents one syncpoint. A syncpoint is an array of two or three values:

Value 1: Bar

Required. The zero-based bar number in the slice, as an integer.

For example, the first bar in the slice will always be 0 — regardless of how it’s actually labeled in the visual notation.

If the slice has repeats and/or jumps, this syncpoint bar value corresponds to the bar number in absolute terms — as if the notation were rewritten to expand all repeats and jumps. For example, in a two-bar slice that has a repeat line at the end, we’d consider that to have four bars for the purposes of syncpoints: 0, 1, 2 and 3.

Value 2: Time

Required. Timecode in the audio, in seconds, as a float.

Value 3: Percentage into the bar

Optional. Distance into the bar.

This lets you have “inner-bar syncpoints,” in cases where a performance is particularly expressive and does not maintain consistent rhythm within a particular bar.

The value is a number (integer or float) between 0 and 480, where 0 is the start of the bar and 480 is the end of the bar.

For example, to specify a syncpoint exactly in the middle of the bar — on beat three of a four-beat bar — use 240 (50% of 480).

If this value isn’t given, it’s assumed to be 0 (the start of the bar, aka the downbeat).

Value 4: Hide playhead

Optional. Whether to hide the playhead starting at this syncpoint. (See here.)

Valid values are 1 (hide playhead) and 0 (don’t hide playhead; default).

The first syncpoint must represent the start of the very first bar. But after that, you can skip bars as you see fit. The Soundslice player will extrapolate syncpoints evenly if they’re not defined for a given bar.

For example, in a piece that lasts 12 bars, starts at timecode 0.0 seconds and was recorded with a metronome at 120 bpm (2 seconds per bar, assuming 4/4 time), you can simply create the first and last syncpoints:

[[0, 0], [12, 24.0]]

Note in this example that we define a syncpoint for bar 13 (index 12), even though the music only has 12 bars — because the syncpoint maps to the end of the performance.

Create folder

POST /api/v1/folders/

Creates a folder within your account’s slice manager.

Use these POST parameters:

name Required The name of the folder.
parent_id Optional Integer. The folder’s parent ID. Use this if you want to nest a folder within another one.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing one key:

  • "id" — The ID of the newly created folder.
HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message. This will happen if you don’t specify a name or if your parent_id is invalid.

Rename folder

POST /api/v1/folders/FOLDER_ID/

Renames the given folder within your account’s slice manager.

Use this POST parameter:

name Required The new name.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 201

Success. Response is a JSON object containing one key:

  • "id" — The ID of the folder.
HTTP status 403

Error. You don’t own this folder.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message.

Get folder contents

GET /api/v1/folders/FOLDER_ID/

Gets the slices and subfolders within the given folder.

The order of the slices and subfolders is undefined.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing these keys:

  • "name" — The requested folder’s name.
  • "subfolders" — An array of all folders directly within this folder. Each has the following keys:
    • "id" — The subfolder’s ID.
    • "name" — The subfolder’s name.
  • "slices" — An array of all slices directly within this folder. Each has the following keys:
    • "scorehash" — The slice’s scorehash. This is a unique identifier with a maximum size of 6 characters.
    • "name" — The slice’s name.
    • "artist" — The slice’s artist. Might be an empty string, but it will always exist in the JSON.
    • "url" — The slice’s URL on soundslice.com. Note this URL will return a 404 until the slice has notation.
HTTP status 403

Error. You don’t own this folder.

Delete folder

DELETE /api/v1/folders/FOLDER_ID/

Deletes the given folder within your account’s slice manager.

The folder must be empty. It can’t contain any slices or other folders.

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON object containing one key:

  • "parent_id" — The ID of the deleted folder’s parent folder, or null if the deleted folder was in the root.
HTTP status 403

Error. You don’t own this folder.

HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message. This will happen if try to delete a non-empty folder.

List folders

GET /api/v1/folders/

Lists all folders within your account’s slice manager.

By default, this lists only the top-level folders. To list subfolders within a given folder, use the GET parameter parent_id:

GET /api/folders/?parent_id=123

To parse the response, check the HTTP status code. Here are the possible responses:

HTTP status 200

Success. Response is a JSON list of objects, with each object containing these keys:

  • "id" — String. The ID of the folder. This is not necessarily a number.
  • "name" — String. The name of the folder.
HTTP status 422

Error. Response is a JSON object containing one key:

  • "error" — A string with an error message.

Changelog

2023-07-05 — Added folder_id to the get slice and list all slices endpoints.

2022-08-12 — Added MusicXML export endpoint.

2022-05-24 — Added get folder contents endpoint.

2021-07-30 — Added client libraries section.

2021-07-16 — Changed get slice’s notation endpoint and put slice’s notation endpoint to use scorehash instead of slug. With this change, all our API methods consistently use scorehashes instead of slugs. Old API URLs (using /scores/ instead of /slices/) will continue to work for backwards compatibility.

2021-04-13 — Added reorder slice’s recordings endpoint.

2021-01-13 — Changed get slice’s recordings endpoint to use scorehash instead of slug. The old URL still works for backwards compatibility, but new code should use scorehashes instead.

2020-06-23 — Added rename folder endpoint.

2020-06-23 — Added list folders endpoint.

2019-11-18 — Added status to get recordings endpoint.

2019-10-09 — Added scorehash to list slices endpoint.

2019-09-05 — Changed create recording endpoint not to require a name parameter. It will now fall back to an appropriate default value.

2019-08-20 — Added duplicate slice endpoint.