Skip to main content
The Rocksky SDKs are native AT Protocol clients: they read from the public AppView and write app.rocksky.* records straight to the user’s PDS (scrobbles, likes, follows, shouts, now-playing). They are not thin HTTP wrappers. Two implementations share one behaviour:
  • Shared Rust core — Python, Ruby, Kotlin, Clojure, and the BEAM trio (Erlang/Elixir/Gleam) are thin bindings over the same Rust engine (rocksky-sdk), so auth, record writing, dedup, and the identity hashes are identical everywhere.
  • Native ecosystem — Go is built on indigo, TypeScript on atcute, and Rust is the rocksky-sdk crate itself (on jacquard).

TypeScript

@rocksky/sdk — built on atcute

Python

rocksky — native core bindings

Rust

rocksky-sdk crate — jacquard

Go

sdk/go/rocksky — built on indigo

Ruby

rocksky gem — native core (fiddle)

Kotlin

app.rocksky:rocksky-kotlin — UniFFI

Elixir

rocksky_ex — over the rocksky_erl NIF

Erlang

rocksky_erl — Rustler NIF

Clojure

app.rocksky/sdk — Panama FFM

Gleam

rocksky — over the rocksky_erl NIF

Common surface

Every SDK exposes the same three things:
  • Reads — a client over the public AppView (https://api.rocksky.app, overridable) covering the full app.rocksky.* read catalog: globalStats, topTracks, topArtists, profile, scrobbles, songs, albums, artists, search, catalog/loved/follow queries, plus a universal get(nsid, params) escape hatch that calls any read query by nsid. Charts take a typed DateInterval (all-time, last N days/weeks/months/years, or a custom range), and matchSong resolves a bare title + artist into full canonical metadata. Each read client also accepts an optional bearer access token for auth-gated queries.
  • Writes — an Agent that logs in with an app password, resolves the account’s PDS, and writes records: scrobble, scrobble_match (match-then-write from a title/artist input object, with optional album override, mbId/isrc match anchors, and a scrobbled-at timestamp), createSong / createAlbum / createArtist, like, follow, shout, now-playing.
  • Identity hashessongHash / albumHash / artistHash (lowercase-hex SHA-256), byte-for-byte identical across every SDK and the server.

Duplicate prevention & real-time sync

The Rust, Go, and TypeScript SDKs (and the native-core bindings) ship an optional local dedup index keyed by the identity hashes: syncRepo() backfills it from the repo CAR (com.atproto.sync.getRepo), and hydrateFromJetstream() keeps it live off the Bluesky Jetstream firehose. With an index attached, write verbs skip records that already exist and never duplicate a same-second scrobble.

Choosing an SDK