Skip to content

Configuration

Defaults

With TYPESAFE_API_KEY set, a no-argument JevClient() is ready to use:

// With TYPESAFE_API_KEY set, the defaults are all you need.
JevClient().use { jev ->
    println(jev.config) // the key is redacted
}

JevClient holds a Ktor HTTP client, so close it when you're done. use { } does that for you.

The configuration builder

val jev =
    JevClient {
        apiKey = System.getenv("MY_TYPESAFE_KEY")      // default: TYPESAFE_API_KEY
        baseUrl = "https://api.typesafe.ai"            // default: TYPESAFE_BASE_URL, then this
        defaultModel = "jev-1.13.0"                    // default: TYPESAFE_DEFAULT_MODEL, then "jev-latest"
        timeout = 15.seconds                           // per HTTP attempt; default 10 s
        retry = RetryPolicy(maxRetries = 4)            // see "Retries & Errors"
        headers["X-Request-Source"] = "support-triage" // sent with every request
    }

Each setting resolves in this order: the explicit value, then the environment variable, then the default. Blank environment variables are ignored.

Setting Environment variable Default
apiKey TYPESAFE_API_KEY none; required
baseUrl TYPESAFE_BASE_URL https://api.typesafe.ai
defaultModel TYPESAFE_DEFAULT_MODEL jev-latest
timeout 10 seconds per HTTP attempt
retry RetryPolicy(), matching the official SDKs; see Retries & Errors
engine a CIO engine created by the client
headers none; extra headers sent with every request

A missing API key throws a JevConfigException that names TYPESAFE_API_KEY. JevConfig.toString() redacts the key, so it's safe to log.

Retry policies

// More patience for a batch job:
JevClient {
    retry =
        RetryPolicy(
            maxRetries = 5,
            initialBackoff = 1.seconds,
            maxBackoff = 20.seconds,
        )
},
// Fail fast in an interactive request path:
JevClient { retry = RetryPolicy.NONE },
// Retry rate limits and overloads, but not other server errors:
JevClient { retry = RetryPolicy(retryStatuses = setOf(429, 529)) },

A custom HTTP engine

To tune connection pooling, TLS, or proxies, pass your own Ktor engine:

// Supply a tuned Ktor engine instead of the default CIO one. The client won't close an engine you pass in.
val jev =
    JevClient {
        engine =
            CIO.create {
                maxConnectionsCount = 64
                endpoint.maxConnectionsPerRoute = 16
                endpoint.connectTimeout = 2_000 // milliseconds
            }
    }

The client doesn't close an engine you pass in, so one engine can be shared by several clients. Close it yourself when you're done with it. timeout still bounds each whole attempt, but the connect and socket timeouts are left to an engine you supply, so settings like endpoint.connectTimeout above take effect.

baseUrl must carry a scheme, and timeout must be at least a millisecond; anything else is a JevConfigException from the builder, with every problem it found listed at once.

Security

  • Keep API keys on the server. Never ship them in a browser or mobile client.
  • The key is sent as Authorization: Bearer ... on every request, and redacted from JevConfig.toString().
  • Every request carries a User-Agent of jev4k/<version>. A headers entry of the same name replaces the built-in one rather than adding a second value, so a gateway that needs its own Authorization can have it.