โ† Back to Blog

Automating Schema Reviews with Webhooks and APIs

Automation Guide ยท April 22, 2026 ยท 9 min read

Manual schema reviews don't scale. When your team ships ten migrations a week, asking a human to read every ALTER TABLE statement is a bottleneck. Worse, it's unreliable โ€” reviewers miss things, especially at 5 PM on a Friday.

Automation doesn't replace judgment. It removes tedium and catches the obvious dangers before a human ever sees them. The ideal workflow looks like this:

  1. A developer opens a migration PR.
  2. A bot automatically diffs the schema and posts the results.
  3. If breaking changes are detected, Slack gets an alert.
  4. The reviewer approves with full context in 30 seconds.

This post shows you how to build that workflow using the SchemaLens API, standard webhooks, and a little glue code.

The SchemaLens API in 30 seconds

SchemaLens exposes a single REST endpoint at POST /api/diff. It accepts two schema strings, a dialect, and returns a structured diff plus generated migration SQL.

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

The response includes:

There's also a markdown format that returns a full human-readable report. We'll use both.

Rate limits: The API allows 30 requests per minute per IP. For CI/CD use, that's generous. If you need more, cache results or run the CLI locally.

Pattern 1: Slack alerts for breaking changes

The most impactful automation is also the simplest: notify your team when a dangerous schema change is introduced.

Here's a Node.js script you can run in CI or on a schedule. It diffs two schemas and posts to a Slack webhook only if breaking changes are found:

const webhookUrl = process.env.SLACK_WEBHOOK_URL;

async function notifySlack(schemaA, schemaB, dialect = 'postgres') {
  const res = await fetch('https://schemalens.tech/api/diff', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ schemaA, schemaB, dialect, format: 'json' })
  });
  const data = await res.json();

  if (!data.breakingChanges || data.breakingChanges.length === 0) {
    console.log('No breaking changes. Silence is golden.');
    return;
  }

  const critical = data.breakingChanges.filter(b => b.severity === 'critical');
  const warnings = data.breakingChanges.filter(b => b.severity === 'warning');

  const blocks = [
    {
      type: 'header',
      text: { type: 'plain_text', text: '๐Ÿšจ Breaking schema changes detected' }
    },
    {
      type: 'section',
      text: {
        type: 'mrkdwn',
        text: `*Critical:* ${critical.length}\n*Warnings:* ${warnings.length}\n\nReview the migration before deploying.`
      }
    }
  ];

  await fetch(webhookUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ blocks })
  });
}

Run this in your CI pipeline after generating a migration. If breaking changes exist, your #engineering channel gets a ping. If not, nothing happens โ€” no notification fatigue.

Pattern 2: PR comment bot with full diff

Slack alerts are great for attention. PR comments are great for context. Here's how to post a schema diff directly into every migration PR.

Using GitHub Actions + the SchemaLens API:

# .github/workflows/schema-diff-comment.yml
name: Schema Diff Comment
on:
  pull_request:
    paths:
      - 'db/schema.sql'
      - 'migrations/*.sql'

jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get base schema
        run: git show origin/${{ github.base_ref }}:db/schema.sql > base-schema.sql

      - name: Diff schemas
        id: diff
        run: |
          curl -s -X POST https://schemalens.tech/api/diff \
            -H "Content-Type: application/json" \
            -d "{\"schemaA\":$(jq -Rs . < base-schema.sql),\"schemaB\":$(jq -Rs . < db/schema.sql),\"dialect\":\"postgres\",\"format\":\"markdown\"}" \
            | jq -r '.markdown' > report.md

      - name: Comment PR
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const body = '## Schema Diff Report\n\n' + fs.readFileSync('report.md', 'utf8');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body
            });

Every PR that touches schema files gets an automatic comment with the full diff. Reviewers see added columns, dropped indexes, and breaking changes without leaving GitHub.

Pattern 3: Nightly schema drift monitoring

Production schemas drift. Someone runs a hotfix migration manually. A DBA tweaks an index. A feature flag experiment adds a temporary column. Over weeks, your codebase schema and production schema diverge.

Nightly drift detection catches this before it becomes a deployment blocker:

# Run this nightly via cron or GitHub Actions schedule
const fs = require('fs');

async function checkDrift() {
  // Export production schema however you normally would
  const prodSchema = await exportProductionSchema();
  const codeSchema = fs.readFileSync('db/schema.sql', 'utf8');

  const res = await fetch('https://schemalens.tech/api/diff', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      schemaA: codeSchema,
      schemaB: prodSchema,
      dialect: 'postgres',
      format: 'json'
    })
  });
  const data = await res.json();

  const hasChanges =
    data.diff.tablesAdded.length > 0 ||
    data.diff.tablesRemoved.length > 0 ||
    data.diff.tablesModified.length > 0;

  if (hasChanges) {
    await notifySlack(`Schema drift detected. ${data.diff.tablesModified.length} tables modified.`);
    process.exit(1); // Fail the job for visibility
  }
}

checkDrift();

Schedule this with GitHub Actions on: schedule: - cron: '0 6 * * *' or a simple cron job. If drift is detected, your team knows within 24 hours โ€” not three months later when a deploy explodes.

Pattern 4: Build your own webhook listener

If you want real-time schema diffing integrated into your own platform, build a lightweight webhook listener that calls the SchemaLens API.

Example: a Vercel serverless function that receives a webhook from your database platform (like Supabase or PlanetScale) and runs a diff:

// api/schema-webhook.js
module.exports = async (req, res) => {
  const { schemaA, schemaB, dialect, callbackUrl } = req.body;

  const diffRes = await fetch('https://schemalens.tech/api/diff', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ schemaA, schemaB, dialect, format: 'json' })
  });
  const result = await diffRes.json();

  // Post result back to your system
  await fetch(callbackUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      breakingCount: result.breakingChanges.length,
      summary: result.summary,
      migration: result.migration
    })
  });

  res.status(200).json({ processed: true });
};

This pattern turns any event โ€” a schema push, a migration deployment, a scheduled job โ€” into a trigger for automated diff analysis.

Security and privacy considerations

Schema structures can reveal sensitive information: table names like patients or credit_cards, column names like ssn or salary. When automating schema reviews, keep these principles in mind:

Putting it together: the automated review pipeline

Here's what a fully automated schema review pipeline looks like with SchemaLens:

  1. Developer opens PR with a migration file.
  2. GitHub Action runs /api/diff and posts a markdown report as a PR comment.
  3. If breaking changes exist, a second Action sends a Slack alert to #migrations.
  4. Reviewer reads the PR comment, sees the diff, and approves or requests changes.
  5. After merge, a nightly cron job compares db/schema.sql against production to catch drift.

Total human time per migration: 2 minutes of review. Total automation setup: 30 minutes once. Total incidents prevented: hard to measure, but the teams that implement this stop having 3 AM pages from schema issues.

Start automating your schema reviews

SchemaLens is free for up to 10 tables. Use the API, CLI, or browser app to diff schemas and generate migrations instantly.

Try SchemaLens Free

Read the API docs โ†’


Related reading: