ForHosting KIT · Data & Files

JSON object diff

Put the old and new version of a data record side by side and get the real differences sorted out: in the example, 2 additions, 1 removal and 2 changes, 5 in total, while spacing and key order are ignored. Free in your browser.

  • Free
  • Runs in your browser
  • No sign-up
  • Your data stays on your device
Use it from WebAPIEmailTelegramApp soon

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

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.

How to read the list of differences

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.

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. 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.

Using the diff in reviews and automation

Send the original object in before and the proposed object in after. 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. 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.

Review configuration releases

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

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?

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?

A top-level array or primitive produces an invalid-input error.

Does a change deep inside a section show up on its own?

Yes. When both versions contain the same section, the comparison goes inside it and points to the deepest entry that differs. In the example only active changed inside profile, so the result names /profile/active rather than the whole profile.

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.

A text diff can make a small JSON update look noisy because indentation, key order, and unrelated formatting changes distract from the data itself. 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.

Reading a structural JSON diff

Each entry uses a JSON Pointer path beginning with a slash.

How nested objects and arrays are handled

Arrays are treated as ordered JSON values rather than as objects keyed by index. 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

The browser tool can run locally for quick inspection, while an API request costs $0.002 and returns the same deterministic structure for automation. Consumers should match paths as JSON Pointers rather than splitting them naively on slashes, since escaped characters have defined meanings. 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.

Audit webhook payload evolution

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

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.

Read the full KIT documentation →