← Back to Blog
2026-03-20

Declarative Webhook Routing: A Better Way to Handle Alerts

> Most webhook routing solutions are code-first. NKAI Gateway takes a different approach — declarative YAML configuration that non-engineers can read and maintain.

The Code-First Trap

When teams first build webhook routing, they write code. A small Lambda function, a tiny Express server, some if/else chains. It works. Until it doesn't.

Three months later, the original author has moved on. The routing logic has grown. Nobody wants to touch it. Every new integration requires a deploy.

Declarative Is Better

NKAI Gateway's routing engine is built around a single YAML config file. Routes match on incoming webhook fields, transform the payload, and dispatch to a destination. No code required.

routes:
  - match:
      severity: warning
      labels.environment: production
    destination:
      type: jira
      project: OPS
      issue_type: Bug

This is readable by a non-engineer. It's reviewable in a pull request. It's testable without deploying.

Matching Rules

The match block supports exact values, wildcards, and regex patterns:

match:
  source: "grafana"
  alert_name: "/.*CPU.*/i"
  severity: ["critical", "warning"]

Multiple values in an array are treated as OR conditions. Nested fields are supported with dot notation.

Transform Templates

The transform block uses a Jinja-style template syntax. Every field from the incoming webhook payload is available as a variable:

transform:
  title: "{{ alert_name }} — {{ labels.service }}"
  body: |
    ## Alert Details
    - **Severity:** {{ severity }}
    - **Instance:** {{ labels.instance }}
    - **Value:** {{ value_string }}
    - **Started:** {{ starts_at | date_format('%Y-%m-%d %H:%M UTC') }}

Versioned Configuration

Because the config is a file, it lives in your repository. Route changes go through code review. History is preserved in git. Rollback is a git revert away.

This is the right model for infrastructure configuration.