Play Union Types

Model type-safe alternatives with union types. Express that a variable is exactly one of a known set of types — the generated Play clients handle serialization and deserialization automatically.

For example, in an ecommerce system you might accept orders from both registered users (with a username and password) and guest users (first-time visitors). Define a registered_user type and a guest_user type, then combine them into a single user union type and reference it from your order model.

Over the wire, union types in the Play clients are represented based on the types of their members.

D Model unions (with a discriminator)

When all members are models or other unions, the union type is serialized as a JSON object with the discriminator field injected. For example, with the discriminator set to "type":

Example serializations:

{
  "type": "registered_user",
  "guid": "f30dc64e-1793-4d59-aa47-71f000e06851",
  "email": "registered@test.apibuilder.io"
}
{
  "type": "guest_user",
  "guid": "f30dc64e-1793-4d59-aa47-71f000e06851",
  "email": "guest@test.apibuilder.io"
}

S String-serializable unions (literals, enums, and primitives)

When all members are enums, string-serializable primitives (string, uuid, date-iso8601, date-time-iso8601), or literal string values, the union is serialized as a plain JSON string. These unions can also be used in path and query parameters.

Example spec:

"unions": {
  "version_number": {
    "discriminator": "value",
    "types": [
      { "literal": "latest", "aliases": ["LATEST"] },
      { "type": "date-time-iso8601" }
    ]
  }
}

Example serializations:

"latest"
"2026-03-30T12:00:00.000Z"

In Scala, this generates a sealed trait with case objects for literals and wrapper case classes for primitives:

sealed trait VersionNumber
case object Latest extends VersionNumber
case class VersionNumberDateTimeIso8601(value: DateTime) extends VersionNumber

object VersionNumber {
  def apply(value: String): VersionNumber = ...  // parses "latest", "LATEST", or ISO datetime
}

Example Applications

Working examples demonstrating union types:

Ready to define your own union types?

View api.json Specification