JSON Naming Conventions and Best Practices for APIs

There is no official JSON style guide, but there are strong community conventions that make APIs predictable, maintainable, and pleasant to work with. Here are the most important ones.

Key naming: camelCase vs snake_case

The biggest debate in JSON API design. Both are widely used:

// camelCase — most common in JavaScript-centric APIs (GitHub, Twitter, Stripe)
{
  "userId": 42,
  "firstName": "Alice",
  "createdAt": "2026-05-04T10:00:00Z"
}

// snake_case — common in Python-based APIs (Django REST Framework defaults)
{
  "user_id": 42,
  "first_name": "Alice",
  "created_at": "2026-05-04T10:00:00Z"
}

Recommendation: Use camelCase for JSON APIs. It matches JavaScript variable naming natively, so JavaScript clients don't need to transform keys. If your backend is Python, use a serialization library that converts snake_case to camelCase at the API boundary (e.g., humps, Django REST Framework with a custom renderer).

Whatever you choose, be consistent. A mix of camelCase and snake_case in the same response is the worst outcome.

Always use double quotes

This is required by the JSON spec, not just a convention. Single quotes cause a parse error. Every key and every string value must use double quotes.

// Valid
{ "status": "active" }

// Invalid — will not parse
{ 'status': 'active' }

Use null for absent values — don't omit keys

When a value is not available, include the key with a null value rather than leaving the key out entirely:

// Preferred — consistent shape
{
  "userId": 42,
  "middleName": null,
  "phoneNumber": null
}

// Avoid — clients must check both "key missing" and "key is null"
{
  "userId": 42
}

Consistent key presence makes client-side code simpler. Consumers can access data.middleName safely and get null without first checking if the key exists.

Use ISO 8601 for dates and timestamps

ISO 8601 is unambiguous, sortable, and parseable in every major language:

{
  "createdAt": "2026-05-04T14:30:00Z",       // UTC timestamp
  "updatedAt": "2026-05-04T14:30:00+05:30",  // with timezone offset
  "birthDate": "1995-08-22"                   // date only
}

Avoid Unix timestamps as strings ("created": "1746360600") — they're unreadable without conversion. Unix timestamps as numbers are acceptable for high-frequency logging where every byte counts, but name the field clearly (createdAtTimestamp). For the full breakdown — the ISO 8601 grammar, JavaScript and Python serialization, timezone handling, and the seconds-vs-milliseconds trap — see the JSON date format guide.

Use arrays for ordered collections — not numbered keys

A common anti-pattern is using numbered keys to simulate an ordered list:

// Anti-pattern — don't do this
{
  "item_0": { "name": "Widget A" },
  "item_1": { "name": "Widget B" },
  "item_2": { "name": "Widget C" }
}

// Correct — use an array
{
  "items": [
    { "name": "Widget A" },
    { "name": "Widget B" },
    { "name": "Widget C" }
  ]
}

Arrays maintain order, have a length property, and can be iterated with standard array methods. Numbered object keys do none of this.

Avoid deeply nested structures

Nesting beyond 3-4 levels makes JSON hard to read and hard to access programmatically. If you find yourself writing data.response.user.profile.address.city, consider flattening:

// Overly nested
{
  "response": {
    "user": {
      "profile": {
        "address": { "city": "London" }
      }
    }
  }
}

// Flatter — easier to work with
{
  "user": {
    "city": "London"
  }
}

Pagination conventions

When returning paginated lists, include metadata that clients need to navigate pages:

{
  "data": [ ... ],
  "pagination": {
    "page": 2,
    "perPage": 20,
    "total": 157,
    "totalPages": 8,
    "nextPage": 3,
    "prevPage": 1
  }
}

Alternatively, use cursor-based pagination for large or real-time datasets:

{
  "data": [ ... ],
  "cursor": {
    "next": "eyJpZCI6MTAwfQ",
    "hasMore": true
  }
}

Validate your JSON structure

Use the JSON Validator to confirm your API responses are syntactically valid. For structural validation — ensuring required fields are present and have the correct types — consider JSON Schema validation. The JSON Formatter makes it easy to visually inspect complex nested responses.

Try it directly in your browser — free, no signup:

Open JSON Formatter →

Frequently Asked Questions

Should JSON keys use camelCase or snake_case?

camelCase is the most common convention for JSON APIs, especially those designed for JavaScript clients, since it matches JavaScript variable naming (no underscore needed). snake_case is common in Python-based APIs. The most important rule is consistency — pick one and use it everywhere in your API.

How should I represent dates in JSON?

Use ISO 8601 format: '2026-05-04T14:30:00Z' for a UTC timestamp or '2026-05-04' for a date without time. This format is unambiguous, lexicographically sortable, and parseable by Date.parse() in JavaScript and datetime.fromisoformat() in Python. Avoid Unix timestamps as strings — they're unreadable without conversion.

Should I use null or omit the key when a value is absent?

Include the key with a null value rather than omitting it entirely. This makes your API response shape predictable — consumers can always access the key without checking whether it exists. Omitting keys makes API responses inconsistent and forces clients to handle both the missing-key case and the null case separately.

About the author

Pasindu Ishan is a Senior Software Engineer working on data streaming systems. These guides are about writing JSON that other people’s parsers will accept, including the parts of the format that are stricter than they look. He builds the free in-browser tools at JSON Dev Tools.