Documentation
Guides
Notifications

Notifications

Get scan results in Slack, Teams, or any webhook endpoint — no code required. Configure notification channels in .natrc and NAT fires them automatically on the events you care about.

Quick use: Add a notifications block to your .natrc, set SLACK_WEBHOOK_URL in your environment, and every completed scan posts to your channel automatically.


Supported channels

ChannelHow it works
SlackIncoming webhook — one URL, no OAuth app required
Microsoft TeamsWorkflow connector webhook
Generic webhookAny HTTPS endpoint — custom headers supported

Configuration

Add a notifications block to your .natrc:

notifications:
  slack:
    webhook_url: "${SLACK_WEBHOOK_URL}"
    channel: "#api-security"   # display label only — destination channel is set in Slack webhook settings
    on: [scan_complete, finding_critical, finding_high]
 
  teams:
    webhook_url: "${TEAMS_WEBHOOK_URL}"
    on: [scan_complete]
 
  webhook:
    url: "https://your-endpoint.com/nat-events"
    headers:
      Authorization: "Bearer ${WEBHOOK_TOKEN}"
    on: [scan_complete, finding_critical]
⚠️

Never hard-code webhook URLs or tokens in .natrc. Always use environment variable references ("${VAR_NAME}") so secrets are not committed to source control.


Event types

EventFires when
scan_completeAny scan finishes (pass or fail)
scan_failedA scan exits with a non-zero status (error or threshold breach)
finding_criticalA critical-severity finding is discovered during scanning
finding_highA high-severity finding is discovered during scanning
compliance_report_readyA compliance report (nat ai compliance-report) has been generated

You can subscribe to multiple events per channel:

on: [scan_complete, finding_critical, finding_high]

Or subscribe to a single event:

on: [finding_critical]

Payload format

scan_complete

{
  "event": "scan_complete",
  "scan_id": "scan_abc123",
  "timestamp": "2025-01-15T14:32:00Z",
  "target": "https://api.example.com",
  "spec": "./openapi.yaml",
  "summary": {
    "critical": 0,
    "high": 2,
    "medium": 5,
    "low": 3,
    "info": 12,
    "total": 22
  },
  "status": "completed",
  "duration_seconds": 47,
  "dashboard_url": "https://app.nat.dev/scans/scan_abc123"
}

finding_critical / finding_high

{
  "event": "finding_critical",
  "scan_id": "scan_abc123",
  "timestamp": "2025-01-15T14:31:22Z",
  "finding": {
    "id": "finding_xyz789",
    "title": "SQL Injection in /users/search",
    "severity": "critical",
    "endpoint": "GET /users/search",
    "parameter": "q",
    "cwe": "CWE-89",
    "owasp": "API1:2023"
  },
  "dashboard_url": "https://app.nat.dev/scans/scan_abc123/findings/finding_xyz789"
}

compliance_report_ready

{
  "event": "compliance_report_ready",
  "timestamp": "2025-01-15T15:00:00Z",
  "report": {
    "framework": "owasp-api-top-10",
    "scan_id": "scan_abc123",
    "score": 82,
    "download_url": "https://app.nat.dev/reports/report_def456.pdf"
  }
}

Slack message format

When a scan_complete event fires to a Slack channel, the message looks like:

🔍 NAT Scan Complete — api.example.com

Status: ✅ Passed (threshold: high)
Duration: 47s   Scan ID: scan_abc123

Findings:
  🔴 Critical: 0   🟠 High: 2
  🟡 Medium: 5     🔵 Low: 3

👉 View full report: https://app.nat.dev/scans/scan_abc123

For finding_critical events, Slack receives an immediate alert (not batched) so on-call teams are notified instantly.


CI/CD usage

Configure notification secrets as environment variables in your CI/CD platform, then reference them in .natrc:

# .github/workflows/nat-scan.yml
jobs:
  nat-scan:
    runs-on: ubuntu-latest
    env:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
      TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
      WEBHOOK_TOKEN: ${{ secrets.NAT_WEBHOOK_TOKEN }}
    steps:
      - uses: actions/checkout@v4
      - name: Run NAT scan
        uses: nat-testing/nat-action@v1
        with:
          api-key: ${{ secrets.NAT_API_KEY }}
          api-url: ${{ vars.STAGING_API_URL }}

Troubleshooting

ProblemFix
Slack returns 403 ForbiddenWebhook URL has been revoked. Regenerate it in your Slack app settings and update the secret.
Message not appearing in channelThe destination channel is set when the incoming webhook is created in Slack — not by the channel field in .natrc (which is display-only). Verify the webhook URL is configured for the correct channel in your Slack app settings.
Teams webhook returns 400 Bad RequestTeams connector webhooks have a 28 KB message size limit. Try subscribing to fewer events or a specific severity.
Generic webhook times outNAT waits up to 10 seconds for a response. Ensure your endpoint responds promptly and returns a 2xx status.
${SLACK_WEBHOOK_URL} not substitutedThe environment variable is not set in the environment where nat scan runs. Verify with echo $SLACK_WEBHOOK_URL.
No notifications firing at allRun nat doctor to validate your .natrc and confirm the notifications block is parsed correctly.

Related

Was this helpful?