Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.rocksky.app/llms.txt

Use this file to discover all available pages before exploring further.

A Kotlin-first client built on Ktor + kotlinx.serialization.
  • Suspending functions, default parameters, builder DSL, AutoCloseable
  • Every endpoint returns a @Serializable data class
  • Every model field is nullable, unknown JSON keys are ignored
  • 4xx / 5xx responses become typed exceptions
  • JVM 17+; bring your own Ktor engine (CIO is the default)

Install

dependencies {
    implementation("app.rocksky:rocksky-kotlin:0.2.0")
}
Until artifacts land in Maven Central, build locally with ./gradlew :rocksky:publishToMavenLocal and use mavenLocal().

Quick start

import app.rocksky.RockskyClient
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    RockskyClient().use { client ->
        val profile = client.actor.getProfile(did = "did:plc:example")
        println("${profile.handle}${profile.displayName}")

        val top = client.charts.topTracks(limit = 10)
        top.forEach { println("${it.title} by ${it.artist}") }
    }
}

Three styles for create methods

Heavier write endpoints (scrobble.create, song.create, playlist.create, shout.create, apiKey.create) come in three flavors — pick whichever reads best:
// 1. Named arguments (default)
client.scrobble.create(
    title = "Idioteque",
    artist = "Radiohead",
    album = "Kid A",
    duration = 369,
)

// 2. Kotlin DSL
client.scrobble.create {
    title = "Idioteque"
    artist = "Radiohead"
    album = "Kid A"
    duration = 369
}

// 3. Fluent builder (Java-friendly)
client.scrobble.builder()
    .title("Idioteque")
    .artist("Radiohead")
    .album("Kid A")
    .duration(369L)
    .send()
Required fields are validated on send() — calling without them throws IllegalStateException before any HTTP call.

Authenticated calls

val client = RockskyClient {
    token = System.getenv("ROCKSKY_TOKEN")
    userAgent = "my-app/1.0"
}
Swap tokens at runtime: client.setToken("…").

Surface

ResourceMethods (highlights)
client.actorgetProfile, getAlbums, getArtists, getSongs, getScrobbles, getLovedSongs, getPlaylists, getNeighbours, getCompatibility
client.albumget, list, getTracks
client.apiKeylist, create, update, remove
client.artistget, list, getAlbums, getTracks, getListeners, getRecentListeners
client.chartstopTracks, topArtists, scrobblesChart
client.feedget, getGenerator, listGenerators, search, stories, recommendations, artistRecommendations, albumRecommendations
client.graphfollow, unfollow, getFollowers, getFollows, getKnownFollowers
client.likelikeSong, dislikeSong, likeShout, dislikeShout
client.playerplay, pause, next, previous, seek, playFile, playDirectory, currentlyPlaying, queue, addItemsToQueue
client.playlistget, list, create, remove, start, insertFiles, insertDirectory
client.scrobbleget, list, create
client.shoutcreate, reply, remove, report, forProfile, forAlbum, forArtist, forTrack, replies
client.songget, list, match, create, getRecentListeners

Errors

import app.rocksky.AuthenticationException
import app.rocksky.NotFoundException
import app.rocksky.RateLimitException
import app.rocksky.ApiException

try {
    client.scrobble.create(title = "…", artist = "…", album = "…")
} catch (e: AuthenticationException) {
    // 401 — refresh token
} catch (e: RateLimitException) {
    // 429 — back off
} catch (e: NotFoundException) {
    // 404
} catch (e: ApiException) {
    // e.statusCode, e.error, e.serverMessage, e.body
}
Network errors surface as TransportException. Every exception extends RockskyException.

Configuration

val client = RockskyClient {
    baseUrl       = "https://api.rocksky.app"  // default
    token         = "…"                         // optional bearer
    userAgent     = "my-app/1.0"
    timeoutMillis = 30_000

    // engine = OkHttp.create()
    // httpClient = myExistingKtorClient
    configureClient { /* install logging, custom retry, … */ }
}

Types

Public model types are derived from the Rocksky lexicons and live in app.rocksky.generated. The app.rocksky.Models typealiases re-export them under their historical names; Profile, ApiKey, and FollowList extend with SDK-specific fields. Regenerate with bun run lexgen:types at the repo root.

License

MIT © Tsiry Sandratraina. Source: sdk/kotlin.