---
title: "Test Notification Channel"
description: "Tests a notification channel configuration. Optionally sends a real test message."
---

`POST /api/notification-channels/test`

## Request Body

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `type` | string | Yes | - | `webhook`, `slack`, `discord`, `pagerduty`, `pushover`, `opsgenie` |
| `config` | object | Yes | `{}` | Channel config with secrets |
| `organizationId` | number | No | from session | Organization scope |
| `customerId` | number | No | null | Customer scope |
| `websiteId` | number | No | null | Website scope |
| `dryRun` | boolean | No | false | If true, validates only (no actual send) |

## Example (cURL)

```bash
curl -X POST "$BASE_URL/api/notification-channels/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "webhook",
    "config": {
      "url": "https://deinkunde.com/webhook",
      "method": "POST",
      "timeout": 15
    },
    "dryRun": false
  }'
```

## Response

```json
{
  "success": true,
  "mode": "send",
  "message": "Webhook delivered successfully",
  "validation": { "ok": true, "errors": [], "warnings": [] },
  "request": { "url": "https://deinkunde.com/webhook", "method": "POST", "timeoutSeconds": 15, "headers": {}, "bodyPreview": "...", "bodySize": 256 },
  "response": { "reachable": true, "ok": true, "statusCode": 200, "statusText": "OK", "durationMs": 150, "headers": {}, "bodyPreview": null, "bodySize": null }
}
```

HTTP 429 responses are treated as "reachable but rate-limited" (success: true).

## Common errors

- `401 Unauthorized` when not authenticated
- `400 Bad Request` when config is invalid for the given type

