KarboneConfigKarboneConfig is the immutable, per-client configuration behind every Karbone instance:
| Field | Default | Meaning |
|---|---|---|
baseUrl | — | https://api.carbone.io or an on-premise URL such as http://localhost:4000. Trailing slash optional. |
token | null | Bearer token. null sends no Authorization header. |
apiVersion | null | carbone-version header. null omits it (what on-premise expects); cloud uses KarboneConfig.LATEST_API_VERSION (5). |
connectTimeout | 10 seconds | TCP connect timeout. |
requestTimeout | 60 seconds | Per-request timeout. Carbone’s own synchronous render timeout is 60 s. |
retry | RetryPolicy.None | Retries transport failures only — API errors are never retried. |
json | KarboneConfig.DefaultJson | kotlinx.serialization.json.Json used for request bodies and response parsing. |
userAgent | "karbone/<version>" | User-Agent header sent with every request. |
Karbone.cloud and Karbone.onPremise both go through KarboneConfig.Builder, exposed as a trailing lambda:
val cloud = Karbone.cloud("YOUR_API_KEY") {
requestTimeout = 30.seconds
retry = RetryPolicy.OnTransportError(maxAttempts = 3, backoff = 300.milliseconds)
}
val onPremise = Karbone.onPremise("http://localhost:4000", token = "YOUR_JWT") {
connectTimeout = 5.seconds
}Defaults differ deliberately between the two factories:
Karbone.cloud(apiKey) sets baseUrl to KarboneConfig.CLOUD_BASE_URL and apiVersion to KarboneConfig.LATEST_API_VERSION, so every request carries carbone-version: 5.Karbone.onPremise(baseUrl, token) leaves apiVersion at null: no carbone-version header is sent, matching what self-hosted carbone-ee expects (see On-premise). token itself is optional, since on-premise authentication is disabled by default.Retries (RetryPolicy.OnTransportError) only cover connection resets, timeouts and other I/O failures — never a Carbone API error such as a 4xx or 5xx response, which is always surfaced as the corresponding KarboneError on the first attempt.
KarboneConfig configures headers for the whole client; a single render can add its own through RenderOptions.headers (or the builder’s header(name, value)), for example to relay a token to a downstream service via carbone-egress-header-authorization, without changing the client’s own Authorization:
karbone.renders.render(template, data) {
header("carbone-egress-header-authorization", "Bearer downstream-token")
}Spring Boot’s dependency management pins kotlinx-coroutines (1.10.2 in Spring Boot 4.1) and kotlinx-serialization (1.11.0). Karbone is compiled against exactly those versions, so the artifact resolved by the BOM is the one Karbone was built with.
Why it matters: a library compiled against coroutines 1.11 references runBlockingK, an overload that does not exist in 1.10.2. If the BOM downgrades the runtime, the blocking facade fails with NoSuchMethodError at the first call. This bit the first consumer of Karbone 0.1.2. If you need a newer coroutines line anyway, override the managed version for the whole project:
// build.gradle.kts
extra["kotlin-coroutines.version"] = "1.11.0"Arrow (arrow-core) and kotlin-logging are not managed by Spring Boot; Karbone brings its own versions.
Karbone does not expose its KarboneConfig: the token stays private and the configuration is a construction detail. Two read-only values are available because they are useful in startup logs and health checks:
logger.info { "Carbone at ${karbone.baseUrl} (api version ${karbone.apiVersion ?: "server default"})" }Karbone logs through kotlin-logging under the com.ekino.oss.karbone logger names and stays silent at INFO and above in the normal path. See the dedicated Logging page for backends, levels, what is never logged and configuration examples.