JSON Schema Validation Best Practices 2026: Draft 2020-12 Examples
Quick Answer
Best default
Use Draft 2020-12 for new schemas, declare $schema, and compile validators at startup.
Empty schema
{} and true match any JSON value. false rejects every value.
Common trap
format is not always enforced by default. In Ajv v7+, install and enable ajv-formats.
Source-Backed 2026 Notes
The current JSON Schema meta-schema is Draft 2020-12. The official specification separates core behavior from validation vocabularies, and Draft 2020-12 changed tuple validation from older items/additionalItems patterns to prefixItems/items. Ajv supports Draft 2020-12, but its format validators are provided by a separate package.
- JSON Schema Draft 2020-12 is the active meta-schema listed by json-schema.org.
- JSON Schema Core defines boolean schemas, references, dialects, and the behavior of missing keywords.
- JSON Schema Validation defines assertion and annotation vocabularies, including the format split.
- Ajv JSON Schema docs explain Draft 2020-12 keyword behavior and array tuple changes.
What Is JSON Schema?
JSON Schema is a declarative language for describing the structure and constraints of JSON data. Think of it as TypeScript types for your JSON -- it defines what fields exist, what types they have, which ones are required, and what values are valid. But unlike TypeScript, JSON Schema validation happens at runtime, which makes it perfect for validating API payloads, configuration files, form submissions, and any data that crosses trust boundaries.
A JSON Schema is itself a JSON document. It describes another JSON document. When you validate data against a schema, the validator checks every constraint and returns a list of violations if the data does not conform. This approach is language-agnostic -- the same schema works in JavaScript, Python, Go, Java, C#, and every other language with a JSON Schema library.
// A simple JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
},
"required": ["name", "email"]
}
// Valid data:
{ "name": "Alice", "email": "[email protected]", "age": 30 }
// Invalid data (missing required field, wrong type):
{ "email": 123 }
// Errors: "name" is required, "email" must be a stringTo experiment with JSON structures before writing schemas, format your data with our JSON Formatter -- it validates syntax, highlights errors, and pretty-prints with configurable indentation.
JSON Schema Validation Best Practices
The strongest production schemas are explicit at trust boundaries and flexible where compatibility matters. Use this table as the default decision framework before adding validation to an API, webhook, config file, or generated JSON output.
| Decision | Recommended Pattern | Why It Matters |
|---|---|---|
| Draft for new work | "$schema": "https://json-schema.org/draft/2020-12/schema" | Uses the current dialect and avoids older tuple/reference patterns. |
| Strict request payloads | additionalProperties: false | Rejects typos and unexpected client fields before they reach business logic. |
| Strict composed objects | unevaluatedProperties: false | Works better with allOf/oneOf schemas because it sees properties validated by subschemas. |
| Reusable shapes | $defs + $ref | Keeps shared address, user, pagination, and error schemas consistent across endpoints. |
| Tuple arrays | prefixItems + items: false | Draft 2020-12's clear way to say "position 1 means X, position 2 means Y, no extras". |
| Runtime validation | compile once, validate many | Avoids recompiling schemas on every request and makes failures easier to observe. |
Type System: The Foundation
Every JSON Schema starts with a type declaration. JSON Schema supports seven primitive types that map directly to JSON value types.
| Type | JSON Value | Example |
|---|---|---|
| string | Text in double quotes | "hello" |
| number | Any numeric value | 3.14, -1, 2e10 |
| integer | Whole numbers only | 42, -7, 0 |
| boolean | true or false | true |
| object | Key-value pairs | {"key": "value"} |
| array | Ordered list | [1, 2, 3] |
| null | Null value | null |
// Allow multiple types (nullable string)
{ "type": ["string", "null"] }
// Accepts: "hello", null
// Rejects: 42, true
// Enum: restrict to specific values
{ "type": "string", "enum": ["active", "inactive", "pending"] }
// Const: restrict to exactly one value
{ "const": "production" }Empty Schema : Valid, but Usually Too Permissive
A frequent search question is whether an empty JSON Schema is valid. It is: {} has no assertion keywords, so it accepts every JSON value. JSON Schema also supports boolean schemas: true accepts everything and false rejects everything.
// Empty schema: every JSON value is valid
{}
// Same assertion behavior:
true
// Reject every JSON value:
false
// Useful extension point: allow arbitrary metadata
{
"type": "object",
"properties": {
"id": { "type": "string" },
"metadata": {}
},
"required": ["id"]
}Use empty schemas only when "anything goes" is intentional. If you are validating API requests, form submissions, webhook payloads, or configuration files, define a real type and choose whether extra properties should be allowed.
String Constraints
Strings support length constraints, regex pattern matching, and format annotations for common string types like emails, URIs, dates, and UUIDs. Treat format carefully: Draft 2020-12 separates format annotation from format assertion, and many validators require explicit configuration before a bad email or URI is rejected.
// String with length and pattern constraints
{
"type": "string",
"minLength": 3,
"maxLength": 50,
"pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
}
// Accepts: "username_123"
// Rejects: "ab" (too short), "123abc" (doesn't start with letter)
// Built-in format validators
{ "type": "string", "format": "email" } // RFC 5321 email
{ "type": "string", "format": "uri" } // Full URI with scheme
{ "type": "string", "format": "date" } // ISO 8601 date (YYYY-MM-DD)
{ "type": "string", "format": "date-time" } // ISO 8601 datetime
{ "type": "string", "format": "uuid" } // UUID any version
{ "type": "string", "format": "ipv4" } // IPv4 address
{ "type": "string", "format": "ipv6" } // IPv6 address
{ "type": "string", "format": "hostname" } // Internet hostname
{ "type": "string", "format": "json-pointer" } // JSON Pointer (RFC 6901)The pattern keyword accepts any valid regular expression. For building and testing regex patterns, use our Regex Tester to verify they match your expected inputs before embedding them in schemas.
Number Constraints
// Integer with range
{
"type": "integer",
"minimum": 1,
"maximum": 100
}
// Number with exclusive bounds
{
"type": "number",
"exclusiveMinimum": 0, // greater than 0 (not equal)
"exclusiveMaximum": 1 // less than 1 (not equal)
}
// Accepts: 0.5, 0.001, 0.999
// Rejects: 0, 1, -0.5
// Multiple of (useful for prices, grid sizes)
{
"type": "number",
"multipleOf": 0.01 // two decimal places max
}
// Accepts: 9.99, 10.00, 0.01
// Rejects: 9.999
// Percentage with step
{
"type": "integer",
"minimum": 0,
"maximum": 100,
"multipleOf": 5 // 0, 5, 10, 15, ..., 100
}Object Schemas: Properties, Required Fields, and More
Objects are the most common type in JSON APIs. JSON Schema gives you fine-grained control over which properties are allowed, which are required, and what additional properties look like.
// Complete API request schema
{
"type": "object",
"properties": {
"username": {
"type": "string",
"minLength": 3,
"maxLength": 30,
"pattern": "^[a-zA-Z0-9_]+$"
},
"email": {
"type": "string",
"format": "email"
},
"role": {
"type": "string",
"enum": ["admin", "editor", "viewer"],
"default": "viewer"
},
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"required": ["username", "email"],
"additionalProperties": false
}
// "additionalProperties": false → rejects any field not listed in "properties"
// "additionalProperties": true → allows any extra fields (default behavior)
// "additionalProperties": { "type": "string" } → extra fields must be stringsProperty Name Patterns
// patternProperties: apply schemas based on property name patterns
{
"type": "object",
"patternProperties": {
"^x-": { "type": "string" }, // x-* headers must be strings
"^[0-9]+$": { "type": "boolean" } // numeric keys must be booleans
},
"additionalProperties": false
}
// Accepts: { "x-custom": "value", "123": true }
// Rejects: { "x-custom": 42 } (x-* must be string)Property Dependencies
// dependentRequired: if field A exists, field B is required
{
"type": "object",
"properties": {
"creditCard": { "type": "string" },
"billingAddress": { "type": "string" },
"couponCode": { "type": "string" }
},
"dependentRequired": {
"creditCard": ["billingAddress"] // creditCard requires billingAddress
}
}
// Accepts: { "couponCode": "SAVE10" } (no card, no address needed)
// Accepts: { "creditCard": "4111...", "billingAddress": "123 St" }
// Rejects: { "creditCard": "4111..." } (missing billingAddress)Array Schemas: Items, Tuples, and Uniqueness
// Array of strings with length constraints
{
"type": "array",
"items": { "type": "string", "minLength": 1 },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
// Accepts: ["apple", "banana", "cherry"]
// Rejects: ["apple", "apple"] (not unique)
// Rejects: [] (minItems is 1)
// Tuple validation (Draft 2020-12: prefixItems)
{
"type": "array",
"prefixItems": [
{ "type": "string" }, // first element: string
{ "type": "integer" }, // second element: integer
{ "type": "boolean" } // third element: boolean
],
"items": false // no additional items allowed
}
// Accepts: ["hello", 42, true]
// Rejects: ["hello", 42, true, "extra"]
// Mixed array (allow strings or numbers)
{
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "type": "number" }
]
}
}
// Accepts: ["hello", 42, "world", 3.14]
// Rejects: ["hello", true] (boolean not allowed)
// Array of objects (common API pattern)
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
}
}Composition: allOf, anyOf, oneOf, not
Composition keywords let you combine schemas using logical operators. This is how you model inheritance, polymorphism, and complex validation rules that cannot be expressed with simple property definitions.
| Keyword | Logic | Use Case |
|---|---|---|
| allOf | AND -- must match all schemas | Inheritance, combining constraints |
| anyOf | OR -- must match at least one | Multiple acceptable formats |
| oneOf | XOR -- must match exactly one | Discriminated unions, polymorphism |
| not | NOT -- must not match | Exclusion, blacklisting values |
// allOf: extend a base schema
{
"allOf": [
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"createdAt": { "type": "string", "format": "date-time" }
},
"required": ["id", "createdAt"]
},
{
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
]
}
// Result: object must have id, createdAt, name, AND email
// oneOf: discriminated union (API event types)
{
"oneOf": [
{
"type": "object",
"properties": {
"type": { "const": "user.created" },
"data": {
"type": "object",
"properties": { "userId": { "type": "integer" } },
"required": ["userId"]
}
},
"required": ["type", "data"]
},
{
"type": "object",
"properties": {
"type": { "const": "order.completed" },
"data": {
"type": "object",
"properties": { "orderId": { "type": "string" } },
"required": ["orderId"]
}
},
"required": ["type", "data"]
}
]
}additionalProperties vs unevaluatedProperties
additionalProperties: false is fine for simple objects, but it can surprise you when you compose schemas with allOf or oneOf. Draft 2019-09 and 2020-12 added unevaluatedProperties, which can account for properties already evaluated by subschemas.
// Good Draft 2020-12 pattern for composed strict objects
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"allOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
},
{
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" }
},
"required": ["email"]
}
],
"unevaluatedProperties": false
}
// Accepts: { "id": "u_123", "email": "[email protected]" }
// Rejects: { "id": "u_123", "email": "[email protected]", "role": "admin" }Use additionalProperties: false on a single object schema. Use unevaluatedProperties: false when a schema is assembled from multiple subschemas and you still want a closed object.
Conditional Schemas: if / then / else
Conditional schemas let you apply different validation rules based on the data itself. This is extremely useful for forms and API payloads where the required fields depend on a type or mode selection.
// If paymentMethod is "credit_card", require cardNumber and cvv
// If paymentMethod is "bank_transfer", require accountNumber and routingNumber
{
"type": "object",
"properties": {
"paymentMethod": { "type": "string", "enum": ["credit_card", "bank_transfer"] },
"amount": { "type": "number", "minimum": 0.01 }
},
"required": ["paymentMethod", "amount"],
"if": {
"properties": { "paymentMethod": { "const": "credit_card" } }
},
"then": {
"properties": {
"cardNumber": { "type": "string", "pattern": "^[0-9]{16}$" },
"cvv": { "type": "string", "pattern": "^[0-9]{3,4}$" }
},
"required": ["cardNumber", "cvv"]
},
"else": {
"properties": {
"accountNumber": { "type": "string" },
"routingNumber": { "type": "string", "pattern": "^[0-9]{9}$" }
},
"required": ["accountNumber", "routingNumber"]
}
}
// Valid credit card payment:
{ "paymentMethod": "credit_card", "amount": 99.99, "cardNumber": "4111111111111111", "cvv": "123" }
// Valid bank transfer:
{ "paymentMethod": "bank_transfer", "amount": 500, "accountNumber": "12345678", "routingNumber": "021000021" }
// Invalid (credit card selected but missing cvv):
{ "paymentMethod": "credit_card", "amount": 99.99, "cardNumber": "4111111111111111" }Reusable Schemas with $ref and $defs
Real-world schemas share definitions across endpoints. The $defs keyword (formerly definitions in Draft-07) stores reusable schemas, and $ref references them. This keeps your schemas DRY and maintainable.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string", "pattern": "^[A-Z]{2}$" },
"zip": { "type": "string", "pattern": "^[0-9]{5}(-[0-9]{4})?$" }
},
"required": ["street", "city", "state", "zip"]
},
"phone": {
"type": "string",
"pattern": "^\\+?[1-9]\\d{6,14}$"
}
},
"type": "object",
"properties": {
"name": { "type": "string" },
"homeAddress": { "$ref": "#/$defs/address" },
"workAddress": { "$ref": "#/$defs/address" },
"phone": { "$ref": "#/$defs/phone" }
},
"required": ["name", "homeAddress"]
}
// Both homeAddress and workAddress validate against the same schema
// Changes to the address definition automatically apply everywhereFor schemas that span multiple files, you can use absolute or relative URIs in $ref. For example, {"$ref": "./address.schema.json"} references a separate file. When working with complex JSON structures, use our JSON Path Tester to navigate and extract data from deeply nested documents.
Validation in JavaScript with Ajv
Ajv (Another JSON Schema Validator) is the standard JSON Schema validator for JavaScript and TypeScript projects. It compiles schemas into reusable validation functions. For Draft 2020-12, import the 2020 entry point and add formats explicitly when you need email, URI, date-time, UUID, or IP address checks.
// Installation
// npm install ajv ajv-formats
import Ajv2020 from 'ajv/dist/2020';
import addFormats from 'ajv-formats';
const ajv = new Ajv2020({ allErrors: true, strict: true });
addFormats(ajv); // adds "email", "uri", "date-time", etc.
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'integer', minimum: 0 },
},
required: ['name', 'email'],
additionalProperties: false,
};
const validate = ajv.compile(schema);
// Valid data
const valid = validate({ name: 'Alice', email: '[email protected]', age: 30 });
console.log(valid); // true
// Invalid data
const invalid = validate({ email: 'not-an-email' });
console.log(invalid); // false
console.log(validate.errors);
// [
// { keyword: 'required', params: { missingProperty: 'name' } },
// { keyword: 'format', params: { format: 'email' } }
// ]
// Express.js middleware example
function validateBody(schema) {
const validate = ajv.compile(schema);
return (req, res, next) => {
if (!validate(req.body)) {
return res.status(400).json({
error: 'Validation failed',
details: validate.errors,
});
}
next();
};
}
app.post('/api/users', validateBody(schema), (req, res) => {
// req.body is guaranteed to be valid here
});Validation in Python with jsonschema
# pip install jsonschema[format]
from jsonschema import validate, ValidationError, Draft202012Validator
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"tags": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": True
}
},
"required": ["name", "email"],
"additionalProperties": False
}
# Simple validation (raises on first error)
try:
validate(instance={"name": "", "email": "bad"}, schema=schema)
except ValidationError as e:
print(f"Error: {e.message}")
# Error: '' is too short
# Collect all errors
validator = Draft202012Validator(schema)
errors = list(validator.iter_errors({"email": 123}))
for error in errors:
print(f"{error.json_path}: {error.message}")
# $.name: 'name' is a required property
# $.email: 123 is not of type 'string'
# FastAPI integration (uses JSON Schema internally)
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
name: str
email: EmailStr
tags: list[str] = []
# Pydantic generates JSON Schema automatically:
print(UserCreate.model_json_schema())Validation in Go with gojsonschema
// go get github.com/xeipuuv/gojsonschema
package main
import (
"fmt"
"github.com/xeipuuv/gojsonschema"
)
func main() {
schema := gojsonschema.NewStringLoader(`{
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "email"],
"additionalProperties": false
}`)
document := gojsonschema.NewStringLoader(`{
"name": "Alice",
"email": "[email protected]"
}`)
result, err := gojsonschema.Validate(schema, document)
if err != nil {
panic(err)
}
if result.Valid() {
fmt.Println("Document is valid")
} else {
for _, err := range result.Errors() {
fmt.Printf("- %s\n", err)
}
}
}Real-World Schema: REST API Response
Here is a complete schema for a paginated API response -- the kind you would use to validate responses from a REST API.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"user": {
"type": "object",
"properties": {
"id": { "type": "integer", "minimum": 1 },
"username": { "type": "string", "minLength": 3, "maxLength": 30 },
"email": { "type": "string", "format": "email" },
"role": { "type": "string", "enum": ["admin", "editor", "viewer"] },
"createdAt": { "type": "string", "format": "date-time" },
"profile": {
"type": "object",
"properties": {
"displayName": { "type": "string" },
"bio": { "type": ["string", "null"], "maxLength": 500 },
"avatarUrl": { "type": ["string", "null"], "format": "uri" }
},
"required": ["displayName"]
}
},
"required": ["id", "username", "email", "role", "createdAt"]
},
"pagination": {
"type": "object",
"properties": {
"page": { "type": "integer", "minimum": 1 },
"perPage": { "type": "integer", "minimum": 1, "maximum": 100 },
"total": { "type": "integer", "minimum": 0 },
"totalPages": { "type": "integer", "minimum": 0 }
},
"required": ["page", "perPage", "total", "totalPages"]
}
},
"type": "object",
"properties": {
"data": {
"type": "array",
"items": { "$ref": "#/$defs/user" }
},
"pagination": { "$ref": "#/$defs/pagination" }
},
"required": ["data", "pagination"]
}This schema validates the entire response structure including nested user profiles and pagination metadata. For designing APIs with correct status codes, check our API Response Codes Best Practices guide and the HTTP Status Codes reference.
Schema Generation from TypeScript
If you already have TypeScript interfaces, you can generate JSON Schema automatically instead of writing it by hand. This keeps your types and validation in sync.
// Install: npm install typescript-json-schema -D
// Define your TypeScript interface
interface User {
/** @minimum 1 */
id: number;
/** @minLength 3 @maxLength 30 */
username: string;
/** @format email */
email: string;
role: 'admin' | 'editor' | 'viewer';
/** @format date-time */
createdAt: string;
}
// Generate schema from CLI:
// npx typescript-json-schema tsconfig.json User --required --strictNullChecks
// Or use Zod (runtime validation + schema generation):
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';
const userSchema = z.object({
id: z.number().int().min(1),
username: z.string().min(3).max(30),
email: z.string().email(),
role: z.enum(['admin', 'editor', 'viewer']),
createdAt: z.string().datetime(),
});
const jsonSchema = zodToJsonSchema(userSchema);
console.log(JSON.stringify(jsonSchema, null, 2));Need to convert JSON data to TypeScript types first? Our JSON to TypeScript converter generates accurate type definitions from any JSON payload. For converting between JSON and other formats, see our JSON to YAML and JSON to XML converters.
Common Mistakes and Best Practices
- Forgetting additionalProperties -- By default, objects allow any extra fields. Set
additionalProperties: falseto catch typos and unexpected data in API requests. - Using additionalProperties inside the wrong composed schema -- When
allOforoneOfsplits object properties across subschemas, prefer Draft 2020-12unevaluatedProperties: falseat the combined level. - Not enabling format validation -- The
formatkeyword is an annotation by default in most validators. In Ajv, installajv-formatsand calladdFormats(ajv). In jsonschema (Python), install withpip install jsonschema[format]. - Using oneOf when anyOf works --
oneOfrequires exactly one match. If schemas overlap, validation fails even though the data is valid. UseanyOfunless you specifically need exclusive matching. - Overly strict patterns -- Regex patterns in schemas should validate structure, not content. A pattern like
^[A-Z][a-z]+$for names rejects valid names like "O'Brien" or "McDonald". - Not using $defs for repeated structures -- Duplicating schemas leads to inconsistencies when you update one copy but forget the others. Extract shared definitions into
$defsand reference them with$ref. - Leaving empty schemas as placeholders --
{}accepts any value. That is useful for intentional extension points, but dangerous if you meant to validate the field later. - Ignoring error messages -- Default validation errors are technical. Map them to user-friendly messages in your API layer, especially for form validation.
Draft Version Comparison
| Feature | Draft-07 | 2019-09 | 2020-12 |
|---|---|---|---|
| if/then/else | Yes | Yes | Yes |
| $defs (was definitions) | definitions | $defs | $defs |
| prefixItems (tuples) | No | No | Yes |
| dependentRequired | No | Yes | Yes |
| $dynamicRef | No | No | Yes |
| unevaluatedProperties | No | Yes | Yes |
Frequently Asked Questions
Is an empty JSON Schema valid and what does it match?
Yes. An empty JSON Schema object {} is valid and matches any JSON value because it contains no assertion keywords. It has the same assertion behavior as the boolean schema true. The boolean schema false rejects every value.
What are JSON Schema validation best practices?
Use Draft 2020-12 for new schemas, declare $schema, compile validators once at startup, validate untrusted API and configuration input, enable format validation deliberately, use $defs for repeated structures, and choose additionalProperties or unevaluatedProperties based on whether the object is simple or composed.
What is JSON Schema and why should I use it?
JSON Schema is a declarative language for describing the structure and constraints of JSON data. It defines allowed types, required fields, string formats, and nested structures. Use it to validate API payloads, configuration files, form data, and any JSON crossing trust boundaries. It prevents invalid data from entering your system and serves as living documentation for data contracts. The same schema works across all programming languages.
Which JSON Schema draft version should I use?
Use Draft 2020-12 for new projects. It is the latest stable specification supported by major validators including Ajv, jsonschema, and gojsonschema. It introduced prefixItems for tuples and replaced definitions with $defs. If maintaining existing schemas, Draft-07 remains widely supported and perfectly adequate for most use cases.
Can JSON Schema validate nested objects and arrays?
Yes, JSON Schema validates deeply nested structures. Use properties for object fields, items for array elements, and additionalProperties to control extra fields. Nest schemas to any depth, use $ref for shared definitions, and apply conditional validation with if/then/else. Arrays support minItems, maxItems, uniqueItems, and prefixItems for tuple-style validation.
Validate JSON Against a Schema
Paste your JSON and schema into BytePane's browser-based validator to check Draft 2020-12 rules, format assertions, empty schemas, and detailed error paths.
Open JSON Schema ValidatorRelated Articles
JSON Formatting Guide
Learn proper JSON indentation, validation, and common syntax errors.
JSON vs YAML vs XML
Compare data formats: pros, cons, readability, and ecosystem support.
API Response Codes Best Practices
HTTP status codes for REST APIs: 4xx vs 5xx, error formats, and patterns.
Regex Patterns Cheat Sheet
30+ copy-paste regex patterns for validation and data extraction.