![]() |
VOOZH | about |
The SoundCloud API provides endpoints for authentication, track upload and playback, social features, and search. This guide covers common integration patterns with code examples. For detailed endpoint specifications, see the API Explorer. If you use an AI coding assistant, see Building with AI for OpenAPI-first prompt templates and example requests.
https://api.soundcloud.comhttps://secure.soundcloud.comAuthorization: OAuth ACCESS_TOKENAll API usage requires a registered application:
client_id and client_secretSoundCloud uses OAuth 2.1 for authentication. PKCE is required for the authorization code exchange.
If migrating from OAuth 2.0, see the differences in the RFC.
| Flow | User Resources Access | Server-side Implementation |
|---|---|---|
| Authorization Code | Yes | Yes |
| Client Credentials | No | Yes |
The Connect with SoundCloud button enables one-click OAuth registration and sign-in. After authorization, the application gains access to the user's account for uploading, playlist creation, and other user-scoped actions.
Construct the authorization URL with the required parameters and redirect the user's browser to it. This step runs on the front-end.
# open in the browser
https://secure.soundcloud.com/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&code_challenge=CODE_CHALLENGE&code_challenge_method=S256&state=STATE
Parameters:
- YOUR_CLIENT_ID: The client ID from application registration.
- YOUR_REDIRECT_URI: The URI from application registration. The user is redirected here after authentication.
- CODE_CHALLENGE: A PKCE code challenge. See What is PKCE? and PKCE generator sandbox.
- STATE: A random string for CSRF protection. Verify this nonce after retrieving the token.
The user is redirected to SoundCloud to log in and approve the authorization request.
After approval, SoundCloud redirects to your redirect_uri with a code query parameter. Exchange this code for an access token:
curl -X POST "https://secure.soundcloud.com/oauth/token" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
--data-urlencode "redirect_uri=YOUR_REDIRECT_URI" \
--data-urlencode "code_verifier=YOUR_PKCE_GENERATED_CODE_VERIFIER" \
--data-urlencode "code=YOUR_CODE"
Parameters:
- YOUR_CLIENT_ID, YOUR_CLIENT_SECRET: From application registration.
- YOUR_PKCE_GENERATED_CODE_VERIFIER: Generated by your application during step 1.
- YOUR_REDIRECT_URI: Must match the URI used in the authorization request exactly.
- YOUR_CODE: The authorization code received from the authorization server.
The response contains access_token, refresh_token, expires_in, and scope. Store these values associated with the user. Use the access_token for subsequent API requests and the refresh_token to renew expired tokens.
curl "https://api.soundcloud.com/me" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
The Client Credentials flow authenticates an application (not a user) to access public resources. Send client_id and client_secret via HTTP Basic authentication to obtain an access token.
curl -X POST "https://secure.soundcloud.com/oauth/token" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic Base64(client_id:client_secret)" \
--data-urlencode "grant_type=client_credentials"
# If your client_id is "my_client_id" and client_secret is "my_client_secret"
# The concatenated string would be "my_client_id:my_client_secret"
# The Base64 encoded string of "my_client_id:my_client_secret" is "bXlfY2xpZW50X2lkOm15X2NsaWVudF9zZWNyZXQ="
For the client_credentials grant type, only HTTP Basic authentication (Authorization: Basic ...) is supported. Sending credentials in the request body is not supported.
The response contains access_token, refresh_token, expires_in, and scope. Store and reuse the token; use refresh_token to renew expired tokens.
Constraints — Client Credentials token rate limits: - 50 tokens per 12 hours per application - 30 tokens per 1 hour per IP address - Reuse tokens across service instances - Implement the refresh token flow to stay within limits
Note: All clients are currently treated as confidential rather than public, meaning a secret is required to obtain a token.
Access tokens expire after approximately 1 hour. Use the refresh_token to obtain a new access token. Each refresh token is single-use.
Note: All clients are currently treated as confidential rather than public, meaning a secret is required to obtain a token.
curl -X POST "https://secure.soundcloud.com/oauth/token" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=YOUR_CLIENT_ID" \
--data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
--data-urlencode "refresh_token=YOUR_TOKEN"
Mobile and desktop applications use the same authorization code flow as web applications. Use a custom protocol scheme for the redirect_uri (e.g., my-app://soundcloud/callback).
For mobile devices, add display=popup to the authorization URL query string to use the mobile-optimized connect screen.
To sign out the user, send the access_token as follows:
curl -X POST "https://secure.soundcloud.com/sign-out" \
-H "Content-Type: application/json" \
-d '{"access_token": "ACCESS_TOKEN"}'
Error responses have the following format: ```
{ "error": "XXXX" } ```
Sign-out error details:
| Response | Status | Description |
|---|---|---|
| bad_request | 400 | body is missing access token |
| unauthorized | 401 | this token is associated with a session that is already invalid |
Every API request requires an Authorization header:
-H "Authorization: OAuth ACCESS_TOKEN"
Requests without this header return 401 Unauthorized. See the Authentication section for supported auth methods.
The /me endpoint returns profile information for the authenticated user.
curl "https://api.soundcloud.com/me" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
The API supports uploading, managing, and sharing tracks. SoundCloud Upload Requirements is the general reference for formats, file preparation, and quality — all of that guidance applies to API uploads as well as to uploads from the SoundCloud website or apps.
Limits: each upload may be up to 4 GB and 24 hours of audio in length (see the help article above).
SoundCloud transcodes your audio into high-quality streaming formats (like AAC), but starting with a lossless file gives listeners the most detailed sound.
Accepted source formats include: AIFF, WAVE, FLAC, OGG, MP2, MP3, AAC, AMR, WMA. After a successful upload the track is queued for encoding; listeners stream transcoded output (for example AAC), not the raw bytes of your uploaded file.
Send a POST request with multipart/form-data to the /tracks endpoint.
curl -X POST "https://api.soundcloud.com/tracks" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-H "Content-Type: multipart/form-data" \
-F "track[title]=YOUR_TITLE" \
-F "track[asset_data]=@PATH_TO_A_FILE"
On success, the track is queued for encoding.
To update track metadata, send a PUT request to the /tracks/:id endpoint with the properties to update.
Track artwork can be updated via the artwork_data parameter. The audio file cannot be updated after upload.
# Multipart request
curl -X PUT "https://api.soundcloud.com/tracks/TRACK_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: multipart/form-data" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-F "track[title]=YOUR_TITLE" \
-F "track[description]=YOUR_DESCRIPTION" \
-F "track[artwork_data]=@PATH_TO_FILE"
# JSON request
curl -X PUT "https://api.soundcloud.com/tracks/TRACK_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/json" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-d '{"track":{"title":"NEW TITLE"}}'
Playlists group tracks for sharing. A track can belong to multiple playlists. Playlists can be public or private.
Create a playlist by sending a POST request to /playlists with playlist metadata and a list of track IDs.
curl -X POST "https://api.soundcloud.com/playlists" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/json" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-d '{"playlist": {"title":"YOUR_TITLE", "description":"YOUR_DESCRIPTION", "sharing":"public", "tracks":[{"id":1},{"id":2},{"id":3}]}}'
Add tracks to an existing playlist by updating the tracks property via PUT.
curl -X PUT "https://api.soundcloud.com/playlists/PLAYLIST_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/json" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-d '{"playlist": {"tracks":[{"id":1}, {"id":2}, {"id":3}]}}'
Retrieve tracks in a playlist with a GET request to /playlists/:id.
curl -X GET "https://api.soundcloud.com/playlists/PLAYLIST_ID?show_tracks=false" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
Tracks and playlists can be played from your application by embedding the SoundCloud widget or using stream URLs with a custom audio player. Playback uses SoundCloud’s transcoded streams (high-quality streaming formats such as AAC), not your original upload file. The Widget API provides programmatic control and event handling.
Use the oEmbed endpoint to retrieve embed code for any track or playlist URL.
See also: Embedded player guide, Widget API.
Custom player streaming requires proper attribution per the Terms of Use and Attribution Guidelines:
To stream with a custom player, retrieve the track resource and use its stream_url property. A GET request to the stream URL returns available transcodings.
Public tracks can be streamed without a user session. Private tracks require an authorized user session and a secret_token.
# request a track you want to stream
curl -X GET "https://api.soundcloud.com/tracks/TRACK_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
# extract stream_url when available from a response
curl -X GET "https://api.soundcloud.com/tracks/TRACK_ID/stream" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
See also: /oembed, HTML5 Widget API.
Not all tracks are available for off-platform streaming. Tracks may be restricted by the creator, paywalled, or geo-blocked. Restricted tracks have no stream_url and their access field is set to blocked. Calling /tracks/:id/streams for a blocked track returns an error.
Track access levels:
- playable — the track is fully streamable
- preview — a preview snippet is available
- blocked — not streamable, only metadata is provided
The access filter parameter can be used when searching or fetching tracks to include only tracks with specific access levels. See the API Explorer for details.
Send a POST request to /tracks/:track_id/comments to create a comment. Include a timestamp parameter (in milliseconds from track start) for a timed comment. Omitting it creates a non-timed comment.
Comments cannot be posted on tracks where the creator has disabled comments.
curl -X POST "https://api.soundcloud.com/tracks/YOUR_TRACK_ID/comments" \
-H "accept: application/json; charset=utf-8" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN" \
-d '{"comment":{"body":"YOUR_COMMENT","timestamp":12345}}'
Retrieve comments for a track:
curl -X GET "https://api.soundcloud.com/tracks/YOUR_TRACK_ID/comments?limit=3&linked_partitioning=true" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
The API supports following users and liking tracks or playlists. Followed users' tracks and reposts appear in the activity feed.
Follow a user via PUT /me/followings/:user_id:
curl -X PUT "https://api.soundcloud.com/me/followings/USER_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
Like a track or playlist via the /likes/ endpoints:
# liking a track
curl -X POST "https://api.soundcloud.com/likes/tracks/TRACK_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
# liking a playlist
curl -X POST "https://api.soundcloud.com/likes/playlists/PLAYLIST_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
Search tracks, users, and playlists using the q parameter, which matches against fields like title, username, and description.
# search for playable tracks
curl -X GET "https://api.soundcloud.com/tracks?q=hello&ids=1,2,3&genres=Pop,House&access=playable&limit=3&linked_partitioning=true" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
Range filters are supported for bpm, duration, and other fields:
curl -X GET "https://api.soundcloud.com/tracks?q=hello&ids=1,2,3&genres=Pop,House&bpm%5Bfrom%5D=120&duration%5Bfrom%5D=30000&access=playable&limit=3&linked_partitioning=true" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
See the API Explorer for all available search fields and filters.
Collection responses return up to 50 items by default (maximum 200). Pass linked_partitioning=true to enable pagination. Paginated responses include a next_href property pointing to the next page. When next_href is absent, there are no more results.
# fetch first 25 user's playlists
curl -X GET "https://api.soundcloud.com/me/playlists?show_tracks=false&linked_partitioning=true&limit=25" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
# response contains 'next_href': "https://api.soundcloud.com/playlists?show_tracks=false&page_size=25&cursor=1234567"
The /resolve endpoint converts a SoundCloud permalink URL into a full API resource representation.
curl -X GET "https://api.soundcloud.com/resolve?url=https://soundcloud.com/PERMALINK" \
-H "accept: */*" \
-H "Authorization: OAuth ACCESS_TOKEN"
The API supports CORS for browser-based JavaScript requests. JSONP is also supported via a callback query parameter.
const response = await fetch("https://api.soundcloud.com/tracks?ids=1,2,3", {
headers: {
"Accept": "application/json; charset=utf-8",
"Authorization": "OAuth ACCESS_TOKEN"
}
});
const tracks = await response.json();
tracks.forEach(track => console.log(track.title));
The API returns standard HTTP status codes with JSON error descriptions.
# try fetching a non-existing user
curl -X GET "https://api.soundcloud.com/users/INVALID_ID" \
-H "accept: application/json; charset=utf-8" \
-H "Authorization: OAuth ACCESS_TOKEN"
# response 404 Error: Not Found
{
"code": 404,
"message": "404 - Not Found",
"link": "https://developers.soundcloud.com/docs/api/explorer/open-api",
"status": "404 - Not Found",
"errors": [
{
"error_message": "404 - Not Found"
}
],
"error": null
}
The request was malformed or missing required parameters. Consult the API Explorer for endpoint requirements.
Authentication failed. Verify the Authorization header is present and contains a valid token.
Public endpoints accept tokens from the Client Credentials flow. User-specific actions require an Authorization Code token. See the Authentication section.
OAuth tokens expire and must be refreshed to avoid 401 errors.
The authenticated user does not have permission to access this resource.
The requested resource does not exist. Verify the URL path and resource ID.
The server cannot produce a response matching the request's Accept header.
One or more parameters failed validation (e.g., wrong data type such as an array where a string was expected).
The request exceeded a rate limit. See the Rate Limits page for details.
An unexpected server error occurred.
The service is temporarily unavailable. Implement retry logic with backoff.
The server did not receive a timely upstream response. The request may still have been processed; verify resource state before retrying.