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 -X POST https://diff4.com/api/diff \
-H "Content-Type: application/json" \
-d '{
"encrypted_data": {
"ciphertext": "...",
"iv": "...",
"salt": "..."
}
}'Get your preview URL
{
"success": true,
"data": {
"id": "A3KX9M",
"preview_url": "https://diff4.com/p/A3KX9M"
}
}Share the link and passphrase
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/diffRequest Body
Send a JSON object with the following field:
| Field | Type | Required | Description |
|---|---|---|---|
encrypted_data | object | Yes | Encrypted payload (ciphertext, iv, salt) |
Encrypted Data Object
| Field | Type | Description |
|---|---|---|
ciphertext | string | Base64-encoded AES-256-GCM ciphertext |
iv | string | Base64-encoded 12-byte initialization vector |
salt | string | Base64-encoded 16-byte PBKDF2 salt |
Responses
{
"success": true,
"data": {
"id": "A3KX9M",
"preview_url": "https://diff4.com/p/A3KX9M"
}
}| Field | Type | Description |
|---|---|---|
id | string | 6-character ID for the diff |
preview_url | string | Full 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) andfiles(array of file entries). - Each file entry has
filename(string, required),language(string, optional), andpatch(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.