Enums in OpenAPI
The OpenAPI Specification (OAS) version 3.x supports the enum
(enumerated list) keyword for all schemaObject
object properties, including parameters, request bodies, and responses. The OAS defines an enum
according to the JSON Schema Specification. The enum
keyword restricts the value of a JSON property to a fixed set of values. The value must be an array with at least one element and each element must be unique.
For example, the following code defines a property called status
that must have a value of pending
, approved
, or rejected
:
{"type": "object","properties": {"status": {"type": "string","enum": ["pending", "approved", "rejected"]}},"required": ["status"]}
Any JSON instance validated against this schema must have a status
property with one of the three allowed values, case sensitive, or the validation will fail.
The enum
keyword can be used with any JSON data type, including strings, numbers, objects, arrays, booleans, and the null
type. The enum
keyword is often used with the base string
and integer
types. The boolean
type is constrained to true
and false
values and possibly null
for a tri-state boolean
. Using an enum
with floating point number types typically doesn’t make much sense.
Here is an OpenAPI schema defining a status
parameter that must have a value of pending
, approved
, or rejected
:
YAML
parameters:status:in: queryname: statusrequired: trueschema:type: stringenum:- pending- approved- rejected
Any API request that includes this status
parameter must have a value that is one of the three allowed values or the request will be rejected.
Defaults
Use default
to let clients omit a field when calling your service. For example, if a client orders a drink without specifying a cup size, they’ll get a medium cup.
openapi: 3.1.0info:title: Bar APIversion: 1.0.0paths:/orderDrink:post:operationId: orderDrinkrequestBody:content:application/json:schema:type: objectproperties:cupSize:type: stringenum:- small- medium- largedefault: mediumresponses:"200":description: Order placed successfully
If you use default
, remember to omit required: true
from the field.
Enums With Names and Values
A common requirement using enums is to specify a human-readable name for the enum label and an integer for the enum value. For example, in C#:
public enum CupSize{SMALL = 10MEDIUM = 20LARGE = 50}
This is not possible using the enum
keyword in OpenAPI, as OpenAPI enums allow only a list of values. If you want your schema’s enums to have both names and values, you can combine oneOf
and const
. This works only in OpenAPI version 3.1 and later. OpenAPI version 3.0 does not support const
.
Below is an example where a client can order a drink with one of three cup sizes:
openapi: 3.1.0info:title: Bar APIversion: 1.0.0paths:/orderDrink:post:summary: Order a drink with a specified cup sizeoperationId: orderDrinkrequestBody:required: truecontent:application/json:schema:type: objectproperties:cupSize:$ref: "#/components/schemas/CupSize"responses:"200":description: Order placed successfullycomponents:schemas:CupSize:description: Size of the cup to order, represented by a code and label.oneOf:- description: Small cup sizetype: objectproperties:size:type: integerconst: 10label:type: stringconst: "Small"- description: Medium cup sizetype: objectproperties:size:type: integerconst: 20label:type: stringconst: "Medium"- description: Large cup sizetype: objectproperties:size:type: integerconst: 50label:type: stringconst: "Large"
Below is an example call to this API:
{"cupSize": {"size": 20,"label": "Medium"}}
In this oneOf
solution, the client has to supply the label and the value, defeating the purpose of using an enum, where the label serves as a human-readable alias for the actual value. This oneOf
solution illustrates your options for including exact values. You’ll need to decide in your design whether you want a simple enum
or a more descriptive oneOf
.
If you are using OpenAPI 3.0 or want to use enum
, you can use an extension attribute to give labels to enum values. Different code generators and OpenAPI tools use different extension names. Below is an example using the Speakeasy extension field:
components:schemas:CupSize:description: Size of the cup to order, represented by a numeric code with a corresponding label.type: integerenum:- 10- 20- 50x-speakeasy-enums:- Small- Medium- Large
Or you can use a simple text description to prioritize human understanding over tooling support:
components:schemas:CupSize:type: integerenum:- 10- 20- 50description: Small Medium Large
Constants for Single Value Enums
Before JSON Schema 2019 was included in OpenAPI 3.1, using an enum with a single value was the only way to specify a constant. If you are still using OpenAPI 3.0, the example below shows how to specify that a constant string is returned in a response:
openapi: 3.0.0info:title: Bar APIversion: 1.0.0paths:/orderDrink:get:operationId: orderDrinkresponses:"200":description: Get a drinkcontent:application/json:schema:enum:- Here is your beverage
When using OpenAPI 3.1, you can use the const
keyword whose name more clearly matches its intention than enum
does:
openapi: 3.1.0info:title: Bar APIversion: 1.0.0paths:/orderDrink:get:operationId: orderDrinkresponses:"200":description: Get a drinkcontent:application/json:schema:const: Here is your beverage
Nullable Enums
OpenAPI 3.0
In OpenAPI 3.0 you can use the nullable
keyword to specify null
as an accepted value in an enum. In the example below, a client can order a drink with one of three cup sizes or no cup size specified at all:
components:schemas:CupSize:description: Size of the cup to order, represented by a numeric code with a corresponding label.type: stringnullable: trueenum:- SMALL- MEDIUM- LARGE
OpenAPI 3.1
OpenAPI 3.1 more closely aligns with the JSON Schema standard. As a result, the way to specify nullable types differs from OpenAPI 3.0. Instead of using the nullable
attribute, OpenAPI 3.1 uses the JSON Schema approach with an array of types - including the null
type. Here’s the same example adapted for OpenAPI 3.1:
components:schemas:CupSize:description: Size of the cup to order, represented by a numeric code with a corresponding label.type: [string, null]enum:- SMALL- MEDIUM- LARGE- null
Open Enums
Traditionally enums are closed, meaning that only the values listed in the enum are allowed. In contrast, open enums allow additional values beyond those explicitly defined in the spec. Open Enums are useful when your API is evolving to support new use cases. In that scenario, you can let clients send values that aren’t defined yet because their usage is on the edge of your API’s capabilities.
OpenAPI 3.x currently does not natively support the description open enums directly. However, check if your tooling supports x-
extension attributes. For example, the Speakeasy extension x-speakeasy-unknown-values
lets you define an enum with additional values beyond those listed.
components:schemas:CupSize:description: Size of the cup to order, represented by a numeric code with a corresponding label.type: [string, null]x-speakeasy-unknown-values: allowenum:- SMALL- MEDIUM- LARGE- null
Examples
Below is an example from the components
of an API for ordering drinks showing all the different data types you can use with enum
:
components:schemas:Orders:type: objectproperties:cupSize:type: stringenum:- small- medium- largesugarNumbers:type: integerenum:- 0- 1- 2- 3strength:type: numberenum:- 0.25- 0.5- 0.75- 1.0decaffeinated:type: booleanenum:- true- falseteaOrigin:type: objectenum:- { country: India, region: Assam, address: { name: "The farm" } }- { country: China, region: Fujian }- { country: Japan, region: Shizuoka }- { country: Sri Lanka, region: Nuwara Eliya }sizeRange:type: arrayenum:- [1, 10]- [11, 20]
Date objects are not directly supported. Export your dates to ISO strings before using them in an API.
Best Practices
Enums are simple, so there are only a few things to consider when using them in your schema:
- Naming conventions: Be consistent throughout your schema. If you use uppercase, like
NEW
, then stick to uppercase for all values in all enums. - Document values: Ensure that your description field explains exactly what the purpose of each enum value is. If two values are similar, differentiate them carefully. A few extra explanatory lines in your schema can save you days of customer support queries.
- Plan for extension: Have you designed your schema and your server to easily adapt to adding new values to an enum? How much work will clients have to do to use the new values? What about removing values or renaming them? Consider how this affects the versioning of your API and you will explain it to clients.
- Tool support: Which tools, such as code generators, will you use with your schema? Do they support
enum
andconst
? Do they require extension attributes? Research this before writing your schema. - Default value: Provide default values for enums with an obvious default, but avoid them where you need the client to consider their choice. For example, for an API that creates a web server, you would want the client to think carefully about the server size as it costs the client money. In comparison, operating system versions can default to the latest version without the same level of ramifications.