Data Types & Common Objects
Rules for consistent data formats (dates, durations, identifiers) and reusable common objects.
These rules standardize common data types and formats so APIs stay consistent across languages, timezones, and tooling.
Related reference:
Data Types & Formats
#801 - Use ISO 8601 Durations and Intervals
Intent: make durations unambiguous and interoperable across languages and SDKs.
Represent durations and time intervals using ISO 8601 format (e.g., "P3Y6M4DT12H30M5S" for periods, "PT1H30M" for durations) for international standard compliance.
Examples:
PT15M(15 minutes)PT1H30M(1 hour, 30 minutes)P7D(7 days)
Avoid:
- ❌
900(is that seconds? ms?) - ❌
1h30m(non-standard)
Testability:
- OpenAPI schemas and examples use ISO 8601 duration strings consistently for duration-like fields.
#802 - Use Standard Date/Time Formats
Intent: prevent ambiguity and ensure consistent parsing across clients.
JSON payloads:
- Date-time values MUST use RFC 3339 / ISO 8601 date-time strings (OpenAPI
format: date-time).- Prefer UTC
Z: Timestamps SHOULD be stored/transmitted in UTC (Z) whenever possible to prevent timezone ambiguity and simplify client handling. - ⚠
2025-10-15T14:30:00-05:00(allowed by RFC 3339, but prefer UTC)
- Prefer UTC
- Date-only values (no time) MUST use ISO 8601 full-date
YYYY-MM-DD(OpenAPIformat: date).
HTTP headers:
- Date/time values in HTTP headers MUST use HTTP-date format (IMF-fixdate; RFC 9110).
Examples (JSON date-time):
- ✅
2026-01-15T14:30:00Z - ✅
2026-01-15T14:30:00.123Z(fractional seconds) - ⚠
2025-10-15T14:30:00-05:00(allowed by RFC 3339, but prefer UTC) - ❌
01/15/2026 2:30pm
Examples (JSON date-only):
- ✅
2026-01-15 - ❌
15-01-2026
Example (HTTP-date header):
Last-Modified: Tue, 15 Jan 2026 14:30:00 GMTPrecision guidance:
- Be consistent about fractional-second precision across endpoints.
- If you emit milliseconds, always emit milliseconds (don't sometimes emit
.1and sometimes omit it).
OpenAPI example:
createdAt:
type: string
format: date-time
birthDate:
type: string
format: date#803 - Use Standard Country, Language, and Currency Codes
Intent: ensure international interoperability and avoid product-specific code systems.
Use the appropriate standards:
- Country codes: ISO 3166-1 alpha-2 (e.g.,
US,DE) - Language tags: BCP 47 (e.g.,
en-US,de-DE) - Currency codes: ISO 4217 (e.g.,
USD,EUR)
Examples:
- Country:
US,DE - Language:
en-US,de-DE - Currency:
USD,EUR
OpenAPI guidance (examples):
countryCode:
type: string
description: ISO 3166-1 alpha-2 country code.
example: US
languageTag:
type: string
description: BCP 47 language tag.
example: en-US
currency:
type: string
description: ISO 4217 currency code.
example: USD#804 - Define Numeric Formats
Intent: avoid precision loss and ambiguous integer ranges.
Numeric fields MUST be modeled with explicit OpenAPI types and formats.
Integers:
- Use
type: integer. - Use
format: int32for 32-bit ranges. - Use
format: int64for 64-bit ranges.
Floating point:
- Use
type: numberwithformat: floatordoubleonly when floating-point is acceptable.
Decimals / money-like precision:
- Do NOT use floating-point for money or high-precision decimals.
- Use
type: stringwith a documented decimal format (or a dedicated object) and provide examples.
IDs and opaque identifiers:
- Do not model IDs as numbers.
- Use
type: stringto avoid precision loss in JavaScript and other clients.
OpenAPI examples:
count:
type: integer
format: int32
sizeBytes:
type: integer
format: int64
ratio:
type: number
format: double
amount:
type: string
description: Decimal string.
example: "123.45"
resourceId:
type: string
format: uuid#806 - Use Standard Property Formats
Intent: make schemas self-describing and enable validation and codegen.
For common string/number shapes, APIs MUST use standardized OpenAPI formats where they apply, and SHOULD validate them at runtime.
Requirements:
- Use
formatonly when it accurately describes the values emitted/accepted. - Provide examples that match the declared format.
- Prefer standards-based formats instead of ad-hoc regexes in prose.
Common formats (examples):
date-time/date(see [#802])uuidfor UUID stringsurifor absolute URIs;uri-referencewhen relative references are allowedemailfor email addressesipv4/ipv6for IP literals
Examples (OpenAPI):
type: object
properties:
created:
type: string
format: date-time
email:
type: string
format: email
callbackUrl:
type: string
format: uri
requestId:
type: string
format: uuidNotes:
formatis a hint in many toolchains; if a field must be constrained beyond whatformatprovides, add explicit constraints (minLength,maxLength,pattern) and document them.- Do not misuse
formatfor internal implementation types.
#807 - Encode Embedded Binary as base64url
Intent: ensure embedded binary is safe for JSON transport and URL contexts.
Default policy: do not embed binary in JSON. Prefer non-JSON upload/download endpoints and standard media types (see [#704]).
If embedding is unavoidable:
- Use standard base64 for binary embedded in JSON payloads.
- Use base64url only when the encoded value must be URL-safe (e.g., used inside a URL or otherwise constrained by URL-safe character sets).
- Include metadata so clients can interpret the value:
contentType(e.g.,image/png)encoding(base64orbase64url)- optional
sizeBytes(recommended)
Constraints:
- Document maximum allowed size (and reject oversize payloads with a clear error).
- Prefer references/links for large binaries rather than embedding.
Example:
{
"contentType": "image/png",
"encoding": "base64",
"data": "iVBORw0KGgoAAAANSUhEUg..."
}Common Data Types & Objects
#805 - Use Common Field Names
Intent: reduce cognitive load and avoid “same concept, different name” drift across APIs.
APIs MUST reuse common field names and semantics for shared concepts.
Baseline field registry (expand over time):
id(string): stable identifier for the resource (URL-friendly; see [#512])name(string): human-readable display namedescription(string): human-readable description (optional)createdAt(string, date-time): creation timestamp (RFC 3339; see [#802])modifiedAt(string, date-time): last-modified timestamp (RFC 3339; see [#802])type(string): discriminator/type label when neededstatus(string/enum): lifecycle status (document enum values; see [#112])enabled(boolean): boolean flags are true/false only (see [#700])
Rules:
- Do not invent synonyms (
createdvscreatedAt,lastModifiedvsmodifiedAt) without a strong reason. - If you already have a legacy name, do not rename without a compatibility plan; prefer the standard name for new APIs/fields.
If you model money-like values (optional pattern):
- Use
amountas a decimal string (see [#804]) andcurrencyas ISO 4217 (see [#803]).
Testability:
- Reviewers can spot-check schemas across APIs for consistent naming and formats.