Code Examples
Kotlin and Android with the CurrencyCore SDK
Use the official Kotlin SDK on Android, keep the key out of source, call convert from coroutines, and handle ClientException.
The official Kotlin SDK is generated from the OpenAPI contract and works on Android and the JVM. It configures bearer auth, returns typed models, and exposes convert, ratesByBase, history, and the analytics methods. Wrap its blocking calls in Dispatchers.IO.
The key belongs in local.properties during development and reaches code through BuildConfig. Add buildFeatures { buildConfig = true } for Android Gradle Plugin 8 and later, where build config generation is off by default. Do not commit local.properties.
// app/build.gradle.kts
import java.util.Properties
val local = Properties().apply {
val file = rootProject.file("local.properties")
if (file.exists()) file.inputStream().use { load(it) }
}
android {
defaultConfig {
minSdk = 26
buildConfigField(
"String",
"CURRENCYCORE_API_KEY",
"\"${local.getProperty("CURRENCYCORE_API_KEY") ?: ""}\"",
)
}
buildFeatures { buildConfig = true }
}
dependencies {
implementation("com.github.CurrencyCore:currencycore-kotlin:0.1.2")
}
import com.currencycore.sdk.CurrencyCore
import com.currencycore.sdk.infrastructure.ClientException
import com.currencycore.sdk.infrastructure.ServerException
import java.math.BigDecimal
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class CurrencyCoreException(
val status: Int,
val code: String,
override val message: String,
) : Exception(message)
class CurrencyRepository(
private val apiKey: String = BuildConfig.CURRENCYCORE_API_KEY,
) {
private val api = CurrencyCore.client(apiKey = apiKey)
suspend fun convert(from: String, to: String, amount: Double) =
withContext(Dispatchers.IO) {
require(apiKey.isNotBlank()) {
"Set CURRENCYCORE_API_KEY in local.properties"
}
try {
api.convert(
from = from,
to = to,
amount = BigDecimal.valueOf(amount),
)
} catch (error: ClientException) {
throw CurrencyCoreException(
error.statusCode,
"client_error",
error.message ?: "Request failed",
)
} catch (error: ServerException) {
throw CurrencyCoreException(
error.statusCode,
"server_error",
error.message ?: "Server error",
)
}
}
}
The SDK returns the API shape, with one entry per target:
{
"from": "USD",
"amount": 250,
"date": "2026-11-10",
"results": [{ "to": "JPY", "result": 38750.0, "rate": 155.0 }]
}
ClientException covers 4xx responses and ServerException covers 5xx. Both expose statusCode. Branch on the status: 400 is input, 401 is auth, 403 is a plan or history window, and 429 is a limit. On a 429, read Retry-After before retrying.
Production notes
- A shipped APK exposes compiled constants, including
BuildConfigfields. Obfuscation raises the effort but does not make the key secret. Use a backend proxy when the key must stay private. - Rates are central-bank reference rates polled hourly, and the underlying fixings are daily. They are reference values, not executable quotes.
- A
403can mean a plan gate or a date outside the Free 30-day history window. - Cache by
dateand base, and retry only429and5xxwith backoff and jitter.
Next steps
- Official SDKs for TypeScript, Python, Dart and Swift
- API reference and error codes
- Retries and backoff for safe retry rules
- All developer guides