Quick answer: Before releasing an API that uses JSON Schema
format, prove that assertion mode is active, then test valid and invalid date-times, emails, URI forms, UUIDs, hostnames and IP addresses, custom formats, and every production validator. These eight tests catch contracts that look strict in a schema but behave differently at runtime.
format looks like a simple string check, yet its enforcement depends on the schema dialect, vocabulary, validator, plugins, and options. A schema can compile successfully while malformed values pass. The release checklist below turns those hidden choices into small, reviewable fixtures.
If the vocabulary itself is new to your team, start with the JSON Schema guide, then return to these format-specific release tests.
1. Is format assertion actually enabled in production?
Start with one deliberately invalid value and require the production validation path to reject it. Draft 2020-12 separates format annotation from format assertion, so a validator may recognize format without enforcing it. Record the dialect, vocabulary, library, plugin, and options beside the test so the expected behavior is reproducible.
The official Draft 2020-12 overview identifies separate format-annotation and format-assertion vocabularies. The validation specification also explains why supporting the annotation vocabulary does not automatically mean every format must be asserted. This is an interoperability choice, not a JSON parsing error.
Use a smoke fixture that cannot be confused with a borderline case:
{
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string",
"format": "date-time"
},
"instance": "definitely-not-a-date",
"expected": false
}
If that fixture passes, stop debugging the timestamp. Check whether the validator treats formats only as annotations, requires a separate package, or needs an assertion option. Ajv, for example, documents standard format support in the separate ajv-formats package; another implementation may package or configure the same feature differently.
Keep this smoke check close to validator initialization. A playground using assertion behavior does not prove that the server, gateway, generated client, or editor uses the same mode. The earlier JSON Schema validation mistakes guide covers the broader dialect and configuration risks; this checklist goes deeper on format-specific evidence.
2. Do date, time, and date-time fixtures cover RFC 3339 boundaries?
Test calendar validity, required offsets, leap days, fractional seconds, lowercase variants if relevant, and invalid hour or offset boundaries. A regular expression that only resembles a timestamp can accept impossible dates. Run the exact format checker used in production and add separate business rules for ranges, scheduling, and precision.
JSON Schema's standard date, time, and date-time formats are based on RFC 3339. Include obvious passes and failures rather than one current timestamp:
| Value | Format | Expected | Why |
|---|---|---|---|
2024-02-29 | date | Pass | Leap day in a leap year |
2026-02-29 | date | Fail | Impossible calendar day |
2026-10-24T09:30:00Z | date-time | Pass | Offset-bearing instant |
2026-10-24T09:30:00 | date-time | Fail | No UTC designator or numeric offset |
24:00:00Z | time | Fail | Hour is outside the RFC 3339 range |
Do not use successful JavaScript Date parsing as proof of schema conformance. Runtimes can normalize or accept strings outside the profile your contract names. Conversely, a schema-format verdict says nothing about whether a syntactically valid date is in the future, inside a booking window, or supported by a database column.
The nine JSON date API tests cover round trips, offsets, epoch units, and precision after the schema gate. Keep both layers: format fixtures prove the string grammar, while API tests prove the representation survives the whole system.
3. Does email validation match the contract without overpromising?
Test ordinary addresses, malformed separators, missing domains, quoted or internationalized cases your product accepts, and the difference between email and idn-email. Then document the supported profile. A passing format check proves syntax under one implementation; it cannot establish mailbox existence, ownership, deliverability, or user consent.
The JSON Schema validation vocabulary lists both email and idn-email. Implementations may differ at difficult edges because email syntax and internationalized domains involve multiple standards and optional capabilities. The active 2026 cross-implementation format evidence focuses specifically on cases where real validators disagree, making a local fixture set more useful than copying an assumed universal regex.
A practical minimum matrix is:
alice@example.comshould passemail;alice.example.comshould fail because it lacks@;alice@and@example.comshould fail;- an internationalized address should have an explicit expected result for
emailandidn-emailunder every deployed validator; - leading or trailing whitespace should fail unless the application deliberately trims before validation.
Be explicit about preprocessing. If a service trims or lowercases input, test the raw request and transformed value separately. Silent mutation can make logs, signatures, and validation errors disagree about what the client actually sent.
For account creation, syntax validation is only the first gate. Verification links, bounce handling, and consent live outside JSON Schema. Keeping that boundary in the article and code prevents an email annotation from being sold as proof of reachability.
4. Are uri, uri-reference, iri, and iri-reference used deliberately?
Choose the format according to whether the field requires an absolute identifier, permits a relative reference, or supports internationalized characters. Test fragments, relative paths, schemes, percent encoding, whitespace, and malformed escapes. Browser URL parsing is not a substitute because browsers can resolve relative input using environmental base URLs and recovery rules.
The standard vocabulary distinguishes uri from uri-reference, and iri from iri-reference. That distinction belongs in the contract:
{
"properties": {
"canonical": { "type": "string", "format": "uri" },
"next": { "type": "string", "format": "uri-reference" }
}
}
For that schema, https://api.example.com/orders/42 is appropriate for canonical, while ../orders/43?view=full can be a valid relative reference for next. Test %20 as encoded space, a bare literal space, an invalid %ZZ escape, a fragment-only reference, and the schemes your application intends to allow.
Format validity does not make a URI safe to fetch. Enforce permitted schemes, origins, hosts, ports, redirect policy, and network destinations in application code before server-side retrieval. A syntactically valid URI can still point to localhost, private infrastructure, or an untrusted site.
If the field is really an HTTP URL, say so and add that policy. Generic URI syntax permits schemes beyond HTTP and HTTPS. Schema format gives you a representation check; it does not supply an allowlist or prevent server-side request forgery.
5. Does uuid validation reject almost-right identifiers?
Test canonical hyphen placement, hexadecimal characters, accepted letter case, braces, missing groups, and any version or variant policy your application needs. The generic UUID format checks representation, but a service that requires UUIDv4, UUIDv7, or a specific variant must add an explicit rule and corresponding fixtures.
The standard uuid format refers to the UUID textual representation. Use a table that separates syntax from product policy:
| Value | Generic UUID | UUIDv4-only policy |
|---|---|---|
550e8400-e29b-41d4-a716-446655440000 | Pass | Pass |
550e8400e29b41d4a716446655440000 | Fail | Fail |
550e8400-e29b-11d4-a716-446655440000 | Pass | Fail |
{550e8400-e29b-41d4-a716-446655440000} | Fail | Fail |
Do not infer trust or existence from UUID syntax. A well-formed identifier may refer to no record, another tenant's record, or a deleted resource. Authorization and lookup checks still belong after structural validation.
If you add a pattern for a particular version, keep format: uuid as the broad syntax check and anchor the pattern from start to end. Test uppercase and lowercase deliberately. A loosely written substring pattern can pass a UUID surrounded by extra text, while an over-restrictive pattern can reject representations your API previously accepted.
6. Do hostname, IPv4, and IPv6 tests include ambiguous edge cases?
Test the network formats separately with known valid and invalid values, including label boundaries, leading or trailing separators, IPv4 octet limits, compressed IPv6, IPv4-mapped IPv6, and zone identifiers if relevant. Never treat a passing address format as permission to connect; routing and destination policy require separate security checks.
Useful negative fixtures include 256.1.1.1, 192.168.1, a hostname label longer than the supported limit, and an IPv6 address with two :: compression markers. Positive fixtures should include ordinary hostnames, 127.0.0.1, 2001:db8::1, and every special representation your system actually accepts.
The point is not to assemble the largest address corpus. It is to expose differences between a strict standards checker and convenience parsers that accept shorthand or legacy forms. If a proxy, application, and database parse the same string differently, validate at the boundary and pass a normalized typed value downstream.
Security policy comes next. Loopback, private, link-local, multicast, reserved, and documentation ranges can all be syntactically valid. A webhook destination or import URL may need DNS resolution checks and protection against rebinding in addition to URI, hostname, and IP syntax validation.
Use the JSON Viewer to confirm a non-sensitive fixture is a string at the intended property path before schema validation. The viewer helps inspect type and nesting; it does not resolve DNS or validate network policy.
7. Do regex and custom formats behave as explicit application code?
Test the standard regex format with expressions your target regular-expression dialect accepts, then treat every custom format as versioned application code. Define its input type, normalization, failure message, and boundary cases. Unknown custom formats may be ignored, rejected during schema compilation, or handled differently depending on validator configuration.
JSON Schema's regex format asks whether a string is a valid regular expression, but regex engines do not support identical syntax or flags. A pattern accepted by JavaScript may not compile in Java, Python, or a gateway. If the expression will execute in a specific runtime, compile it there during testing rather than assuming one validator models every engine.
For a custom order code, avoid an unanchored rule:
{
"type": "string",
"pattern": "^ORD-[0-9]{8}$"
}
Then test ORD-20261024, xORD-20261024, ORD-202610240, lowercase input, whitespace, non-ASCII digits, and a non-string JSON value. If the organization registers a custom format name instead of using pattern, keep the same cases against the registration callback.
Custom formats reduce portability because consumers must possess the same code. Publish the rule or use ordinary JSON Schema keywords when they express the constraint. If a consumer does not know a format, the safest response depends on the contract: fail schema startup for required enforcement, or explicitly document annotation-only behavior.
8. Do all production validators return the same verdicts?
Run one shared corpus through every validator used by servers, gateways, clients, editors, and code generators. Compare boolean verdicts first, then normalized error locations and keywords where operationally important. Pin versions and options, and require review when an upgrade changes results rather than quietly accepting one implementation as the universal definition.
JSON Schema maintains Bowtie to compare implementation behavior, and the official tooling directory notes that listed tools can support different portions of different drafts. The 2026 format test-suite work provides fresh qualitative evidence that edge-case agreement is still an active interoperability problem; it does not supply search volume or prove every validator is faulty.
Store fixtures in a language-neutral shape:
{
"description": "date-time requires an offset",
"schema": { "type": "string", "format": "date-time" },
"tests": [
{ "data": "2026-10-24T09:30:00Z", "valid": true },
{ "data": "2026-10-24T09:30:00", "valid": false }
]
}
Each harness should load the same declared dialect and assertion settings. If verdicts differ, reduce the case, check the governing specification, and decide whether to narrow the accepted contract or align configuration. Do not average the answers or hide the mismatch behind a generic validation error.
For background, Wikipedia's JSON Schema overview explains how a schema describes JSON data. The official specification and the exact implementation documentation remain the authorities for format behavior.
What should the format-validation release checklist record?
Record the schema dialect, assertion vocabulary or option, validator and format-package versions, preprocessing rules, positive and negative fixtures, and cross-runtime results. Keep format syntax separate from reachability, authorization, and business policy. Re-run the matrix whenever schemas, dependencies, gateways, generated clients, or runtime versions change.
A compact release record should answer:
- Which
$schemaURI and format vocabulary are active? - Which library, extension package, and options enforce formats?
- Which edge cases are intentionally accepted or rejected?
- Does input change before validation through trimming or coercion?
- Do all production validators agree on the shared corpus?
- Which post-format checks enforce application and security policy?
Treat that record as part of the API contract. A format library upgrade can be a behavior change even when no schema file changes. Named fixtures make the difference visible during review and give teams a concrete reason to accept, reject, or stage the new behavior.