Home/Docs/Webhooks

Webhooks

Webhooks let external services push events to Zubo in real time. When a webhook receives an event, Zubo processes the payload through a configurable prompt template and takes action automatically. This turns Zubo into a reactive automation hub — connect GitHub for push notifications, Stripe for payment events, CI/CD pipelines for build results, or any service that can send HTTP POST requests.

Copy-Paste Task Cards

Secure API Access

Enable API auth and create a key before exposing ports beyond localhost.

zubo config set auth.enabled true
zubo auth create-key my-app

Set Local Model Fallback

Keep responses available during provider outages or API quota issues.

zubo config set failover '["openai","ollama"]'
zubo config set providers.ollama.model llama3.3

Common Errors

401 Unauthorized / Missing Bearer token

If auth.enabled is true, all /api/* calls require Authorization: Bearer <key>. Create a new key if needed.

curl -H "Authorization: Bearer YOUR_KEY" http://localhost:3000/api/dashboard/status
Provider Timeout / Upstream unavailable

Use failover and switch temporarily to a responsive provider or smaller model. Check logs for repeated timeout patterns.

zubo model openai/gpt-4o-mini
zubo logs --follow
Missing local model (Ollama/LM Studio)

If local providers fail, ensure the runtime is running and a model is installed.

ollama serve
ollama pull llama3.3

Network Requirements

Localhost won't work for external services. Webhook URLs like http://localhost:61939/api/webhook/... are only reachable from your own machine. External services (GitHub, Stripe, etc.) cannot send events to localhost.

To receive webhooks from external services, you need a publicly reachable URL. Options:

Once you have a public URL, configure the external service to send events to https://your-public-url/api/webhook/<webhook-id>.

Creating Webhooks

You can create webhooks through the dashboard, the CLI, or the API.

Via the Dashboard

  1. Open the web dashboard and navigate to the Webhooks panel in the sidebar.
  2. Click Create Webhook.
  3. Enter a descriptive name (e.g., github-pushes) and an optional HMAC secret for signature verification.
  4. Write a prompt template that tells Zubo how to process incoming events. Use {{payload}} to inject the raw event payload.
  5. Click Save. The dashboard displays the webhook URL to configure in your external service.

Via the CLI

# Create a webhook with a prompt template
zubo webhook create \
  --name "github-pushes" \
  --secret "whsec_abc123..." \
  --prompt "A GitHub push event just occurred: {{payload}}. Summarize what was pushed and notify me."

# List all webhooks
zubo webhook list

# Delete a webhook
zubo webhook delete github-pushes

Via the API

POST /api/webhooks
Content-Type: application/json

{
  "name": "github-pushes",
  "secret": "whsec_abc123...",
  "prompt": "A GitHub push event just occurred: {{payload}}. Summarize what was pushed and notify me."
}

The response includes the generated webhook URL and ID:

{
  "id": "wh_a1b2c3",
  "name": "github-pushes",
  "url": "http://localhost:3000/webhooks/wh_a1b2c3",
  "secret": "whsec_abc123...",
  "createdAt": "2026-02-15T10:00:00Z"
}

HMAC Secret Verification

Zubo supports HMAC-SHA256 signature verification to ensure that incoming webhook payloads are authentic and have not been tampered with. When a webhook has a secret configured, Zubo validates the X-Hub-Signature-256 header on every incoming request.

Prompt Templates

Each webhook has a prompt template that defines how Zubo should process incoming events. The template is a plain-text string with a special {{payload}} placeholder that gets replaced with the full JSON body of the incoming request.

# Simple notification
"New event received: {{payload}}. Summarize it and save to memory."

# GitHub-specific template
"A GitHub {{payload.action}} event occurred on {{payload.repository.full_name}}.
Details: {{payload}}
Summarize the changes and notify me on Telegram."

# Stripe-specific template
"A Stripe payment event occurred: {{payload}}.
If the payment succeeded, log the amount and customer.
If the payment failed, alert me immediately."

When a webhook receives a POST request, Zubo substitutes {{payload}} with the stringified JSON body, constructs a message from the resulting text, and sends it through the agent loop. The agent then processes the message like any other user input — it can use tools, search memory, send notifications, and take any action described in the prompt template.

Dashboard Management

The Webhooks panel in the dashboard provides a visual interface for managing all your webhooks.

Examples

GitHub Push Events

Notify yourself on Telegram whenever code is pushed to your repository.

Step 1: Create the webhook:

POST /api/webhooks
Content-Type: application/json

{
  "name": "github-main-pushes",
  "secret": "my-github-webhook-secret",
  "prompt": "A GitHub push event just happened: {{payload}}. Tell me who pushed, to which branch, and list the commit messages. Send me a summary on Telegram."
}

Step 2: In your GitHub repository, go to Settings → Webhooks → Add webhook. Set the Payload URL to the webhook URL returned above, Content type to application/json, and the Secret to the same value. Select "Just the push event."

Result: Every time someone pushes to the repository, Zubo receives the event, summarizes the commits, and sends the summary to your Telegram.

Stripe Payment Events

Track successful payments and alert on failures.

POST /api/webhooks
Content-Type: application/json

{
  "name": "stripe-payments",
  "secret": "whsec_stripe_signing_secret",
  "prompt": "A Stripe webhook event occurred: {{payload}}. If this is a successful payment (payment_intent.succeeded), save the amount, currency, and customer email to memory. If this is a failed payment (payment_intent.payment_failed), alert me immediately with the failure reason."
}

Configure the webhook URL in your Stripe Dashboard under Developers → Webhooks. Select the payment_intent.succeeded and payment_intent.payment_failed events.

API Endpoints

All webhook management endpoints are under /api/webhooks and require authentication when auth.enabled is true.

List Webhooks

GET /api/webhooks

Returns all configured webhooks with their metadata.

Response:

{
  "webhooks": [
    {
      "id": "wh_a1b2c3",
      "name": "github-pushes",
      "url": "http://localhost:3000/webhooks/wh_a1b2c3",
      "hasSecret": true,
      "prompt": "A GitHub push event...",
      "createdAt": "2026-02-15T10:00:00Z",
      "lastTriggeredAt": "2026-02-15T14:30:00Z",
      "eventCount": 12
    }
  ]
}

Create Webhook

POST /api/webhooks
Content-Type: application/json

{
  "name": "github-pushes",
  "secret": "whsec_abc123...",
  "prompt": "Process this event: {{payload}}"
}

Create a new webhook endpoint. The name and prompt fields are required. The secret field is optional but recommended for production use.

Response:

{
  "id": "wh_a1b2c3",
  "name": "github-pushes",
  "url": "http://localhost:3000/webhooks/wh_a1b2c3",
  "secret": "whsec_abc123...",
  "createdAt": "2026-02-15T10:00:00Z"
}

Update Webhook

PUT /api/webhooks/:id
Content-Type: application/json

{
  "name": "github-all-events",
  "secret": "new-secret",
  "prompt": "Updated prompt: {{payload}}"
}

Update a webhook's name, secret, or prompt template. All fields are optional — only the fields you include will be updated.

Delete Webhook

DELETE /api/webhooks/:id

Delete a webhook and all its associated event history. Returns 204 No Content on success.

Get Webhook Events

GET /api/webhooks/:id/events?limit=20&offset=0

Returns the event history for a specific webhook, ordered by most recent first.

Query parameters:

ParameterDefaultDescription
limit20Number of events to return. Maximum 100.
offset0Number of events to skip for pagination.

Response:

{
  "events": [
    {
      "id": "evt_xyz789",
      "webhookId": "wh_a1b2c3",
      "timestamp": "2026-02-15T14:30:00Z",
      "status": "processed",
      "payloadSize": 2048,
      "processingTimeMs": 1250
    }
  ],
  "total": 12
}

Test Webhook

POST /api/webhooks/:id/test
Content-Type: application/json

{
  "payload": {
    "action": "push",
    "repository": { "full_name": "user/repo" },
    "commits": [{ "message": "test commit" }]
  }
}

Send a test payload to a webhook. The payload is processed through the prompt template and the agent's response is returned. The event is recorded in the webhook's event history with a "test" status. If no payload is provided, a default sample payload is used.

Response:

{
  "reply": "A push to user/repo was received with 1 commit: 'test commit'.",
  "eventId": "evt_test_001"
}