Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.feral.sh/llms.txt

Use this file to discover all available pages before exploring further.

Webhooks

FERAL exposes a webhook endpoint that lets any external service push events into your AI brain. Connect GitHub pushes, Stripe payments, IFTTT applets, Zapier zaps, or any service that can send HTTP POST requests.

Creating a Webhook

Via API

curl -X POST http://localhost:9090/v1/webhooks \
  -H "Content-Type: application/json" \
  -d '{
    "name": "github-pushes",
    "events": ["push", "pull_request"],
    "action": "notify",
    "secret": "your-webhook-secret"
  }'
Response:
{
  "id": "wh_abc123",
  "url": "http://localhost:9090/v1/webhooks/wh_abc123",
  "name": "github-pushes",
  "secret": "your-webhook-secret",
  "created_at": "2026-04-15T12:00:00Z"
}
All webhook management goes through the HTTP API. The brain mounts the router at /v1/webhooks; use curl, httpie, or any HTTP client.

Signature Verification

FERAL verifies webhook signatures to ensure requests are authentic. When you create a webhook with a secret, FERAL computes an HMAC-SHA256 signature and compares it to the incoming request’s signature header.
ServiceSignature HeaderAlgorithm
GitHubX-Hub-Signature-256HMAC-SHA256
StripeStripe-SignatureHMAC-SHA256 (with timestamp)
IFTTT(custom)Bearer token
ZapierX-Zapier-SignatureHMAC-SHA256
GenericX-Webhook-SignatureHMAC-SHA256
If the signature doesn’t match, FERAL rejects the request with 401 Unauthorized.

Connecting Services

GitHub

  1. Create a webhook in FERAL by POSTing to /v1/webhooks (see the curl example above) with "name": "github" and "action": "process"
  2. In your GitHub repo: SettingsWebhooksAdd webhook
  3. Set the Payload URL to your FERAL webhook URL (use a tunnel like ngrok for remote access)
  4. Set Content type to application/json
  5. Enter the same secret you used when creating the FERAL webhook
  6. Select events: Pushes, Pull requests, Issues, etc.

IFTTT

  1. Create a webhook in FERAL
  2. In IFTTT, use the Webhooks service as the action
  3. Set the URL to your FERAL webhook endpoint
  4. Set Method to POST and Content-Type to application/json
  5. Map IFTTT ingredients to the JSON body

Zapier

  1. Create a webhook in FERAL
  2. In Zapier, add a Webhooks by Zapier action step
  3. Choose “POST” and enter your FERAL webhook URL
  4. Map your Zap’s data fields to the payload

Stripe

  1. Create a webhook in FERAL with a secret
  2. In the Stripe Dashboard: DevelopersWebhooksAdd endpoint
  3. Enter your FERAL webhook URL
  4. Select events (e.g., payment_intent.succeeded, invoice.paid)
  5. Copy the signing secret from Stripe and update your FERAL webhook

Action Mapping

Each webhook can map to an action that FERAL performs when the event arrives:
ActionDescription
notifySend a notification to your preferred channel (push, Telegram, etc.)
processFeed the event to the Brain for intelligent processing and response
logStore the event in FERAL’s knowledge graph for later reference
skillTrigger a specific FERAL skill by name
automationRun a Home Assistant automation (requires HA integration)
Example: trigger a skill when a GitHub issue is opened:
curl -X POST http://localhost:9090/v1/webhooks \
  -H "Content-Type: application/json" \
  -d '{
    "name": "github-issues",
    "action": "skill",
    "skill_name": "triage_github_issue",
    "secret": "gh-secret-123"
  }'

Managing Webhooks

# List all webhooks
curl http://localhost:9090/v1/webhooks

# Get details
curl http://localhost:9090/v1/webhooks/wh_abc123

# Delete
curl -X DELETE http://localhost:9090/v1/webhooks/wh_abc123

# Test (send a mock event)
curl -X POST http://localhost:9090/v1/webhooks/wh_abc123/test \
  -H "Content-Type: application/json" \
  -d '{"test": true}'

Exposing to the Internet

By default, FERAL runs on localhost. To receive webhooks from external services, you need to expose the endpoint. Options:
  1. ngrok (recommended for development):
    ngrok http 9090
    # Use the generated URL as your webhook endpoint
    
  2. Cloudflare Tunnel (recommended for production):
    cloudflared tunnel --url http://localhost:9090
    
  3. Reverse proxy — configure Nginx/Caddy to forward /v1/webhooks/* to FERAL

Security

  • Always use a webhook secret for signature verification
  • Webhook secrets are stored in FERAL’s encrypted credentials file
  • FERAL logs all webhook deliveries (with redacted payloads) for audit
  • Rate limiting: 60 requests/minute per webhook by default
  • IP allowlisting is available via FERAL_WEBHOOK_ALLOWED_IPS

Troubleshooting

The signature doesn’t match. Verify that the secret in FERAL matches the secret configured in the external service. Check the signature header name.
FERAL runs on localhost by default. Use ngrok or a Cloudflare Tunnel to expose it. Verify your firewall allows inbound connections.
Check the webhook’s action setting. Run curl http://localhost:9090/v1/webhooks/<id> to verify the configuration. Check FERAL logs for processing errors.