๐ŸŽฏ What You Can Build

CI/CD Pipeline Gates

Fail a build when a pull request introduces breaking schema changes. Catch dropped columns and NOT_NULL mismatches before they reach production.

Slack Alerts for Schema Drift

Post a formatted diff summary to Slack whenever staging and production schemas diverge. Include risk scores and migration SQL.

Nightly Drift Monitoring

Run a cron job every night that compares your committed schema against your production database. Detect undocumented changes automatically.

๐Ÿ”‘ Step 1 โ€” Get a Pro License Key

1

Purchase a Pro license

API access requires a SchemaLens Pro license key. Keys are delivered instantly after purchase.

2

Format

License keys look like SL-XXXX-XXXX-XXXX-XXXX. Pass them in the X-License-Key header or licenseKey body field.

๐Ÿš€ Step 2 โ€” Make Your First Request

The API has one primary endpoint. Send two SQL schemas and receive a full diff, migration SQL, breaking change analysis, and risk score.

POST https://schemalens.tech/api/diff

Choose your language

curl -X POST https://schemalens.tech/api/diff \
  -H "Content-Type: application/json" \
  -H "X-License-Key: SL-XXXX-XXXX-XXXX-XXXX" \
  -d '{
    "schemaA": "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));",
    "schemaB": "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));",
    "dialect": "postgres",
    "format": "json"
  }'
const response = await fetch('https://schemalens.tech/api/diff', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-License-Key': 'SL-XXXX-XXXX-XXXX-XXXX'
  },
  body: JSON.stringify({
    schemaA: 'CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));',
    schemaB: 'CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));',
    dialect: 'postgres',
    format: 'json'
  })
});

const data = await response.json();
console.log(data.migration);
// ALTER TABLE "users" ADD "email" VARCHAR ( 255 );
import requests

response = requests.post(
    'https://schemalens.tech/api/diff',
    headers={
        'Content-Type': 'application/json',
        'X-License-Key': 'SL-XXXX-XXXX-XXXX-XXXX'
    },
    json={
        'schemaA': 'CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));',
        'schemaB': 'CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));',
        'dialect': 'postgres',
        'format': 'json'
    }
)

data = response.json()
print(data['migration'])
# ALTER TABLE "users" ADD "email" VARCHAR ( 255 );
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

type DiffRequest struct {
    SchemaA  string `json:"schemaA"`
    SchemaB  string `json:"schemaB"`
    Dialect  string `json:"dialect"`
    Format   string `json:"format"`
}

func main() {
    payload := DiffRequest{
        SchemaA: "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));",
        SchemaB: "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));",
        Dialect: "postgres",
        Format:  "json",
    }
    body, _ := json.Marshal(payload)

    req, _ := http.NewRequest("POST", "https://schemalens.tech/api/diff", bytes.NewBuffer(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-License-Key", "SL-XXXX-XXXX-XXXX-XXXX")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result["migration"])
}

๐Ÿ†“ Free Diff API โ€” No License Key Required

Perfect for CI/CD pipelines, open-source projects, and quick checks. Returns a summarized diff with a migration teaser.

POST https://schemalens.tech/api/free-diff
curl -X POST https://schemalens.tech/api/free-diff \
  -H "Content-Type: application/json" \
  -d '{
    "schemaA": "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));",
    "schemaB": "CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255));",
    "dialect": "postgres",
    "format": "json"
  }'

Free tier limits: 15 requests/minute. Response includes summary, risk score, first 5 breaking changes, and first 5 lines of migration SQL. Upgrade to Pro for unlimited access and full migration generation.

๐Ÿ“„ See Dedicated curl Demo Page โ†’

๐ŸŽฎ Interactive Playground โ€” Try the Free Diff API

Paste two schemas below and hit Run API Request to see the live response. No signup required.

curl -X POST https://schemalens.tech/api/free-diff -H "Content-Type: application/json" -d '{...}'

๐Ÿ“ค Step 3 โ€” Understand the Response

{
  "diff": {
    "tablesAdded": [],
    "tablesRemoved": [],
    "tablesModified": [
      {
        "name": "users",
        "columnsAdded": [{ "name": "email", "type": "VARCHAR(255)", ... }],
        "columnsRemoved": [],
        "columnsModified": []
      }
    ],
    "enumsAdded": [],
    "enumsRemoved": [],
    "triggersAdded": [],
    "triggersRemoved": [],
    "triggersModified": [],
    "viewsAdded": [],
    "viewsRemoved": [],
    "viewsModified": [],
    "functionsAdded": [],
    "functionsRemoved": [],
    "functionsModified": []
  },
  "migration": "ALTER TABLE \"users\" ADD \"email\" VARCHAR ( 255 );",
  "breakingChanges": [],
  "riskScore": {
    "score": 0,
    "label": "Safe",
    "icon": "๐ŸŸข"
  },
  "summary": {
    "tablesAdded": 0,
    "tablesRemoved": 0,
    "tablesModified": 1,
    "enumsAdded": 0,
    "enumsRemoved": 0,
    "triggersAdded": 0,
    "triggersRemoved": 0,
    "triggersModified": 0,
    "viewsAdded": 0,
    "viewsRemoved": 0,
    "viewsModified": 0,
    "functionsAdded": 0,
    "functionsRemoved": 0,
    "functionsModified": 0,
    "breakingChangeCount": 0
  }
}

Response Fields

diff
Full semantic diff with added, removed, and modified tables, columns, constraints, indexes, enums, triggers, views, and functions.
migration
Generated ALTER TABLE / CREATE TABLE SQL to migrate from schemaA to schemaB.
breakingChanges
Array of dangerous changes (DROP_TABLE, DROP_COLUMN, ADD_NOT_NULL_NO_DEFAULT, etc.). Empty if safe.
riskScore
Object with score (0-100), label (Safe / Low / Medium / High / Critical), and icon.
summary
Counts of all object changes for quick dashboard display.

๐Ÿ› ๏ธ Step 4 โ€” Common Patterns

Pattern A: Fail a CI Build on Breaking Changes

#!/bin/bash
set -e

RESPONSE=$(curl -s -X POST https://schemalens.tech/api/diff \
  -H "Content-Type: application/json" \
  -H "X-License-Key: $SCHEMALENS_KEY" \
  -d "{\"schemaA\":$(cat base.sql | jq -Rs .),\"schemaB\":$(cat head.sql | jq -Rs .),\"dialect\":\"postgres\"}")

COUNT=$(echo "$RESPONSE" | jq '.summary.breakingChangeCount')
if [ "$COUNT" -gt 0 ]; then
  echo "โŒ Breaking changes detected:"
  echo "$RESPONSE" | jq '.breakingChanges'
  exit 1
fi

echo "โœ… Schema diff passed. No breaking changes."

Pattern B: Post Diff Summary to Slack

# First, get the diff
DIFF=$(curl -s -X POST https://schemalens.tech/api/diff \
  -H "Content-Type: application/json" \
  -H "X-License-Key: $SCHEMALENS_KEY" \
  -d '{"schemaA":"...","schemaB":"...","dialect":"postgres"}')

# Then, send to Slack via SchemaLens webhook proxy
curl -X POST https://schemalens.tech/api/slack \
  -H "Content-Type: application/json" \
  -d "{
    \"webhookUrl\": \"$SLACK_WEBHOOK_URL\",
    \"diff\": $(echo "$DIFF" | jq '.diff'),
    \"migration\": $(echo "$DIFF" | jq '.migration'),
    \"breakingChanges\": $(echo "$DIFF" | jq '.breakingChanges'),
    \"dialect\": \"postgres\"
  }"

Pattern C: Markdown Report for PR Comments

curl -X POST https://schemalens.tech/api/diff \
  -H "Content-Type: application/json" \
  -H "X-License-Key: SL-XXXX-XXXX-XXXX-XXXX" \
  -d '{
    "schemaA": "...",
    "schemaB": "...",
    "dialect": "postgres",
    "format": "markdown"
  }' | jq -r '.markdown' > schema-diff-report.md

# Post the markdown to GitHub PR comment via gh CLI
gh pr comment 42 --body-file schema-diff-report.md

โš ๏ธ Error Handling

StatusMeaningHow to Fix
400Bad RequestCheck that schemaA and schemaB are strings and dialect is valid.
401UnauthorizedProvide a valid Pro licenseKey or X-License-Key header.
429Rate LimitedWait 60 seconds. Maximum 30 requests per minute per IP.
500Server ErrorRetry with exponential backoff. Contact support if persistent.

๐Ÿ“‹ Parameters Reference

ParameterTypeRequiredDescription
schemaAstringYesThe old (base) schema SQL.
schemaBstringYesThe new (target) schema SQL.
dialectstringNopostgres (default), mysql, sqlite, mssql, oracle
formatstringNojson (default) or markdown
licenseKeystringYesSchemaLens Pro license key. Also accepted as X-License-Key header.

๐Ÿ”’ Privacy & Limits

๐Ÿ’ป CLI Alternative

For offline use or air-gapped environments, the SchemaLens CLI provides the same engine without network requests.

node ci/schemalens-diff.js schemaA.sql schemaB.sql --dialect=postgres --format=json

Ready to automate your schema reviews?

Get a SchemaLens Pro license and start diffing programmatically today.

Get Lifetime Pro โ€” $39 Full API Docs โ†’