ForHosting KIT · Data & Files

JSON object diff

A text diff can make a small JSON update look noisy because indentation, key order, and unrelated formatting changes distract from the data itself.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

Runs in your browser. Free, unlimited — your data never leaves this page.

This JSON object diff compares parsed values instead. It reports added, removed, and changed keys in separate lists, follows shared objects into nested properties, and gives every result an unambiguous JSON Pointer path. Arrays remain ordered values and are compared as complete units. The operation is deterministic, requires no network access, and rejects arrays, primitives, or null when either top-level input must be an object.

Reading a structural JSON diff

The result separates differences into added, removed, and changed collections. An added entry is a key that exists only in the updated object, while a removed entry is a key found only in the original. A changed entry exists on both sides but has a different value, so it includes both the before and after values. Each entry uses a JSON Pointer path beginning with a slash. For example, /profile/name identifies the name property inside profile. Pointer escaping keeps unusual property names precise: a slash inside a key becomes ~1 and a tilde becomes ~0. This is safer than dot notation because a literal key named profile.name cannot be confused with a nested name property. Results are sorted by property name during traversal, making repeated calls with the same logical objects stable and easy to test. The counts block summarizes each category and provides a total, which is useful when a pipeline only needs to decide whether any meaningful difference exists before inspecting details. Empty arrays in all three categories mean the two objects are structurally equal, even if their original textual formatting or object-key order differed.

How nested objects and arrays are handled

When the same key contains an object on both sides, comparison continues recursively so the output points to the deepest differing property. If profile exists in both inputs and only profile.active changes, the changed path is /profile/active rather than the broader /profile. When a key exists on only one side, the result records that key once with its complete value; it does not expand every descendant into a separate addition or removal. That choice keeps a newly inserted configuration section readable as one event. Arrays are treated as ordered JSON values rather than as objects keyed by index. Any insertion, deletion, reordering, or element update therefore produces one changed entry for the array property, with complete before and after arrays. Primitive values and null are compared directly, while objects inside arrays participate in the array comparison without creating separate indexed paths. If a property's type changes, such as an object becoming a string, that property is reported as changed. Only the two top-level values have a stricter rule: both must be non-null JSON objects, because this capability is designed specifically for object-key differences rather than general document or array comparison.

Using the diff in reviews and automation

Send the original object in before and the proposed object in after. The browser tool can run locally for quick inspection, while an API request costs $0.002 and returns the same deterministic structure for automation. A deployment check can reject changes when removed contains protected settings, a test can assert that only approved paths changed, and an audit process can store the compact difference instead of duplicating two large documents. Because formatting and key order do not create false positives, the result works well for configuration snapshots, webhook fixtures, feature flags, permissions, and normalized API responses. Consumers should match paths as JSON Pointers rather than splitting them naively on slashes, since escaped characters have defined meanings. They should also inspect the category, not only the path: removing a value and adding one elsewhere carries different operational meaning from changing an existing value. For arrays, downstream code should expect the whole array in a changed record and apply any domain-specific set or identity logic separately. Validate input before submitting when possible, but failed requests caused by a top-level array, null, string, number, or boolean return an invalid-input error rather than a misleading empty diff.

Review configuration releases

Compare the deployed configuration with a candidate release and surface only structural key changes, without whitespace or key-order noise.

Audit webhook payload evolution

Record which nested fields appeared, disappeared, or changed between two normalized webhook examples as an integration evolves.

Guard approved settings

Check diff paths in CI and stop a deployment when protected settings are removed or altered outside an approved change list.

What path format does the result use?

Every path is an RFC 6901-style JSON Pointer. Slashes in property names are escaped as ~1 and tildes as ~0.

Does object key order count as a change?

No. Objects are compared by their keys and values, so different serialization order does not produce a difference.

How are arrays compared?

Arrays are ordered values and are compared as complete units. Any element edit, insertion, deletion, or reordering marks the containing array property as changed.

Can I compare two top-level arrays?

No. Both before and after must be non-null JSON objects. A top-level array or primitive produces an invalid-input error.

How much does the API request cost?

The browser tool runs free locally. Each API request uses the published base price of $0.002, with no network or AI dependency in the comparison itself.

Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.

POSThttps://api.kit.forhosting.com/data/diff-json-objects

Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.

curl -X POST https://api.kit.forhosting.com/data/diff-json-objects \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"before":{"name":"Ada","profile":{"active":true,"score":8},"roles":["reader"]},"after":{"name":"Ada","profile":{"active":false,"score":8,"city":"London"},"roles":["reader","editor"]}}'
{
  "before": {
    "name": "Ada",
    "profile": {
      "active": true,
      "score": 8
    },
    "roles": [
      "reader"
    ]
  },
  "after": {
    "name": "Ada",
    "profile": {
      "active": false,
      "score": 8,
      "city": "London"
    },
    "roles": [
      "reader",
      "editor"
    ]
  }
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "data.diff_json_objects",
  "status": "queued",
  "_links": {
    "result": "/tasks/tsk_…/result"
  }
}

The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

max_mb25
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →