# Text and JSON Diff (`brightwater-tools/text-json-diff`) Actor

Compare two texts (unified diff with line numbers) or two JSON documents (added, removed and changed paths), with summary counts. Standard library only. No network access and no scraping.

- **URL**: https://apify.com/brightwater-tools/text-json-diff.md
- **Developed by:** [Brightwater Tools](https://apify.com/brightwater-tools) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 successful comparisons

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Text and JSON Diff

Compare two texts or two JSON documents and see what changed. Paste the original and the new versions, pick a mode, and get the result.

The comparison code makes no outside requests, reads no files and does no scraping. It works only on the two inputs you paste in. The result is saved to your run's dataset on Apify.

**$0.005 per successful comparison.** Failed runs are not charged.

### What you can do with it

- Check what changed between two versions of a config file, a spec or a list.
- Get a **unified diff with line numbers** for a code review or a ticket.
- Compare two **JSON API responses** and see which fields were added, removed or changed, with their paths (for example `$.parts[2].name`).

### How to use it

1. Choose a **mode**: `text` or `json`.
2. Paste the **original** version into `old_text` and the **new** version into `new_text`.
3. Click **Start**. The result is saved as one item in the run's dataset on Apify.

#### Mode: text

Output fields: `identical`, `old_lines`, `new_lines`, `added_lines`, `removed_lines`, `hunks` and `unified_diff`.

- The `@@ -a,b +c,d @@` headers in `unified_diff` give the starting line and the number of lines in each text.
- `context_lines` sets how many unchanged lines appear around each change (0 to 10, default 3). Use 0 to show only the changed lines.
- Lines are compared without their line endings, so a missing final newline is not counted as a change.
- An empty text counts as zero lines, so every line of the other text shows as added or removed.

Example input:

```json
{
  "mode": "text",
  "old_text": "alpha\nbeta\ngamma\n",
  "new_text": "alpha\nBETA\ngamma\ndelta\n",
  "context_lines": 3
}
```

Output (one dataset item):

```json
{
  "mode": "text",
  "identical": false,
  "old_lines": 3,
  "new_lines": 4,
  "added_lines": 2,
  "removed_lines": 1,
  "hunks": 1,
  "unified_diff": "--- old_text\n+++ new_text\n@@ -1,3 +1,4 @@\n alpha\n-beta\n+BETA\n gamma\n+delta\n"
}
```

In the diff, lines starting with `-` were removed from the old text, lines starting with `+` were added in the new text, and lines starting with a space are unchanged.

#### Mode: json

- Both inputs must be valid JSON. NaN and Infinity are refused.
- Output fields: `identical`, `added_count`, `removed_count`, `changed_count`, and the lists `added` and `removed` (each item has a `path` and a `value`) and `changed` (each item has a `path`, `old` and `new`).
- Paths start at `$`. Keys that are not plain names are quoted, for example `$["my key"]`.
- `1`, `1.0`, `true` and `"1"` are different values, so a change between them is reported as `changed`.
- `context_lines` is not used in this mode.

Example input:

```json
{
  "mode": "json",
  "old_text": "{\"a\": 1, \"gone\": true, \"c\": [1, 2]}",
  "new_text": "{\"a\": 2, \"b\": false, \"c\": [1, 2, 3]}"
}
```

Output (one dataset item):

```json
{
  "mode": "json",
  "identical": false,
  "added_count": 2,
  "removed_count": 1,
  "changed_count": 1,
  "added": [
    { "path": "$.c[2]", "value": 3 },
    { "path": "$.b", "value": false }
  ],
  "removed": [
    { "path": "$.gone", "value": true }
  ],
  "changed": [
    { "path": "$.a", "old": 1, "new": 2 }
  ]
}
```

### Pricing

- **$0.005 per successful run** (UNCONFIRMED against the live Store) (event `conversion`). One run compares one pair of texts or documents.
- **Failed runs** (bad input, an unsupported mode, invalid JSON, a value over the size limit) are **not charged**.
- Apify's own platform usage for the run is separate from this price.

### Limits

- **Size:** each input can be up to 1,000,000 bytes by default. Set `max_input_bytes` to go up to 5,000,000 bytes. The limit applies to each input on its own.
- **Context lines:** 0 to 10 in text mode.
- **JSON nesting:** documents nested too deeply to compare are refused with a message.
- **JSON lists** are compared position by position. Inserting one item at the start of a list reports every later item as changed, because each one now sits at a different position.
- **Text mode** works line by line. A block that moved shows as a removal in one place and an addition in another.

### FAQ

**Does it send my data anywhere?** The comparison code makes no outside requests in its own code, reads no files and does no scraping. The result is saved to your run's storage on Apify, like any Apify actor's output.

**Which diff format does text mode use?** The standard unified diff format, produced by Python's `difflib` module.

**Can I call it from code?** Yes, through the Apify API or the Apify client for JavaScript or Python, like any Apify actor.

**I found a bug or need a feature.** Open an issue on this actor's Issues tab.

### AI use

The code for this actor was written with help from AI coding tools. The actor does not call an AI model when it runs. Its output comes from Python's standard `difflib` and `json` modules.

***

Made by Brightwater Tools.

# Actor input Schema

## `mode` (type: `string`):

'text' compares two texts line by line and returns a unified diff with line numbers. 'json' compares two JSON documents and lists the added, removed and changed paths.

## `old_text` (type: `string`):

The earlier version. In 'text' mode it can be any text. In 'json' mode it must be a JSON document. Nothing is fetched from a URL or read from a file.

## `new_text` (type: `string`):

The later version, in the same format as the original. Nothing is fetched from a URL or read from a file.

## `context_lines` (type: `integer`):

Unchanged lines shown around each change in 'text' mode. Use 0 to show only the changed lines. Not used in 'json' mode.

## `max_input_bytes` (type: `integer`):

Each of the two inputs is refused if it is larger than this. The hard ceiling is 5,000,000 bytes.

## Actor input object example

```json
{
  "mode": "text",
  "old_text": "alpha\nbeta\ngamma\n",
  "new_text": "alpha\nBETA\ngamma\ndelta\n",
  "context_lines": 3,
  "max_input_bytes": 1000000
}
```

# Actor output Schema

## `results` (type: `string`):

One item per run: summary counts plus the unified diff (text mode), or the added, removed and changed paths (json mode).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("brightwater-tools/text-json-diff").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("brightwater-tools/text-json-diff").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call brightwater-tools/text-json-diff --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brightwater-tools/text-json-diff"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4zU5NxIw7kSADTwn5/builds/OYHaaEytZCnYz4SZm/openapi.json
