Ktor 2.3.7 Help

Sending responses

Ktor allows you to handle incoming requests and send responses inside route handlers. You can send different types of responses: plain text, HTML documents and templates, serialized data objects, and so on. For each response, you can also configure various response parameters, such as a content type, headers, and cookies.

Inside a route handler, the following API is available for working with responses:

Set response payload

Plain text

To send a plain text in a response, use the call.respondText function:

get("/") { call.respondText("Hello, world!") }


Ktor provides two main ways to send HTML responses to a client:

  • By building HTML using Kotlin HTML DSL.

  • By using JVM template engines, such as FreeMarker, Velocity, and so on.

To send HTML build using Kotlin DSL, use the call.respondHtml function:

routing { get("/") { val name = "Ktor" call.respondHtml(HttpStatusCode.OK) { head { title { +name } } body { h1 { +"Hello from $name!" } } } } }

To send a template in a response, call the call.respond function with a specific content ...

get("/index") { val sampleUser = User(1, "John") call.respond(FreeMarkerContent("index.ftl", mapOf("user" to sampleUser))) }

... or use an appropriate call.respondTemplate function:

get("/index") { val sampleUser = User(1, "John") call.respondTemplate("index.ftl", mapOf("user" to sampleUser)) }

You can learn more from the Templating help section.


To enable serialization of data objects in Ktor, you need to install the ContentNegotiation plugin and register a required converter (for example, JSON). Then, you can use the call.respond function to pass a data object in a response:

get("/customer/{id}") { val id = call.parameters["id"] val customer: Customer = customerStorage.find { it.id == id!!.toInt() }!! call.respond(customer) }

You can find the full example here: json-kotlinx.


To respond to a client with a content of a file, use the call.respondFile function. A code sample below shows how to send a specified file in a response and make this file downloadable by adding the Content-Disposition header:

import io.ktor.server.application.* import io.ktor.http.* import io.ktor.server.plugins.autohead.* import io.ktor.server.plugins.partialcontent.* import io.ktor.server.response.* import io.ktor.server.routing.* import java.io.File fun Application.main() { install(PartialContent) install(AutoHeadResponse) routing { get("/download") { val file = File("files/ktor_logo.png") call.response.header( HttpHeaders.ContentDisposition, ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, "ktor_logo.png") .toString() ) call.respondFile(file) } } }

Note that this sample has two plugins installed:

  • PartialContent enables the server to respond to requests with the Range header and send only a portion of content.

  • AutoHeadResponse provides the ability to automatically respond to HEAD request for every route that has a GET defined. This allows the client application to determine the file size by reading the Content-Length header value.

To learn how to run the sample, see download-file.

Raw payload

If you need to send the raw body payload, use the call.respondBytes function.

Set response parameters

Status code

To set a status code for a response, call ApplicationResponse.status. You can pass a predefined status code value ...

get("/") { call.response.status(HttpStatusCode.OK) }

... or specify a custom status code:

get("/") { call.response.status(HttpStatusCode(418, "I'm a tea pot")) }

Note that functions for sending a payload have overloads for specifying a status code.

Content type

With the installed ContentNegotiation plugin, Ktor chooses a content type for a response automatically. If required, you can specify a content type manually by passing a corresponding parameter. For example, the call.respondText function in a code snippet below accepts ContentType.Text.Plain as a parameter:

get("/") { call.respondText("Hello, world!", ContentType.Text.Plain, HttpStatusCode.OK) }


There are several ways to send specific headers in a response:

  • Add a header to the ApplicationResponse.headers collection:

    get("/") { call.response.headers.append(HttpHeaders.ETag, "7c876b7e") }
  • Call the ApplicationResponse.header function:

    get("/") { call.response.header(HttpHeaders.ETag, "7c876b7e") }
  • Use functions dedicated to specifying concrete headers, for example, ApplicationResponse.etag, ApplicationResponse.link, and so on.

    get("/") { call.response.etag("7c876b7e") }
  • To add a custom header, pass its name as a string value to any function mentioned above, for example:

    get("/") { call.response.header("Custom-Header", "Some value") }


To configure cookies sent in a response, use the ApplicationResponse.cookies property:

get("/") { call.response.cookies.append("yummy_cookie", "choco") }

Ktor also provides the capability to handle sessions using cookies. You can learn more from the Sessions section.


To generate a redirection response, call the respondRedirect function:

get("/") { call.respondRedirect("/moved", permanent = true) } get("/moved") { call.respondText("Moved content") }
Last modified: 08 December 2023