diff4
APIs

Diff API

Create shareable diff previews via the REST API.

Overview

The Diff API lets you create an end-to-end encrypted diff preview from a set of file patches. Each diff is assigned a short, shareable ID and a preview URL. The server never sees plaintext data — encryption and decryption happen entirely on the client side.

Diffs automatically expire after 24 hours and are no longer accessible after that.

All diff content is end-to-end encrypted using AES-256-GCM. The server only stores the encrypted blob and cannot read the content. Viewers must enter the correct passphrase to decrypt.

Quick Start

Encrypt your diff data

Encrypt the { title, files } JSON using the encryption function with your chosen passphrase:

const plaintext = JSON.stringify({
  title: "Fix login bug",
  files: [
    {
      filename: "src/auth.ts",
      language: "typescript",
      patch: "@@ -1,5 +1,6 @@\n import { validate } from \"./validator\";\n \n-export function login(token: string) {\n+export function login(token: string, retry = false) {\n   const user = validate(token);\n-  return user;\n+  if (!user && retry) throw new Error(\"retry failed\");\n+  return user;\n }",
    },
  ],
});

const encrypted = await encryptDiff(plaintext, "my-secret-passphrase");

Send the encrypted payload

cURL
curl -X POST https://diff4.com/api/diff \
  -H "Content-Type: application/json" \
  -d '{
    "encrypted_data": {
      "ciphertext": "...",
      "iv": "...",
      "salt": "..."
    }
  }'

Get your preview URL

Response
{
  "success": true,
  "data": {
    "id": "A3KX9M",
    "preview_url": "https://diff4.com/p/A3KX9M"
  }
}

Open preview_url in any browser. The viewer will prompt for the passphrase to decrypt and render the diff. If the viewer previously entered the passphrase, it will be remembered in browser storage.

Endpoint

POST /api/diff

Request Body

Send a JSON object with the following field:

FieldTypeRequiredDescription
encrypted_dataobjectYesEncrypted payload (ciphertext, iv, salt)

Encrypted Data Object

FieldTypeDescription
ciphertextstringBase64-encoded AES-256-GCM ciphertext
ivstringBase64-encoded 12-byte initialization vector
saltstringBase64-encoded 16-byte PBKDF2 salt

Responses

{
  "success": true,
  "data": {
    "id": "A3KX9M",
    "preview_url": "https://diff4.com/p/A3KX9M"
  }
}
FieldTypeDescription
idstring6-character ID for the diff
preview_urlstringFull URL to view the diff preview

Returned when required fields are missing or invalid.

{
  "success": false,
  "error": "ciphertext must be a string, iv must be a string"
}
{
  "success": false,
  "error": "Internal server error"
}

Notes

  • The plaintext (before encryption) must be valid JSON with title (string) and files (array of file entries).
  • Each file entry has filename (string, required), language (string, optional), and patch (string, required, unified diff format).
  • The server cannot decrypt the content. If the passphrase is lost, the diff is unrecoverable.
  • No authentication is required to create or view diffs, but the passphrase is needed to decrypt.

On this page