Integrations

Webhooks, API keys, and CI/CD pipeline integration.

Webhook notifications

Configure webhooks from Settings → Webhooks to receive real-time notifications. Supported events:

  • migration.started — Fires when a migration begins processing
  • migration.completed — Fires when a migration finishes successfully
  • migration.failed — Fires when a migration encounters an error
  • cdc.error — CDC channel error (e.g., oplog disconnection)
  • cdc.lag_exceeded — Replication lag rose above the migration's alert threshold (set on the migration's detail screen)
  • cdc.lag_recovered — Lag fell back below half the threshold after a cdc.lag_exceeded
  • schema.drift — A field appeared in the source that isn't in the schema mapping; data.action says what the drift policy did with it

Each payload is { event, timestamp, data }, where data includes the migration ID, plus an error message for failures, lagMs and thresholdMs for lag events, and sourceField, targetColumn, type and action for drift. Delivery retries automatically with exponential backoff, up to 5 attempts total. URLs must use HTTPS.

Every delivery is signed. When you add an endpoint you get a signing secret (whsec_…, shown once — rotate it from the endpoint's row to get a new one). Each request carries X-NoSQLSync-Event, X-NoSQLSync-Delivery and X-NoSQLSync-Signature: t=<unix seconds>,v1=<hex>, where v1 is the HMAC-SHA256 of `${t}.${rawBody}` keyed with the secret. Recompute it over the raw request body, compare in constant time, and reject timestamps more than 5 minutes old:

import { createHmac, timingSafeEqual } from "crypto";

function verify(secret, rawBody, header) {
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return v1.length === expected.length && timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}

Endpoints created before signing was introduced have no secret and are delivered unsigned until you rotate one.

New Live Sync and dual-write migrations alert when lag exceeds 60 seconds. Change or turn off the threshold, and choose what happens when a new source field appears, under Live Sync alerts in the migration's detail drawer.

Lag is measured from the source's commit timestamp to the moment the change is written to the target, and is checked about every 10 seconds. A running channel with nothing left to apply reports 0. The alert only fires again after it has recovered, so a lag that hovers near the threshold sends one alert, not one every 10 seconds.

API keys

Pro and Team plans can generate API keys from Settings → API. Send the key as a bearer token on any API request instead of a browser session cookie:

curl https://app.nosqlsync.com/api/migrations \
  -H "Authorization: Bearer nss_..."

The raw key is shown once at creation time and is not recoverable afterward — only its prefix is kept for display. Deleting a key from Settings invalidates it immediately.

Each key has a scope, enforced on every request:

  • Read only — GET requests only (list jobs, logs, schema, metrics).
  • Read & write — also create, start, pause, resume, stop, validate and delete migrations and share validation reports. Connections, webhooks, API keys, team, security and billing stay read-only.
  • Admin — full access, including connections. Keys created before scopes existed are Admin.

A request outside the key's scope gets 403 with code FORBIDDEN_SCOPE. Settings shows when each key was last used.

Docker & Kubernetes

Run NoSQLSync in Docker for local development or deploy as Kubernetes pods. The docker-compose file spins up Redis, MongoDB (replica set), PostgreSQL target, MySQL target, and the app:

docker compose up -d pnpm dev        # Next.js dev server pnpm worker     # BullMQ worker

For Kubernetes, deploy the web app and worker as separate deployments sharing the same Redis and PostgreSQL. Workers connect via internal service DNS.

CI/CD pipeline integration

Run migrations as part of your deployment pipeline using the API:

# GitHub Actions example
- name: Run database migration
  run: |
    curl -X POST https://app.nosqlsync.com/api/migrations \
      -H "Authorization: Bearer ${{ secrets.NOSQLSYNC_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{"name":"deploy-${{ github.sha }}","sourceConnectionId":"...","mode":"one-time"}'

- name: Wait for migration
  run: |
    STATUS=$(curl -s -H "Authorization: Bearer ${{ secrets.NOSQLSYNC_API_KEY }}" \
      https://app.nosqlsync.com/api/migrations/$MIGRATION_ID | jq -r '.status')
    echo "Migration status: $STATUS"