OpenAPI describes the shape of API data using JSON Schema’s primitive types
(string, number, integer, boolean, array, object, null) refined by
an optional format keyword. Choosing the right type/format pair makes generated
clients, server stubs and documentation accurate. This reference lists the common
combinations and their semantics.
How it works
Every schema in an OpenAPI document has a type. For scalar types a format
narrows the meaning — for example type: string, format: date-time means an
RFC 3339 timestamp, and type: integer, format: int64 means a 64-bit integer.
Tooling uses these to pick the right language type (e.g. OffsetDateTime,
UUID, long) when generating code. In OpenAPI 3.1, schemas are pure JSON
Schema 2020-12, so null is expressed with type arrays rather than the old
nullable keyword.
Common type and format pairs
| type | format | What it means | Generated language type |
|---|---|---|---|
string | (none) | Arbitrary UTF-8 text | string |
string | date-time | RFC 3339 timestamp (2025-01-15T10:30:00Z) | OffsetDateTime, datetime |
string | date | Calendar date (2025-01-15) | LocalDate, date |
string | time | Time of day (10:30:00) | LocalTime, time |
string | duration | ISO 8601 duration (PT1H30M) | Duration |
string | uuid | UUID (550e8400-e29b-41d4-…) | UUID, Guid |
string | email | Email address | string (validated) |
string | uri | Full URI (https://…) | URI, URL |
string | byte | Base64-encoded data | []byte, byte[] |
string | binary | Binary file stream | Stream, bytes |
string | password | Sensitive; redacted in docs | string |
number | float | 32-bit IEEE float | float |
number | double | 64-bit IEEE float (default) | double |
integer | (none) | Unspecified-width integer | int |
integer | int32 | Signed 32-bit (±2.1B) | int |
integer | int64 | Signed 64-bit (±9.2×10¹⁸) | long |
boolean | (none) | true or false | boolean |
array | (none) | Ordered list (requires items) | List<T>, []T |
object | (none) | Key-value map | struct, class |
Nullable in 3.0 vs 3.1
# OpenAPI 3.0
nickname:
type: string
nullable: true
# OpenAPI 3.1 (JSON Schema 2020-12)
nickname:
type: [string, "null"]
The 3.0 nullable: true shorthand is not valid in 3.1. Many code generators and
linters will flag it, so migrate to the array syntax when upgrading spec versions.
Practical gotchas
int64 and JavaScript. JSON numbers and JavaScript’s Number type cannot
safely represent integers larger than 2^53 − 1. If your API returns a 64-bit
ID (common in databases), declare it as type: string, format: int64 or transmit
it as a quoted string. Code generators in strongly typed languages (Java, Go)
will still emit a long, but JavaScript clients need the string form.
date-time timezone requirement. RFC 3339 timestamps must include a timezone
offset. 2025-01-15T10:30:00 (no Z or offset) is not strictly valid. Use Z
for UTC or an explicit offset like +05:30.
byte vs binary. Use byte for Base64-encoded data transferred as a JSON
string. Use binary for raw file uploads and downloads (typically in
multipart/form-data or application/octet-stream).
Notes and tips
Treat format as a hint: many validators ignore formats they do not recognise,
so add explicit constraints (pattern, minimum, maxLength) when correctness
matters. Large identifiers that exceed the safe JavaScript integer range are often
modelled as type: string even though they are numeric. Custom formats are
allowed and simply pass through as documentation — pair them with a pattern
regex if you want constraint enforcement.