Kotlin / Android
Kotlin SDK
Integrate Meridian chat completions into your Android app using OkHttp and Kotlin coroutines. Minimal dependencies, maximum control.
Installation
Add the dependency to your module-level build.gradle.kts:
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("com.google.code.gson:gson:2.10.1")
}Alternatively, use OpenAI-Kotlin for a higher-level client with full OpenAI-compatible API coverage.
Quickstart
Create a client, build a chat completion request, and stream the response using Kotlin coroutines.
import kotlinx.coroutines.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
data class ChatMessage(
val role: String,
val content: String
)
data class ChatRequest(
val model: String,
val messages: List<ChatMessage>,
val stream: Boolean = false
)
data class Choice(val message: ChatMessage)
data class ChatResponse(val choices: List<Choice>)
class MeridianClient(
private val apiKey: String,
private val baseUrl: String = "https://api.getnimbus.net/v1"
) {
private val client = OkHttpClient()
private val gson = Gson()
private val jsonMediaType = "application/json".toMediaType()
suspend fun chat(
model: String,
messages: List<ChatMessage>
): ChatResponse = withContext(Dispatchers.IO) {
val body = gson.toJson(ChatRequest(model, messages))
.toRequestBody(jsonMediaType)
val request = Request.Builder()
.url("$baseUrl/chat/completions")
.addHeader("Authorization", "Bearer $apiKey")
.post(body)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw Exception("API error: ${response.code}")
}
gson.fromJson(
response.body?.string(),
ChatResponse::class.java
)
}
}
}
// Usage
fun main() = runBlocking {
val meridian = MeridianClient("sk-your-key-here")
val response = meridian.chat(
model = "meridian-1",
messages = listOf(
ChatMessage("system", "You are a helpful assistant."),
ChatMessage("user", "Explain Kotlin coroutines.")
)
)
println(response.choices.first().message.content)
}Streaming
Set stream = true and parse Server-Sent Events line by line.
suspend fun chatStream(
model: String,
messages: List<ChatMessage>,
onDelta: (String) -> Unit
) = withContext(Dispatchers.IO) {
val body = gson.toJson(
ChatRequest(model, messages, stream = true)
).toRequestBody(jsonMediaType)
val request = Request.Builder()
.url("$baseUrl/chat/completions")
.addHeader("Authorization", "Bearer $apiKey")
.post(body)
.build()
client.newCall(request).execute().use { response ->
val source = response.body?.source() ?: return@withContext
while (!source.exhausted()) {
val line = source.readUtf8Line() ?: continue
if (line.startsWith("data: ") && line != "data: [DONE]") {
val json = line.removePrefix("data: ")
val delta = gson.fromJson(json, DeltaResponse::class.java)
delta.choices.firstOrNull()
?.delta?.content?.let(onDelta)
}
}
}
}
data class DeltaContent(val content: String?)
data class DeltaChoice(val delta: DeltaContent)
data class DeltaResponse(val choices: List<DeltaChoice>)