Skip to content
← all posts
6 min read

Webhook-Triggered Agent Chains: Connect Everything

Mentiko Team

Cron schedules are the starting point for most automation. But real work doesn't happen on a clock. A customer pays, a PR opens, a support message lands -- and you need an agent chain running within seconds, not waiting for the next scheduled window.

Webhooks turn external events into chain triggers. Anything that can send an HTTP POST can start a chain.

Beyond cron: event-based execution

Scheduled chains answer the question "what should run at 6am?" Webhook-triggered chains answer a different question: "what should happen when X occurs?"

The difference matters. A scheduled PR review chain runs every hour and checks for new PRs. A webhook-triggered PR review chain runs the instant a PR is opened. One is polling. The other is reacting. Reacting is faster, cheaper, and doesn't miss events between poll intervals.

Mentiko treats webhooks as first-class chain triggers. You define a webhook endpoint, map it to a chain, and incoming HTTP requests become chain executions. The webhook payload becomes the chain's input context -- available to every agent in the pipeline.

{
  "name": "github-pr-review",
  "trigger": {
    "type": "webhook",
    "path": "/hooks/github-pr",
    "secret": "$GITHUB_WEBHOOK_SECRET"
  },
  "agents": [...]
}

That trigger block replaces the cron expression. Instead of "schedule": "0 * * * *", you get a URL that GitHub (or anything else) can POST to.

GitHub webhook: code review chain

A PR is opened. Within 60 seconds, five agents have reviewed the diff, checked for security issues, verified test coverage, and posted a summary comment back to GitHub.

{
  "name": "pr-review-pipeline",
  "trigger": {
    "type": "webhook",
    "path": "/hooks/github-pr",
    "secret": "$GITHUB_WEBHOOK_SECRET",
    "filter": {
      "headers": { "X-GitHub-Event": "pull_request" },
      "body": { "action": "opened" }
    }
  },
  "agents": [
    {
      "name": "diff-parser",
      "prompt": "Parse the PR diff from the webhook payload. Identify changed files, functions, and line counts. Ignore generated files.",
      "triggers": ["chain:start"],
      "emits": ["diff:parsed"]
    },
    {
      "name": "logic-reviewer",
      "prompt": "Review the parsed diff for logic errors, edge cases, and potential bugs.",
      "triggers": ["diff:parsed"],
      "emits": ["review:complete"]
    },
    {
      "name": "security-scanner",
      "prompt": "Check the diff for hardcoded secrets, SQL injection, XSS, and dependency vulnerabilities.",
      "triggers": ["diff:parsed"],
      "emits": ["review:complete"]
    },
    {
      "name": "review-compiler",
      "prompt": "Combine all review findings into a single PR comment. Post to GitHub via API.",
      "triggers": ["review:complete"],
      "collect": 2,
      "emits": ["chain:complete"]
    }
  ]
}

The filter block is key. GitHub sends webhooks for every PR event -- opened, closed, labeled, review requested. Without the filter, your chain would fire on all of them. The filter narrows it to only pull_request events where action is opened.

The diff-parser fans out to logic-reviewer and security-scanner in parallel. The review-compiler collects both results before posting.

Stripe webhook: onboarding chain

Payment confirmed. Now what? Most teams have a manual checklist: send welcome email, provision account, assign onboarding rep, schedule kickoff call. That's four handoffs and at least one gets dropped.

{
  "name": "customer-onboarding",
  "trigger": {
    "type": "webhook",
    "path": "/hooks/stripe",
    "secret": "$STRIPE_WEBHOOK_SECRET",
    "filter": {
      "body": { "type": "checkout.session.completed" }
    }
  },
  "agents": [
    {
      "name": "customer-enricher",
      "prompt": "Extract customer email and plan from the Stripe payload. Look up their company in Clearbit. Build a customer profile.",
      "triggers": ["chain:start"],
      "emits": ["profile:ready"]
    },
    {
      "name": "welcome-sender",
      "prompt": "Send a personalized welcome email based on the customer profile and plan tier.",
      "triggers": ["profile:ready"],
      "emits": ["onboard:step-complete"]
    },
    {
      "name": "workspace-provisioner",
      "prompt": "Create the customer's workspace, set default quotas based on plan, generate API keys.",
      "triggers": ["profile:ready"],
      "emits": ["onboard:step-complete"]
    },
    {
      "name": "onboard-tracker",
      "prompt": "Log all onboarding steps to the CRM. Flag if any step failed.",
      "triggers": ["onboard:step-complete"],
      "collect": 2,
      "emits": ["chain:complete"]
    }
  ]
}

From payment to fully provisioned workspace with welcome email sent -- no human in the loop. The customer-enricher adds context that makes the welcome email actually personal, not a template.

Slack webhook: support triage chain

A customer posts in your support channel. The chain classifies urgency, drafts a response, and either posts it directly (for common questions) or escalates to a human (for complex issues).

{
  "name": "support-triage",
  "trigger": {
    "type": "webhook",
    "path": "/hooks/slack",
    "secret": "$SLACK_SIGNING_SECRET",
    "filter": {
      "body": { "event.type": "message", "event.channel": "C04SUPPORT" }
    }
  },
  "agents": [
    {
      "name": "classifier",
      "prompt": "Classify this support message. Categories: billing, technical, feature-request, bug-report. Urgency: low, medium, high, critical.",
      "triggers": ["chain:start"],
      "emits": ["ticket:classified"]
    },
    {
      "name": "responder",
      "prompt": "Draft a response based on classification. For billing and feature-request, draft a complete response. For technical and bug-report, draft an acknowledgment and tag the right team.",
      "triggers": ["ticket:classified"],
      "emits": ["response:ready"]
    },
    {
      "name": "poster",
      "prompt": "Post the response to the Slack thread. If urgency is critical, also ping #incidents.",
      "triggers": ["response:ready"],
      "emits": ["chain:complete"]
    }
  ]
}

Average response time goes from "whenever someone checks the channel" to under 30 seconds. The classifier's urgency rating means critical issues get immediate human attention via the #incidents ping, while routine questions get handled automatically.

Custom HTTP: the generic endpoint

Not everything comes from a well-known service. Internal tools, IoT devices, monitoring systems, CI pipelines -- anything that can make an HTTP POST can trigger a chain.

{
  "trigger": {
    "type": "webhook",
    "path": "/hooks/custom/deploy-monitor",
    "auth": {
      "type": "bearer",
      "token": "$DEPLOY_WEBHOOK_TOKEN"
    }
  }
}

Then from your CI pipeline:

curl -X POST https://your-instance.mentiko.com/hooks/custom/deploy-monitor \
  -H "Authorization: Bearer $DEPLOY_WEBHOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"service": "api-gateway", "version": "2.4.1", "environment": "production"}'

The entire POST body becomes available to agents as {{webhook.body}}. Headers are available as {{webhook.headers}}. You can build chains that react to any HTTP event from any system.

Webhook security

Accepting arbitrary HTTP requests is a security surface. Three layers of protection:

Signature verification. GitHub signs payloads with HMAC-SHA256. Stripe signs with a timestamp + signature scheme. Mentiko validates these automatically when you provide the secret. Invalid signatures are rejected before the chain starts.

IP filtering. Lock webhook endpoints to known IP ranges. GitHub publishes their webhook IPs. Stripe publishes theirs. Add them to the allow list:

{
  "trigger": {
    "type": "webhook",
    "path": "/hooks/github-pr",
    "secret": "$GITHUB_WEBHOOK_SECRET",
    "ip_allow": ["140.82.112.0/20", "192.30.252.0/22"]
  }
}

Replay protection. Every webhook includes a timestamp. Mentiko rejects payloads older than 5 minutes by default. This prevents an attacker from capturing a valid webhook and replaying it later. The window is configurable per endpoint.

All three layers are optional but recommended. At minimum, always use signature verification.

Chaining webhooks: output triggers output

A chain triggered by a webhook can itself send a webhook as its final step. This creates cross-system automation pipelines.

GitHub PR opened -> code review chain -> if critical issues found, POST to PagerDuty webhook -> incident chain triggers on PagerDuty's confirmation webhook -> notification chain posts to Slack.

{
  "name": "review-with-escalation",
  "agents": [
    {
      "name": "reviewer",
      "prompt": "Review the PR diff. If critical security issues found, emit escalation event.",
      "triggers": ["chain:start"],
      "emits": ["review:clean", "review:critical"]
    },
    {
      "name": "escalator",
      "prompt": "POST to PagerDuty with the critical findings. Include PR URL and severity.",
      "triggers": ["review:critical"],
      "webhook_out": {
        "url": "https://events.pagerduty.com/v2/enqueue",
        "headers": { "Authorization": "Token $PAGERDUTY_TOKEN" }
      },
      "emits": ["chain:complete"]
    }
  ]
}

Each chain stays focused on one concern. The webhook-out lets chains compose across systems without becoming monoliths.

Setting it up

  1. Define your chain with a trigger.type of webhook instead of a schedule
  2. Deploy the chain -- Mentiko generates the endpoint URL
  3. Copy the URL and configure it in the source system (GitHub settings, Stripe dashboard, Slack app config)
  4. Add the signing secret to your Mentiko secrets vault
  5. Send a test event from the source system
  6. Check the run history to verify the chain executed correctly

The webhook URL follows the pattern: https://your-instance.mentiko.com{trigger.path}. Each endpoint is scoped to one chain. Multiple chains can have different webhook paths.

Webhooks and schedules aren't mutually exclusive. The same chain can have both -- a webhook for real-time triggers and a schedule as a safety net that catches anything the webhook missed.


Already using scheduled chains? Webhooks are the next step. Learn about chain patterns or join the waitlist to start building.

Get new posts in your inbox

No spam. Unsubscribe anytime.