Contract Drift Detection

Contract Drift Detection

Automatically compare your mock API responses against live production endpoints. Catch renamed fields, type mismatches, missing data, and broken schemas — before your users do.

What problem does this solve? You built your frontend against a mock API. The backend team then renamed user_name to username, added a required field, and changed a price from a string to a number — without telling anyone. Drift detection catches every one of these automatically.

How It Works

1

Snapshot your mock

moqapi.dev calls your mock API endpoint and records the response: HTTP status, headers, and the full JSON body schema (field names + types).

2

Probe your production URL

The same path is called on your real production URL with the same query parameters and any auth headers you configure.

3

Structural compare

Every field is compared — presence, data type, nesting depth, array item shapes, extra / missing keys, and HTTP status codes.

4

AI classification

Gemini AI classifies each difference as critical (breaking), warning (potential issue), or info (cosmetic). It also detects renames automatically.

5

Report & alert

A drift report is generated with field-by-field findings, a drift score (0–100), and a remediation suggestion for each issue. Alerts fire via Slack, Discord, or email.

Step 1 — Enable Drift Detection

Drift detection is configured per mock API. You need the mock API ID (visible in the mock API settings page) and the base URL of your production API.

Via the Dashboard

  1. 1.Open Mock APIs in the sidebar → click the mock API you want to monitor.
  2. 2.Click the Settings (⚙) icon on the mock API card, then open the Contract Drift tab.
  3. 3.Enter your Production Base URL — e.g. https://api.yourapp.com
  4. 4.Set a schedule using a cron expression. Every 6 hours: 0 */6 * * *
  5. 5.Add any auth headers your production API requires (e.g. Authorization: Bearer prod-token).
  6. 6.Click Save & Enable. The first drift check runs immediately.

Via the API

enable-drift.shbash
curl -X POST https://moqapi.dev/api/apis/drift/configure \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mockApiId": "your-mock-api-id",
    "productionUrl": "https://api.yourapp.com",
    "schedule": "0 */6 * * *",
    "headers": {
      "Authorization": "Bearer your-production-token"
    },
    "enabled": true
  }'

Step 2 — Run a Drift Check

Checks run automatically on your schedule. You can also trigger a manual check any time — useful before a big deployment.

trigger-drift.shbash
curl -X POST https://moqapi.dev/api/apis/drift/run \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "mockApiId": "your-mock-api-id" }'

# Response
{
  "reportId": "rpt_abc123",
  "status": "running",
  "message": "Check started. Results ready in ~10 seconds."
}

Step 3 — Read the Drift Report

View reports in the dashboard under Drift → Reports, or fetch via API.

get-report.shbash
curl https://moqapi.dev/api/drift/reports/rpt_abc123 \
  -H "Authorization: Bearer YOUR_TOKEN"
report-response.jsonjson
{
  "reportId": "rpt_abc123",
  "driftScore": 68,
  "summary": { "critical": 2, "warning": 3, "info": 5 },
  "events": [
    {
      "endpoint": "GET /users",
      "fieldPath": "$.data[0].user_name",
      "severity": "critical",
      "type": "field_missing_in_production",
      "suggestion": "Field renamed to 'username' in production — update your mock."
    },
    {
      "endpoint": "GET /orders",
      "fieldPath": "$.data[0].price",
      "severity": "critical",
      "type": "type_mismatch",
      "mockType": "string",
      "productionType": "number",
      "suggestion": "Change price field type in mock from string to number."
    },
    {
      "endpoint": "GET /users",
      "fieldPath": "$.data[0].avatar_url",
      "severity": "info",
      "type": "field_added_in_production",
      "suggestion": "New optional field. Consider adding to mock for completeness."
    }
  ]
}

Critical

Removed fields, type changes, renamed properties. These WILL break existing clients.

Warning

New required fields, changed enum values, status code changes. Likely to cause issues.

Info

New optional fields, extra data in production. Cosmetic differences — usually safe.

Step 4 — Suppress Known Differences

Some fields always differ — timestamps, request IDs, UUIDs. Add suppression rules so these don't show up as false positives. Suppression uses JSONPath syntax.

add-suppressions.shbash
curl -X POST https://moqapi.dev/api/drift/suppression-rules \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mockApiId": "your-mock-api-id",
    "rules": [
      { "fieldPath": "$.meta.request_id",   "reason": "Always differs — dynamically generated." },
      { "fieldPath": "$.data[*].created_at", "reason": "Timestamps always differ." },
      { "fieldPath": "$.data[*].id",         "reason": "UUIDs generated differently in mock vs production." }
    ]
  }'

Step 5 — Resolve Drift Events

There are three ways to handle a drift finding. Choose based on whether the change is intentional.

Update the mockrecommended

If production changed intentionally — update your mock API to match the new schema. Go to Mock APIs → open the route → update the response body. Re-run a drift check to confirm drift score drops to 0.

Add a suppression ruleif intentional difference

If the mock intentionally returns less data (e.g. you omit internal fields), suppress the path. The event disappears from future reports.

File a bug / revertif production broke

If the production API changed accidentally (breaking change slipped through), mark the event as acknowledged with a note for your team, then fix the underlying issue.

resolve-event.shbash
# Mark a drift event as resolved
curl -X POST https://moqapi.dev/api/drift/events/evt_xyz/resolve \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "resolution": "updated_mock", "note": "Renamed user_name to username in mock." }'

Step 6 — Block Deploys on Critical Drift (CI/CD)

Add a drift check as a deployment gate. If critical drift is found, the pipeline fails. Get your token from Settings → API Keys.

.github/workflows/check-drift.ymlyaml
- name: API Contract Drift Gate
  env:
    MOQAPI_TOKEN: {{ secrets.MOQAPI_TOKEN }}
    MOCK_API_ID: your-mock-api-id
  run: |
    RESULT=$(curl -sf -X POST https://moqapi.dev/api/apis/drift/run \
      -H "Authorization: Bearer $MOQAPI_TOKEN" \
      -H "Content-Type: application/json" \
      -d "{\"mockApiId\": \"$MOCK_API_ID\"}")

    CRITICAL=$(echo "$RESULT" | jq '.summary.critical')

    if [ "$CRITICAL" -gt "0" ]; then
      echo "FAIL: $CRITICAL critical contract drift events."
      echo "$RESULT" | jq '.events[] | select(.severity=="critical")'
      exit 1
    fi
    echo "Contract drift check passed — no critical issues."

API Reference

POST/api/apis/drift/configure
POST/api/apis/drift/run
GET/api/drift/reports?projectId=
GET/api/drift/reports/{reportId}
POST/api/drift/suppression-rules
GET/api/drift/suppression-rules
DELETE/api/drift/suppression-rules/{id}
POST/api/drift/events/{id}/resolve
GET/api/drift/summary?projectId=