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
| Channel | How it works |
|---|---|
| Slack | Incoming webhook — one URL, no OAuth app required |
| Microsoft Teams | Workflow connector webhook |
| Generic webhook | Any 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
| Event | Fires when |
|---|---|
scan_complete | Any scan finishes (pass or fail) |
scan_failed | A scan exits with a non-zero status (error or threshold breach) |
finding_critical | A critical-severity finding is discovered during scanning |
finding_high | A high-severity finding is discovered during scanning |
compliance_report_ready | A 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_abc123For 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
| Problem | Fix |
|---|---|
Slack returns 403 Forbidden | Webhook URL has been revoked. Regenerate it in your Slack app settings and update the secret. |
| Message not appearing in channel | The 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 Request | Teams connector webhooks have a 28 KB message size limit. Try subscribing to fewer events or a specific severity. |
| Generic webhook times out | NAT waits up to 10 seconds for a response. Ensure your endpoint responds promptly and returns a 2xx status. |
${SLACK_WEBHOOK_URL} not substituted | The environment variable is not set in the environment where nat scan runs. Verify with echo $SLACK_WEBHOOK_URL. |
| No notifications firing at all | Run nat doctor to validate your .natrc and confirm the notifications block is parsed correctly. |