scala> sealed trait Op defined trait Op scala> case class Foo(s: String) extends Op defined class Foo scala> case class Ciao(i: Int) extends Op defined class Ciao scala> case class Bar(op: Op, b: Boolean) defined class Bar scala> Bar(Ciao(3), false) res6: Bar = Bar(Ciao(3),false) scala> res6.asJson res7: io.circe.Json = { "op" : { "Ciao" : { "i" : 3 } }, "b" : false } scala> decode[Bar](res7.toString) res8: cats.data.Xor[io.circe.Error,Bar] = Right(Bar(Ciao(3),false))