← Back to DominateTools
BEST PRACTICES

The JSON Best Practices Guide (2026 Edition)

The difference between amateur and production-quality JSON is in the details. Discover the rigorous standards for naming conventions, data modeling, secure envelopes, strict type checking, and optimization strategies that power enterprise APIs.

Updated March 2026 · 22 min read

Table of Contents

Writing valid JSON is easy. Writing good JSON — consistent, predictable, performant, and secure — requires deliberate choices about naming conventions, data modeling, error representation, and serialization strategies. These choices compound across an entire API surface: a well-designed JSON schema makes client code simple and robust, while a poorly designed one creates a constant stream of parsing bugs, type mismatches, and integration headaches.

The best practices in this guide are distilled from analyzing hundreds of production APIs (including Google, GitHub, Stripe, Twilio, and the OpenAPI ecosystem), reviewing common failure patterns in JSON-based systems, and synthesizing the recommendations of RFC 8259 (the JSON specification), RFC 7807 (Problem Details for HTTP APIs), and the JSON:API specification. Each practice is accompanied by concrete code examples showing both the recommended approach and the anti-patterns to avoid.

Whether you're designing a new API, refactoring an existing one, or reviewing code that produces or consumes JSON, these sixteen practices will help you build more reliable, maintainable, and performant systems. Use our JSON Formatter to validate and inspect your JSON as you apply these recommendations.

Validate Your JSON Design

Our free JSON Formatter validates structure, highlights issues, and beautifies output — perfect for reviewing API responses.

Open JSON Formatter →

1. Naming Conventions

Consistent key naming is the foundation of a usable API. Inconsistent naming — mixing camelCase and snake_case, or using different names for the same concept across endpoints — forces consumers to maintain mental mappings and increases the likelihood of bugs.

Convention Example Used By Best When
camelCase firstName, createdAt Google, Twitter JavaScript/TypeScript ecosystems
snake_case first_name, created_at GitHub, Stripe Python/Ruby ecosystems
kebab-case first-name Rare in JSON Avoid in JSON (not valid unquoted in JS)
PascalCase FirstName .NET APIs C#/.NET ecosystems only
The #1 Rule Pick one naming convention and use it everywhere, without exception. Consistency matters far more than which convention you choose.

2. Date and Time Representation

Dates are one of the most common sources of JSON interoperability bugs. Always use ISO 8601 format with explicit timezone information:

// ✅ Good: ISO 8601 with timezone { "createdAt": "2026-03-11T16:00:00Z", "updatedAt": "2026-03-11T21:30:00+05:30", "expiresAt": "2026-12-31T23:59:59Z" } // ❌ Bad: Ambiguous formats { "createdAt": "03/11/2026", // US format? EU format? "updatedAt": 1741708200, // Seconds or milliseconds? "expiresAt": "Dec 31, 2026" // Locale-specific }

3. Null vs Absent Fields

Distinguish between "this field has no value" (null) and "this field does not apply" (absent). Each has different semantics that consumers need to understand:

// User has no middle name (field present, value is null) { "firstName": "Alice", "middleName": null, "lastName": "Chen" } // User profile without optional bio (field absent) { "firstName": "Alice", "lastName": "Chen" // bio field not included — not applicable }

For PATCH (partial update) operations, this distinction is critical: sending "middleName": null means "clear this field," while omitting the field means "don't change it."

4. Error Response Structure

Use a consistent, structured error format across your entire API. The RFC 7807 "Problem Details" format is a well-established standard:

// ✅ Good: Structured error with actionable information { "type": "https://api.example.com/errors/validation", "title": "Validation Error", "status": 422, "detail": "The request body contains invalid fields.", "errors": [ { "field": "email", "code": "INVALID_FORMAT", "message": "Must be a valid email address" }, { "field": "age", "code": "OUT_OF_RANGE", "message": "Must be between 0 and 150" } ] } // ❌ Bad: Vague string error { "error": "Something went wrong" }

5. Pagination

For endpoints that return collections, always implement pagination. The two most common approaches are offset-based (simple, supports jumping to any page) and cursor-based (performant, handles real-time data insertion):

Approach Pros Cons Best For
Offset-based Simple, supports page jumping Slow on large datasets, skips/duplicates on inserts Admin dashboards, static data
Cursor-based Fast, handles real-time inserts Can't jump to page N Feeds, timelines, large datasets

6. Envelope vs Raw Responses

Wrapping responses in an envelope object provides a consistent structure for metadata, pagination, and error handling. This is especially useful when your API needs to communicate information beyond the primary data:

// Envelope pattern — consistent structure across all endpoints { "data": { "id": "user_123", "name": "Alice", "email": "alice@example.com" }, "meta": { "requestId": "req_abc123", "timestamp": "2026-03-11T16:00:00Z" } } // Collection with pagination { "data": [ { "id": "user_1", "name": "Alice" }, { "id": "user_2", "name": "Bob" } ], "pagination": { "page": 1, "perPage": 20, "total": 150, "hasMore": true } }

7. Number Handling and Precision Loss

JSON numbers follow IEEE 754 double-precision floating point. This means integers larger than 2^53 (9,007,199,254,740,992) lose precision, and decimal arithmetic has floating-point rounding issues:

// ❌ Problem: Large IDs lose precision { "id": 9007199254740993 } // Parsed as 9007199254740992! // ✅ Solution: Use string IDs for large numbers or UUIDs { "id": "9007199254740993" } // ❌ Problem: Monetary amounts with floating-point errors { "price": 19.99 } // Could become 19.990000000000002 // ✅ Solution: Use integer cents (or string) { "priceInCents": 1999 } { "price": "19.99" }

8. Flattenting Deeply Nested Structures

Deeply nested JSON leads to massive payload sizes, complicated client-side mapping (especially in strictly typed languages like Java or Go), and parser performance degradation. Instead of embedding full child objects within parent objects, practice data normalization using explicit references.

// ❌ Bad: Deep nesting (hard to parse, high duplication) { "post_id": "123", "title": "JSON Practices", "author": { "user_id": "99", "name": "Alice", "company": { "company_id": "88", "name": "Acme Corp" } } } // ✅ Good: Normalized references (flat, fast to parse) { "post_id": "123", "title": "JSON Practices", "author_id": "99" }

If the client needs the author or company data, they can either make a separate request or use a GraphQL-style inclusion parameter (?include=author) to return a flattened dictionary of side-loaded entities.

9. Preventing JSON Hijacking

JSON Hijacking is an old but still relevant security vulnerability where a malicious site uses a <script> tag to GET an array-based JSON endpoint, overriding the native Array constructor to steal the data.

Modern browsers have mitigated this, but best practice dictates you should never return a raw JSON array at the root level of an authenticated GET request.

// ❌ Vulnerable to Hijacking (Raw Array) [ { "secret": "token_123" }, { "secret": "token_456" } ] // ✅ Secure (Wrapped in an Object Envelope) { "data": [ { "secret": "token_123" }, { "secret": "token_456" } ] }

10. Strict Content-Type Headers

Always transmit JSON with the exact header Content-Type: application/json; charset=utf-8. Never use text/plain or text/html. If you serve JSON with a text/html header, and user input is reflected in the JSON, a browser might attempt to execute the payload as HTML if accessed directly, leading to Cross-Site Scripting (XSS) vulnerabilities.

Furthermore, explicitly instruct browsers not to sniff the content type by sending the X-Content-Type-Options: nosniff header on every API response.

11. Dealing with Enums and State

When an API returns a state or category, never use arbitrary integer codes unless absolutely necessary for micro-optimization. Use explicit, uppercase string enums. They are self-documenting and easier to debug.

// ❌ Bad: Magic Numbers (What does 2 mean?) { "orderId": "123", "status": 2 } // ✅ Good: String Enums (Self-documenting) { "orderId": "123", "status": "PROCESSING" }

12. Robust Client-Side Parsing

JSON parsing must always be treated as a potentially fatal operation. Never trust that an API (even internal ones) will return valid JSON or respect the expected schema. A network error, proxy timeout, or upstream crash often results in an HTML error page being returned instead of JSON.

Always wrap your `JSON.parse` operations in try-catch blocks, or rely on robust fetching libraries (like Axios) that handle the parsing and error throwing automatically.

13. Performance Optimization

JSON payloads can become significant performance bottlenecks as applications scale. Here are the key techniques for keeping JSON fast:

Minimize payload size: Only include fields that the client actually needs. Use sparse fieldsets (?fields=name,email) or GraphQL to let clients specify required fields. Exclude computed or rarely-used fields from default responses.

Enable compression: Gzip compression reduces JSON payload size by 70-90% for transmission. Most web servers and CDNs support automatic compression. Always set Accept-Encoding: gzip in API requests.

Use streaming for large data: For files over 100 MB, use streaming JSON parsers (like JSONStream in Node.js or ijson in Python) instead of JSON.parse(), which loads the entire document into memory.

14. API Versioning

When your JSON response structure needs to change in ways that break existing clients, use API versioning. The three common approaches:

Method Example Pros Cons
URL path /v1/users, /v2/users Obvious, easy to implement URL duplication
Header Accept: application/vnd.api+json;v=2 Clean URLs Harder to test in browser
Query param /users?version=2 Easy to test Can conflict with other params

Format & Validate Your API JSON

Review your API response quality — paste any JSON into our formatter for instant structure analysis.

Open JSON Formatter →

Frequently Asked Questions

What naming convention should I use for JSON keys?
Use camelCase for JavaScript ecosystems or snake_case for Python/Ruby. The #1 rule: pick one and be 100% consistent across your entire API. Never mix conventions.
Should I use null or omit missing fields in JSON?
Use null when a field is known but empty (e.g., no middle name). Omit the field when it doesn't apply. For PATCH operations: null = "clear this field," absent = "don't change it."
How should I represent dates in JSON?
Always ISO 8601 with timezone: "2026-03-11T16:00:00Z". Never Unix timestamps (seconds vs milliseconds ambiguity), locale-specific formats ("03/11/2026"), or partial formats.
How do I handle errors in JSON API responses?
Use structured error objects with: HTTP status code, machine-readable code ("VALIDATION_ERROR"), human message, and field-level details array. Follow RFC 7807 for standardized format. Never return 200 with error in body.
How can I improve JSON parsing performance?
Include only needed fields (sparse fieldsets). Enable gzip/brotli (70-90% reduction). Use streaming parsers for large files. Avoid nesting beyond 3-4 levels. Use NDJSON for large datasets. Always validate before parsing.

Related Resources