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.
Hint: Log into your Soundslice account, then refresh this page. We’ll tell you whether your account is eligible.
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.
|
embed_status |
Optional |
An integer specifying embed options. For context, see embedding docs.
|
print_status |
Optional |
Whether the slice can be printed.
|
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:
|
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:
|
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:
|
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:
|
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:
|
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, Note |
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:
- Initiate an upload via POST. We’ll give you a temporary URL to PUT the notation to.
- PUT the notation file to that URL.
- 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:
|
HTTP status 403 |
Error. You don’t have permission to edit this slice. |
HTTP status 422 |
Error. Your |
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 |
|
error |
This error string will exist in case of errors. Example:
|
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:
|
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:
|
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.
|
source_data |
Depends |
Extra data, depending on the value of
|
hls_url |
Depends |
The URL for an HLS playlist for this recording, if The value is not required if you provide |
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:
|
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:
|
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:
|
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:
|
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 |
hls_url |
Optional |
The URL for an HLS playlist for this recording, if |
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:
|
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:
|
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:
|
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:
- Initiate an upload via POST. We’ll give you a temporary URL to PUT the media file to.
- 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:
|
HTTP status 403 |
Error. You don’t have permission to edit this recording. |
HTTP status 422 |
Error. This recording’s |
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:
|
HTTP status 422 |
Error. Response is a JSON object containing one key:
|
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 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: |
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 For example, to specify a syncpoint exactly in the middle of the bar — on beat three of a four-beat bar — use If this value isn’t given, it’s assumed to be |
Value 4: Hide playhead |
Optional. Whether to hide the playhead starting at this syncpoint. (See here.) Valid values are |
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:
|
HTTP status 422 |
Error. Response is a JSON object containing one key:
|
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:
|
HTTP status 403 |
Error. You don’t own this folder. |
HTTP status 422 |
Error. Response is a JSON object containing one key:
|
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:
|
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:
|
HTTP status 403 |
Error. You don’t own this folder. |
HTTP status 422 |
Error. Response is a JSON object containing one key:
|
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:
|
HTTP status 422 |
Error. Response is a JSON object containing one key:
|
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.