
Compiles AT Protocol lexicons into typed classes, generates API interfaces and HTTP (Ktor) implementations, and supplies OAuth and Jetstream bindings plus a Gradle plugin for schema generation.
The Ozone project for the AT Protocol consists of several components:
O3 exists at all levels in the ATmosphere.
No relation to the moderation tools also named Ozone.
Documentation is available at ozone.christian.sh.
Warning
🚧 🚧 🚧 Everything in here is very much a work-in-progress! The upstream schemas are still subject to breaking changes and may break at any moment if used in production code. Use at your own risk!
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:bluesky:0.3.3")
}In Xcode, select File > Add Packages and enter https://github.com/christiandeange/BlueskyAPI
Documentation is available at ozone.christian.sh in the sh.christian.ozone.oauth package.
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:oauth:0.3.3")
}Documentation is available at ozone.christian.sh in the sh.christian.ozone.jetstream package.
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:jetstream:0.3.3")
}In addition to shipping the lexicons that define the official Bluesky API, this project also includes a Gradle Plugin that allows you to bring your own lexicon definitions and generate any set of AT Protocol bindings from them.
// build.gradle[.kts]
plugins {
id("sh.christian.ozone.generator") version "0.3.3"
}
dependencies {
// This is where you have your schema files stored in your project.
lexicons(fileTree("lexicons") { include("**/*.json") })
// You can also depend directly on the published Bluesky lexicons instead.
lexicons("sh.christian.ozone:lexicons:2026.04.21")
}
lexicons {
// Determines the package name of generated supporting methods. Defaults to "sh.christian.ozone".
namespace.set("com.example.myapp")
// Configuration for how to handle unknown types and known values.
defaults {
// Determines whether to generate classes to encapsulate unknown types for union references. Defaults to false.
generateUnknownsForSealedTypes.set(true)
// Determines whether to generate classes to encapsulate unknown values for strings. Defaults to false.
generateUnknownsForEnums.set(true)
// Defines what type to use when the protocol has binary data inputs or outputs. Defaults to ByteArray.
binaryDataType.set(BinaryDataType.ByteArray)
}
// Generates an additional interface for the target schemas.
// This method can be called more than once to generate multiple API interfaces.
generateApi("BlueskyApi") {
// Determines the package name of the generated API. Defaults to "sh.christian.ozone".
packageName.set("com.example.myapp")
// Generates an additional class that implements this interface by sending corresponding
// XRPC requests to a provided host conforming to the AT Protocol.
// Inherits the same package name as the generated interface.
// NOTE: Responses are still read entirely into memory regardless of the binaryDataType
// specified in the default configuration. Streaming response types are unsupported
// at this time.
withKtorImplementation("XrpcBlueskyApi")
// Determines the return type for each generated API method. Defaults to Raw.
// - Raw: the raw data type
// - Result: Result<T>
// - Response: AtpResponse<T>
returnType.set(ApiReturnType.Result)
// Determines whether the generated methods should be marked as suspend functions.
// When generating a Ktor implementation as well, execution will block the current thread
// for non-suspending methods. Defaults to true.
suspending.set(true)
}
// File path where Kotlin source files will be written to. Defaults to "<project-dir>/build/generated/lexicons".
outputDirectory.set(project.layout.buildDirectory.dir("out"))
}The Ozone project for the AT Protocol consists of several components:
O3 exists at all levels in the ATmosphere.
No relation to the moderation tools also named Ozone.
Documentation is available at ozone.christian.sh.
Warning
🚧 🚧 🚧 Everything in here is very much a work-in-progress! The upstream schemas are still subject to breaking changes and may break at any moment if used in production code. Use at your own risk!
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:bluesky:0.3.3")
}In Xcode, select File > Add Packages and enter https://github.com/christiandeange/BlueskyAPI
Documentation is available at ozone.christian.sh in the sh.christian.ozone.oauth package.
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:oauth:0.3.3")
}Documentation is available at ozone.christian.sh in the sh.christian.ozone.jetstream package.
// build.gradle[.kts]
dependencies {
api("sh.christian.ozone:jetstream:0.3.3")
}In addition to shipping the lexicons that define the official Bluesky API, this project also includes a Gradle Plugin that allows you to bring your own lexicon definitions and generate any set of AT Protocol bindings from them.
// build.gradle[.kts]
plugins {
id("sh.christian.ozone.generator") version "0.3.3"
}
dependencies {
// This is where you have your schema files stored in your project.
lexicons(fileTree("lexicons") { include("**/*.json") })
// You can also depend directly on the published Bluesky lexicons instead.
lexicons("sh.christian.ozone:lexicons:2026.04.21")
}
lexicons {
// Determines the package name of generated supporting methods. Defaults to "sh.christian.ozone".
namespace.set("com.example.myapp")
// Configuration for how to handle unknown types and known values.
defaults {
// Determines whether to generate classes to encapsulate unknown types for union references. Defaults to false.
generateUnknownsForSealedTypes.set(true)
// Determines whether to generate classes to encapsulate unknown values for strings. Defaults to false.
generateUnknownsForEnums.set(true)
// Defines what type to use when the protocol has binary data inputs or outputs. Defaults to ByteArray.
binaryDataType.set(BinaryDataType.ByteArray)
}
// Generates an additional interface for the target schemas.
// This method can be called more than once to generate multiple API interfaces.
generateApi("BlueskyApi") {
// Determines the package name of the generated API. Defaults to "sh.christian.ozone".
packageName.set("com.example.myapp")
// Generates an additional class that implements this interface by sending corresponding
// XRPC requests to a provided host conforming to the AT Protocol.
// Inherits the same package name as the generated interface.
// NOTE: Responses are still read entirely into memory regardless of the binaryDataType
// specified in the default configuration. Streaming response types are unsupported
// at this time.
withKtorImplementation("XrpcBlueskyApi")
// Determines the return type for each generated API method. Defaults to Raw.
// - Raw: the raw data type
// - Result: Result<T>
// - Response: AtpResponse<T>
returnType.set(ApiReturnType.Result)
// Determines whether the generated methods should be marked as suspend functions.
// When generating a Ktor implementation as well, execution will block the current thread
// for non-suspending methods. Defaults to true.
suspending.set(true)
}
// File path where Kotlin source files will be written to. Defaults to "<project-dir>/build/generated/lexicons".
outputDirectory.set(project.layout.buildDirectory.dir("out"))
}