Skip to content

Custom Webhook

The webhook channel is the universal “anything else” integration. If a platform can POST JSON to an HTTP endpoint and accept a JSON response, you can connect it to AI Butler via webhook.

Use it for:

  • Custom chat UIs
  • IFTTT, Zapier, n8n, Make.com
  • SMS gateways (Twilio, MessageBird, etc.) via their webhook
  • IoT devices with HTTP output
  • Your own mobile app
  • Cron jobs and batch systems
  1. An external system POSTs JSON to https://your-host/webhook/custom
  2. AI Butler processes the message through the agent pipeline
  3. Response is returned in the HTTP response body (synchronous) or POSTed back to a callback URL (async)
configurations:
channels:
webhook:
enabled: true
active:
- webhook

All webhook requests must include a shared secret in the X-Aibutler-Secret header — this prevents random internet traffic from triggering the agent.

Terminal window
aibutler vault set webhook_auth_secret $(openssl rand -hex 32)

If you want async delivery (fire-and-forget POST in, response delivered separately), set an outbound URL and auth scheme:

Terminal window
export AIBUTLER_WEBHOOK_OUTBOUND_URL=https://your-system/aibutler-callback
export AIBUTLER_WEBHOOK_AUTH_TYPE=bearer # or "basic" or "none"

The outbound auth secret is the same webhook_auth_secret you set in step 2.

Terminal window
aibutler run

Look for webhook: tools registered in the logs.

POST a JSON body to /webhook/custom:

{
"user_id": "user-123",
"message": "What's the weather?",
"metadata": {
"platform": "my-chat-app",
"location": "Madrid"
}
}

Headers:

Content-Type: application/json
X-Aibutler-Secret: <your secret>

Response (synchronous):

{
"reply": "It's currently 18°C and sunny in Madrid.",
"session_id": "sess-abc123",
"tool_calls": []
}

If you configured AIBUTLER_WEBHOOK_OUTBOUND_URL, AI Butler acknowledges with 202 Accepted immediately and POSTs the reply to your callback URL when ready:

{
"session_id": "sess-abc123",
"reply": "It's currently 18°C and sunny in Madrid.",
"in_reply_to": "user-123"
}

This is the right mode for slow models or long-running tool calls.

Twilio SMS webhooks post application/x-www-form-urlencoded, not JSON, so you’ll want a tiny adapter (single AWS Lambda, Cloudflare Worker, or nginx Lua) to translate and forward. Example for Cloudflare Workers:

export default {
async fetch(req) {
const form = await req.formData();
return fetch("https://your-aibutler/webhook/custom", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Aibutler-Secret": "YOUR_SECRET",
},
body: JSON.stringify({
user_id: form.get("From"),
message: form.get("Body"),
metadata: { platform: "twilio-sms" },
}),
});
},
};
FeatureSupported
Synchronous replyYes
Async callbackYes (configurable)
HMAC authVia shared secret header
Bearer / Basic authYes (outbound)
JSON request/responseYes
File attachmentsURL reference (you host the file)
Rate limitingHonors global channel rate limits

401 Unauthorized. The X-Aibutler-Secret header doesn’t match webhook_auth_secret in the vault. Check for trailing newlines or whitespace.

Request times out. Long-running tool calls (like a 30-second model generation) can exceed your caller’s timeout. Switch to async mode with an outbound callback URL.

Async callback never arrives. Check that AIBUTLER_WEBHOOK_OUTBOUND_URL is reachable from the AI Butler host and that your receiver returns a 2xx status.