AllJSONTools

Free JSON Developer Tools

JSON API Best Practices: The Complete Guide for 2026

2026-02-26 · 14 min read · By AllJSONTools

API
Best Practices
REST
Having JSON issues?

Paste broken JSON and fix it instantly with AI — plain-English explanations included.

Fix JSON with AI

Why JSON API Design Matters

JSON is the default data format for web APIs. A well-designed JSON API is easy to consume, predictable, and forgiving of client mistakes. A poorly designed one creates bugs, support tickets, and breaking changes that ripple across every consumer. These best practices help you build APIs that developers actually enjoy using.

1. Use a Consistent Response Envelope

Every API response should follow the same top-level shape. This lets clients write generic error handling and parsing logic instead of special-casing each endpoint.

json
{
  "success": true,
  "data": {
    "id": 42,
    "name": "Jane Doe",
    "email": "jane@example.com"
  },
  "meta": {
    "requestId": "req_abc123",
    "timestamp": "2026-02-25T10:30:00Z"
  }
}

For errors, use the same envelope with an error object instead of data:

json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email is required",
    "details": [
      { "field": "email", "message": "must not be empty" }
    ]
  },
  "meta": {
    "requestId": "req_def456",
    "timestamp": "2026-02-25T10:30:01Z"
  }
}

Use the JSON Formatter to inspect and prettify API responses while developing.

2. Use camelCase for Keys

JavaScript is the primary consumer of most JSON APIs, and JavaScript uses camelCase natively. Avoid snake_case, PascalCase, or kebab-case in JSON keys — they force clients to transform every response before using it.

json
// Good
{ "firstName": "Jane", "lastName": "Doe", "createdAt": "2026-01-15" }

// Avoid
{ "first_name": "Jane", "last_name": "Doe", "created_at": "2026-01-15" }

Whatever convention you pick, be consistent across your entire API. Mixing conventions is worse than picking the “wrong” one.

3. Paginate List Endpoints

Never return unbounded arrays. Even if your collection is small today, it will grow. Use cursor-based or offset-based pagination from day one.

json
{
  "success": true,
  "data": [
    { "id": 1, "name": "Widget A" },
    { "id": 2, "name": "Widget B" }
  ],
  "pagination": {
    "page": 1,
    "perPage": 20,
    "total": 87,
    "totalPages": 5,
    "nextPage": "/api/widgets?page=2&perPage=20"
  }
}

For high-throughput APIs, prefer cursor-based pagination (using an opaque token) over offset-based. It handles real-time inserts and deletes without skipping or duplicating records.

4. Use Correct HTTP Status Codes

Don’t return 200 OK with an error message in the body. Use HTTP status codes correctly:

  • 200 — Success (GET, PUT, PATCH)

  • 201 — Created (POST that creates a resource)

  • 204 — No Content (successful DELETE)

  • 400 — Bad Request (validation errors, malformed JSON)

  • 401 — Unauthorized (missing or invalid auth)

  • 404 — Not Found

  • 422 — Unprocessable Entity (valid JSON but semantic errors)

  • 429 — Too Many Requests (rate limiting)

  • 500 — Internal Server Error

5. Use ISO 8601 for Dates

Always return dates in ISO 8601 format with a timezone. Unix timestamps are ambiguous (seconds? milliseconds?) and locale-formatted strings are unparseable.

json
// Good — unambiguous, parseable everywhere
{ "createdAt": "2026-02-25T10:30:00Z" }

// Bad — is this seconds or milliseconds?
{ "createdAt": 1772130600 }

// Bad — locale-dependent, unparseable
{ "createdAt": "Feb 25, 2026 10:30 AM" }

6. Be Deliberate About Null vs. Absent Fields

There is a semantic difference between a field being null and being absent. Use null to mean “this field exists but has no value” and omit the field entirely to mean “this field doesn’t apply here.”

json
// User has no phone number set
{ "name": "Jane", "phone": null }

// Phone field doesn't exist for this resource type
{ "name": "Jane" }

Document this convention clearly. Use the JSON Schema Generator to create schemas that explicitly define which fields are required, optional, or nullable.

7. Version Your API

APIs evolve. When you need to make breaking changes, version your API so existing clients don’t break. The most common approach is URL path versioning:

bash
GET /api/v1/users/42
GET /api/v2/users/42

Alternatively, use a header like Accept: application/vnd.myapi.v2+json. URL versioning is simpler and more discoverable, so prefer it unless you have a strong reason not to.

8. Support Filtering, Sorting, and Field Selection

Don’t force clients to download everything and filter client-side. Provide query parameters for common operations:

bash
# Filter by status
GET /api/v1/orders?status=shipped

# Sort by date descending
GET /api/v1/orders?sort=-createdAt

# Select specific fields only
GET /api/v1/orders?fields=id,status,total

# Combine them
GET /api/v1/orders?status=shipped&sort=-createdAt&fields=id,total&page=2

The minus prefix for descending sort ( -createdAt) is a common convention. Document your filtering syntax clearly.

9. Communicate Rate Limits

Include rate limit information in response headers so clients can throttle proactively instead of getting slammed with 429 errors:

bash
HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1772131200

When a client does hit the limit, return a 429 status with a Retry-After header telling them when to try again.

10. Validate with JSON Schema

Don’t write validation logic by hand for every endpoint. Define a JSON Schema for each request body and validate incoming payloads against it. This gives you:

  • Automatic, consistent error messages

  • A machine-readable contract between client and server

  • Auto-generated documentation

  • Type safety when combined with code generators

Use the AllJSONTools JSON Schema Validator to test your schemas against sample payloads, and the Schema Generator to bootstrap schemas from existing API responses.

11. Security Essentials

JSON APIs are a common attack surface. Follow these rules:

  • Always use HTTPS — Never send credentials or tokens over plain HTTP.

  • Validate all input — Reject unexpected fields, enforce types, set maximum lengths.

  • Don’t expose internal IDs — Use UUIDs or slugs instead of auto-incrementing database IDs.

  • Set proper CORS headers — Don’t use Access-Control-Allow-Origin: * in production.

  • Use short-lived JWTs — See our JWT Security Guide for token best practices. Decode and inspect tokens with the JWT Decoder.

12. Make APIs Easy to Debug

Include a unique requestId in every response. When a client reports an issue, you can trace it through your logs instantly. Also return meaningful error messages — “Something went wrong” helps nobody.

When debugging API responses during development, paste them into the JSON Formatter to prettify and validate, use the Tree Viewer to navigate deeply nested structures, or run JSON Diff to compare expected vs actual responses.

Quick Reference Checklist

  1. Consistent response envelope (success/error + meta)

  2. camelCase keys everywhere

  3. Paginate all list endpoints

  4. Correct HTTP status codes

  5. ISO 8601 dates with timezone

  6. Deliberate null vs. absent fields

  7. URL-based API versioning

  8. Filtering, sorting, field selection

  9. Rate limit headers on every response

  10. JSON Schema validation

  11. HTTPS, input validation, proper CORS

  12. Request IDs and meaningful error messages

Having JSON issues?

Paste broken JSON and fix it instantly with AI — plain-English explanations included.

Fix JSON with AI