# soundcloud-api-ts v1.4.3 > A TypeScript client for the SoundCloud API. Zero dependencies, native fetch, full OAuth 2.0 + PKCE support. ## Installation npm install soundcloud-api-ts ## Quick Start ```ts import { SoundCloudClient } from 'soundcloud-api-ts'; const sc = new SoundCloudClient({ clientId: 'YOUR_CLIENT_ID', clientSecret: 'YOUR_CLIENT_SECRET', redirectUri: 'https://example.com/callback', // optional, needed for user auth }); // Get a client credentials token const token = await sc.auth.getClientToken(); sc.setToken(token.access_token); // Fetch a track const track = await sc.tracks.getTrack(123456); console.log(track.title); ``` ## API Reference All methods accept an optional trailing `{ token?: string }` parameter to override the stored token. Paginated responses return `SoundCloudPaginatedResponse` with `collection: T[]` and `next_href?: string`. ### Auth (sc.auth) getAuthorizationUrl(options?: { state?: string; codeChallenge?: string }): string getClientToken(): Promise getUserToken(code: string, codeVerifier?: string): Promise refreshUserToken(refreshToken: string): Promise signOut(accessToken: string): Promise ### PKCE Helpers (standalone exports) generateCodeVerifier(): string generateCodeChallenge(verifier: string): Promise ### Tracks (sc.tracks) getTrack(trackId: string | number): Promise getStreams(trackId: string | number): Promise getComments(trackId: string | number, limit?: number): Promise> createComment(trackId: string | number, body: string, timestamp?: number): Promise getLikes(trackId: string | number, limit?: number): Promise> getReposts(trackId: string | number, limit?: number): Promise> getRelated(trackId: string | number, limit?: number): Promise update(trackId: string | number, params: UpdateTrackParams): Promise delete(trackId: string | number): Promise ### Users (sc.users) getUser(userId: string | number): Promise getFollowers(userId: string | number, limit?: number): Promise> getFollowings(userId: string | number, limit?: number): Promise> getTracks(userId: string | number, limit?: number): Promise> getPlaylists(userId: string | number, limit?: number): Promise> getLikesTracks(userId: string | number, limit?: number, cursor?: string): Promise> getLikesPlaylists(userId: string | number, limit?: number): Promise> getWebProfiles(userId: string | number): Promise ### Playlists (sc.playlists) getPlaylist(playlistId: string | number): Promise getTracks(playlistId: string | number, limit?: number, offset?: number): Promise> getReposts(playlistId: string | number, limit?: number): Promise> create(params: CreatePlaylistParams): Promise update(playlistId: string | number, params: UpdatePlaylistParams): Promise delete(playlistId: string | number): Promise ### Search (sc.search) tracks(query: string, pageNumber?: number): Promise> users(query: string, pageNumber?: number): Promise> playlists(query: string, pageNumber?: number): Promise> ### Me — Authenticated User (sc.me) getMe(): Promise getActivities(limit?: number): Promise getActivitiesOwn(limit?: number): Promise getActivitiesTracks(limit?: number): Promise getLikesTracks(limit?: number): Promise> getLikesPlaylists(limit?: number): Promise> getFollowings(limit?: number): Promise> getFollowingsTracks(limit?: number): Promise> getFollowers(limit?: number): Promise> getTracks(limit?: number): Promise> getPlaylists(limit?: number): Promise> follow(userUrn: string | number): Promise unfollow(userUrn: string | number): Promise ### Likes (sc.likes) likeTrack(trackId: string | number): Promise unlikeTrack(trackId: string | number): Promise likePlaylist(playlistId: string | number): Promise unlikePlaylist(playlistId: string | number): Promise ### Reposts (sc.reposts) repostTrack(trackId: string | number): Promise unrepostTrack(trackId: string | number): Promise repostPlaylist(playlistId: string | number): Promise unrepostPlaylist(playlistId: string | number): Promise ### Resolve (sc.resolve) resolveUrl(url: string): Promise ### Pagination (instance methods) sc.paginate(firstPage: () => Promise>): AsyncGenerator sc.paginateItems(firstPage: () => Promise>): AsyncGenerator sc.fetchAll(firstPage: () => Promise>, options?: { maxItems?: number }): Promise ### Client Methods sc.setToken(accessToken: string, refreshToken?: string): void sc.clearToken(): void sc.accessToken: string | undefined sc.refreshToken: string | undefined ## Common Patterns ### Client Credentials Flow (server-to-server) ```ts const sc = new SoundCloudClient({ clientId: '...', clientSecret: '...' }); const token = await sc.auth.getClientToken(); sc.setToken(token.access_token); ``` ### User Authorization Flow (with PKCE) ```ts import { SoundCloudClient, generateCodeVerifier, generateCodeChallenge } from 'soundcloud-api-ts'; const sc = new SoundCloudClient({ clientId: '...', clientSecret: '...', redirectUri: 'https://...' }); const verifier = generateCodeVerifier(); const challenge = await generateCodeChallenge(verifier); const authUrl = sc.auth.getAuthorizationUrl({ state: 'random', codeChallenge: challenge }); // redirect user to authUrl, get code from callback const token = await sc.auth.getUserToken(code, verifier); sc.setToken(token.access_token, token.refresh_token); ``` ### Pagination ```ts // Iterate individual items across all pages for await (const track of sc.paginateItems(() => sc.search.tracks('lofi'))) { console.log(track.title); } // Collect all into an array (with optional limit) const all = await sc.fetchAll(() => sc.search.tracks('lofi'), { maxItems: 100 }); ``` ### Error Handling ```ts import { SoundCloudError } from 'soundcloud-api-ts'; try { await sc.tracks.getTrack(999); } catch (err) { if (err instanceof SoundCloudError) { if (err.isNotFound) console.log('Not found'); if (err.isRateLimited) console.log('Rate limited'); if (err.isUnauthorized) console.log('Bad token'); console.log(err.status, err.message); } } ``` ### Auto Token Refresh ```ts const sc = new SoundCloudClient({ clientId: '...', clientSecret: '...', onTokenRefresh: async (client) => { const newToken = await client.auth.refreshUserToken(client.refreshToken!); client.setToken(newToken.access_token, newToken.refresh_token); return newToken; }, }); ``` ## Full Documentation https://twin-paws.github.io/soundcloud-api-ts/