Content type

The endpoint’s output content type is bound to the body outputs, that are specified for the endpoint (if any). The codec of a body output contains a CodecFormat, which in turns contains the MediaType instance.

Codec formats and server interpreters

Codec formats define the default media type, which will be set as the Content-Type header. However, any user-provided value will override this default:

  • dynamic content type, using .out(header(HeaderNames.ContentType))
  • fixed content type, using e.g. out(header(Header.contentType(MediaType.ApplicationJson)))

Multiple content types

Multiple, alternative content types can be specified using oneOf, similarly as when specifying status code mappings.

On the server side, the appropriate mapping will be chosen using content negotiation, via the Accept header, using the configurable ContentTypeInterceptor. Note that both the base media type, and the charset for text types are taken into account.

On the client side, the appropriate mapping will be chosen basing on the Content-Type header value.

For example:

import sttp.tapir._
import sttp.tapir.Codec.{JsonCodec, XmlCodec}
import sttp.model.StatusCode

case class Entity(name: String)
implicit val jsonCodecForOrganization: JsonCodec[Entity] = ???
implicit val xmlCodecForOrganization: XmlCodec[Entity] = ???

    oneOfMapping(StatusCode.Ok, anyJsonBody[Entity]),
    oneOfMapping(StatusCode.Ok, xmlBody[Entity]),

For details on how to create codes manually or derive them automatically, see custom types and the subsequent section on json.