Ktor 1.5.4 Help

Setting up a client

Ktor includes a multiplatform asynchronous HTTP client, which allows you to make requests and handle responses, extend its functionality with features, such as authentication, JSON serialization, and so on. In this topic, we'll take an overview of the client - from setting it up to making requests and installing features.

Add dependencies

To use the Ktor HTTP client in your project, you need to add at least two dependencies: a client dependency and an engine dependency. If you want to extend the client functionality with specific features, you also need to add the appropriate dependencies.

Client dependency

The main client functionality is available in the ktor-client-core artifact. Depending on your build system, you can add it in the following way:

implementation "io.ktor:ktor-client-core:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-client-core</artifactId> <version>${ktor_version}</version> </dependency>

Engine dependency

An engine is responsible for processing network requests. There are different client engines available for various platforms, such as Apache, CIO, Android, iOS, and so on. For example, you can add a CIO engine dependency as follows:

implementation "io.ktor:ktor-client-cio:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-client-cio</artifactId> <version>${ktor_version}</version> </dependency>

For a full list of dependencies required for a specific engine, see Add an engine dependency.

Feature dependency

If you want to use additional client features, you need to add a corresponding dependency. You can learn which dependencies you need from a topic for a required feature.

Create the client

To instantiate the client, create the HttpClient class instance and pass an engine as a parameter:

import io.ktor.client.* import io.ktor.client.engine.cio.* val client = HttpClient(CIO)

In this example, we use the CIO engine.

You can also omit an engine:

import io.ktor.client.* val client = HttpClient()

In this case, the client will choose an engine automatically depending on the artifacts added in a build script. You can learn how the client chooses an engine from the Default engine documentation section.

Configure the client

Basic configuration

To configure the client, you can pass an additional functional parameter to the client constructor. The HttpClientEngineConfig class is a base class for configuring the client. For instance, we can change the behaviour of exceptions as follows:

import io.ktor.client.* import io.ktor.client.engine.cio.* val client = HttpClient(CIO) { expectSuccess = false }

Engine configuration

You can configure an engine using the engine function:

import io.ktor.client.* import io.ktor.client.engine.cio.* val client = HttpClient(CIO) { engine { // Configure an engine } }

See the Engines section for additional details.


Ktor lets you use additional client functionality (features) that is not available by default, for example, logging, authorization, or serialization. Most of them are provided in separate artifacts. For example, you can log HTTP calls by installing the Logging feature:

import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.features.logging.* val client = HttpClient(CIO) { install(Logging) }

You can also configure a feature inside the install block. For example, for the Logging feature, you can specify the logger and logging level:

val client = HttpClient(CIO) { install(Logging) { logger = Logger.DEFAULT level = LogLevel.HEADERS } }

Make a request

The main way for making HTTP requests is the request function that takes a URL as a parameter. Inside this function, you can configure various request parameters: specify an HTTP method, add headers, specify the request body, and so on. These parameters are exposed by the HttpRequestBuilder class.

import io.ktor.client.request.* import io.ktor.client.statement.* val response: HttpResponse = client.request("https://ktor.io/") { // Configure request parameters exposed by [[[HttpRequestBuilder|https://api.ktor.io/1.5.4/io.ktor.client.request/-http-request-builder/index.html]]] }

Note that this function allows you to receive a response in various ways. In this example, we receive a response as an HttpResponse object.

When calling the request function, you can specify the desired HTTP method using the method property:

import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* val response: HttpResponse = client.request("https://ktor.io/") { method = HttpMethod.Get }

In addition to the request function, HttpClient provides specific functions for basic HTTP methods: get, post, put, and so on. For example, you can replace the example above with the following code:

import io.ktor.client.request.* import io.ktor.client.statement.* val response: HttpResponse = client.get("https://ktor.io/")

To learn how to add headers, cookies, and specify a request body, see the Making requests help topic.

Receive a Response

All request functions (request, get, post, etc.) allow you to receive a response in several ways:

  • As an HttpResponse object:

    val httpResponse: HttpResponse = client.get("https://ktor.io/")
  • As a string:

    val stringResponse: String = client.get("https://ktor.io/")
  • As a byte array:

    val byteArrayResponse: ByteArray = client.get("https://ktor.io/")

You can learn more from the Receiving responses topic.

Close the HTTP client

After you finish working with the HTTP client, you need to free up the resources: threads, connections, and CoroutineScope for coroutines. To do this, call the HttpClient.close function:


If you need to use HttpClient for a single request, call the use function, which automatically calls close after executing the code block:

val status = HttpClient().use { client -> // ... }

Note that the close function prohibits creating new requests but doesn't terminate currently active ones. Resources will only be released after all client requests are completed.

Last modified: 19 April 2021