Channels

A channel is a destination for alerts. A rule targets at least one; a channel can serve several rules.

kind Destination Creation through the API
webhook Your HTTPS server, signed requests. Direct (201), with url.
discord A Discord channel, through an incoming webhook. Direct (201), with url.
slack A Slack channel, through an incoming webhook. Direct (201), with url.
email 1 to 10 email addresses. Direct (201), with emails.
telegram A Telegram group or chat. By invitation link (202).
hellome A helloMe conversation. By invitation link (202).

Allowed kinds depend on the plan (403 channel_kind_not_in_plan): see Plans and quotas.

Common fields#

Field Meaning
name Free name, 80 characters at most.
role alerts (default) or escalation: an escalation channel receives the reminders of unacknowledged critical alerts.
locale Message language: fr (default) or en.

A channel's configuration (URL, tokens, secret) is never returned by the API; the target field gives a masked form: https://hooks.example.com/aicscan, o***@example.com, Telegram group -1001234567890.

Webhook#

Shell
curl -X POST https://aicscan.io/v1/channels \
  -H "Authorization: Bearer $AICSCAN_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"kind":"webhook","url":"https://hooks.example.com/aicscan","name":"SIEM","locale":"en"}'

The 201 response contains webhook_secret (whsec_…), shown only once: you need it to verify signatures. The URL must use https and point to a public host: private, loopback, link-local, cloud metadata and reserved addresses, local names and URLs with credentials are refused (422 url_not_allowed, reason in details.reason). The check runs again at every delivery.

Discord and Slack#

Shell
curl -X POST https://aicscan.io/v1/channels \
  -H "Authorization: Bearer $AICSCAN_API_KEY" -H "Content-Type: application/json" \
  -d '{"kind":"discord","url":"https://discord.com/api/webhooks/1234567890/abcDEF","name":"#treasury"}'
  • Discord: URL shaped like https://discord.com/api/webhooks/… (Channel settings, Integrations, Webhooks).
  • Slack: URL shaped like https://hooks.slack.com/services/… (Incoming Webhooks app).

Email#

Shell
curl -X POST https://aicscan.io/v1/channels \
  -H "Authorization: Bearer $AICSCAN_API_KEY" -H "Content-Type: application/json" \
  -d '{"kind":"email","emails":["ops@example.com","cfo@example.com"],"locale":"en"}'

Telegram and helloMe#

These channels are linked with an invitation link, to be opened by a group administrator within 10 minutes. They accept neither name, role, url nor emails.

Shell
curl -X POST https://aicscan.io/v1/channels \
  -H "Authorization: Bearer $AICSCAN_API_KEY" -H "Content-Type: application/json" \
  -d '{"kind":"telegram","locale":"en"}'
JSON
{
  "kind": "telegram",
  "status": "pending",
  "invite": {
    "token": "Kx3p9QvT2mWb7aZr",
    "link": "https://t.me/AicscanBot?startgroup=Kx3p9QvT2mWb7aZr",
    "expires_at": "2026-11-14T09:25:00Z",
    "expires_in_minutes": 10
  }
}

Send invite.link to the group administrator, then poll the URL given by the Location header (GET /v1/channel-invites/{token}) until status: "linked": channel_id then gives the new channel's id. An unused invitation becomes expired. If the service has no bot configured for this kind, creation answers 503 channel_kind_unavailable.

Testing a channel#

Shell
curl -X POST https://aicscan.io/v1/channels/$CHANNEL_ID/test -H "Authorization: Bearer $AICSCAN_API_KEY"

A test message is queued (202); its outcome can be read on GET /v1/notifications/{notification_id} (status and attempts). A disabled channel answers 409 channel_inactive.

Disable, enable, delete#

Shell
curl -X PATCH https://aicscan.io/v1/channels/$CHANNEL_ID \
  -H "Authorization: Bearer $AICSCAN_API_KEY" -H "Content-Type: application/json" \
  -d '{"state":"disabled"}'

curl -X DELETE https://aicscan.io/v1/channels/$CHANNEL_ID -H "Authorization: Bearer $AICSCAN_API_KEY"
  • PATCH accepts state (active or disabled) and name. Enabling a channel resets its failure streak.
  • Deletion is soft: the delivery history stays readable and the channel no longer counts toward the plan. It is refused while an active rule uses the channel (409 channel_in_use, rules in details.rules); links with paused rules are removed. The workspace owners and its other active channels are notified.

Delivery reliability#

  • Every delivery is logged: GET /v1/notifications/{id} lists the attempts (delivery_attempts) with HTTP status, duration and error.
  • A failed delivery is retried: 30 s, 2 min, 10 min, 30 min, 1 h, 3 h, then every 6 h, for 24 hours at most.
  • A channel failing continuously for 24 hours is disabled automatically (disabled_reason) and the workspace owner is notified by email. Enable it again with PATCH {"state":"active"} once the cause is fixed.
  • A sent or failed notification can be resent: POST /v1/notifications/{id}/resend.
  • During a flood of alerts, Aicscan groups the following alerts into a digest sent once a minute (type: "digest") so the channel is not drowned; grouped alerts have the grouped status.