Config Diff API Documentation

Semantic comparison of JSON and YAML configs. Free tier with detailed change tracking.

⚡ Quick Start

Make a POST request to compare two configuration files:

curl -X POST https://saasory.com/api/v1/config-diff/ -H "Content-Type: application/json" -d '{"left": {"content": "{\"name\": \"john\", \"age\": 30}", "format": "json"}, "right": {"content": "{\"name\": \"john\", \"age\": 31}", "format": "json"}}'

No API key required for free tier (50 requests/hour per IP)

🎯 Endpoint

POST https://saasory.com/api/v1/config-diff/

Compare two JSON or YAML configurations. Returns detailed semantic differences with shareable link.

📝 Request Parameters

Parameter Type Required Description
left object Required Left config with content and format
left.content string Required Raw config text (JSON or YAML)
left.format string Optional json, yaml, or auto. Default: auto
right object Required Right config with content and format
right.content string Required Raw config text (JSON or YAML)
right.format string Optional json, yaml, or auto. Default: auto
options object Optional Comparison options (see below)
options.ignoreKeyOrder boolean Optional Ignore dictionary key ordering. Default: true
options.ignoreArrayOrder boolean Optional Ignore array element ordering. Default: false
options.ignorePaths array Optional JSONPath patterns to exclude (e.g., ["$.metadata.*"])

✅ Response Format

Success Response (200 OK):

{ "identical": false, "summary": { "added": 1, "removed": 0, "modified": 1, "type_changed": 0, "total_changes": 2 }, "changes": { "values_changed": { "root['age']": { "old_value": 30, "new_value": 31 } }, "dictionary_item_added": { "root['email']": "john@example.com" } }, "shareUrl": "/tools/config-diff/share/abc123/", "processingTime": 12, "formats": { "left": "json", "right": "json" } }

⏱️ Rate Limits

Tier Hourly Monthly Requirement
Free 50 / hour per IP 50 / month per session None - just start using!
Pro Coming Soon 500 / month Free account

💻 Code Examples

cURL

curl -X POST https://saasory.com/api/v1/config-diff/ -H "Content-Type: application/json" -d '{"left": {"content": "{\"name\": \"john\", \"age\": 30}", "format": "json"}, "right": {"content": "{\"name\": \"jane\", \"age\": 31, \"email\": \"jane@example.com\"}", "format": "json"}, "options": {"ignoreKeyOrder": true, "ignoreArrayOrder": false}}'

Python

import requests response = requests.post( "https://saasory.com/api/v1/config-diff/", json={ "left": { "content": '{"name": "john", "age": 30}', "format": "json" }, "right": { "content": '{"name": "jane", "age": 31}', "format": "json" }, "options": { "ignoreKeyOrder": True } } ) data = response.json() print(f"Changes: {data['summary']['total_changes']}") print(f"Share URL: {data['shareUrl']}")

JavaScript

const response = await fetch("https://saasory.com/api/v1/config-diff/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ left: { content: '{"name": "john", "age": 30}', format: "json" }, right: { content: '{"name": "jane", "age": 31}', format: "json" }, options: { ignoreKeyOrder: true } }) }); const data = await response.json(); console.log("Changes:", data.summary.total_changes); console.log("Share URL:", data.shareUrl);

⚠️ Error Codes

400 Bad Request

Missing/invalid parameters or unparseable JSON/YAML content.

{ "error": "Left content is required" }
429 Rate Limit Exceeded

Exceeded 50 requests/hour (IP limit) or 50 requests/month (session limit).

{ "error": "Rate limit exceeded (50 requests/hour per IP). Try again later." }
500 Server Error

Diff computation failed (parsing error, internal error, or timeout).

{ "error": "Failed to compute diff: Invalid YAML syntax on line 5" }

🎓 Best Practices

Mix JSON and YAML freely

You can compare JSON against YAML. Set format: "auto" to let the API detect automatically.

Use ignorePaths for dynamic fields

Exclude timestamps, UUIDs, or metadata fields using JSONPath patterns like ["$.metadata.*", "$.createdAt"].

Handle parsing errors

Invalid JSON/YAML returns 400. Validate syntax client-side before sending to avoid wasted requests.

Ready to start?

Try the API in our interactive playground first.

Open Playground