GC
User Guide / WebhooksMenu
5 min read·Updated 2026-04-10

Webhooks

Webhooks are a channel for external systems to start agent turns. Built-in wake and agent endpoints plus custom hooks with Mustache templates.

Mental model

Requires

Webhooks must be enabled in runtime config with a secret. The runtime rejects requests to disabled webhooks with 403 Forbidden.

Webhooks let external systems start an agent turn by sending an HTTP POST. The runtime exposes two built-in endpoints — a simple wake-up message and a full agent turn — and lets you define custom endpoints that transform arbitrary payloads into agent messages with Mustache templates.

The reader should picture webhooks as a channel, the same category as dashboard chat or Telegram: an entry point that delivers input to the runtime. What comes out is a normal agent turn — tools, memory, tier routing, everything.

Enable webhooks

preferences/webhooks.json — enable and set the secret
json
{
  "webhooks": {
    "enabled": true,
    "secret": "your-webhook-secret"
  }
}

The secret is sent as a bearer token on every request. All built-in and custom hooks share the same secret.

Wake endpoint

The simplest endpoint delivers a message into the default session without running a full tool loop. Use this when the external system just needs to notify the agent and does not expect the agent to act on the message in that request.

POST /api/hooks/wake
bash
curl -X POST http://localhost:8080/api/hooks/wake \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-webhook-secret" \
  -d '{"message": "Build completed successfully"}'
Example output
json
{
  "status": "accepted",
  "deliveryId": "whd_01HCDu5LRGeP2o7s2xGmxyx8",
  "session": "default"
}

Agent endpoint

The agent endpoint runs a full tool loop — the message enters as a user turn, the agent can call tools, respond, and update state. Optional skill field activates a skill before the turn.

POST /api/hooks/agent
bash
curl -X POST http://localhost:8080/api/hooks/agent \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-webhook-secret" \
  -d '{
    "message": "Review deployment logs for errors",
    "skill": "code-review"
  }'
Example output
json
{
  "status": "accepted",
  "deliveryId": "whd_01HCDv8Qn4kLp9r7x3WmVzYa",
  "session": "webhook-agent",
  "skillActivated": "code-review"
}

Custom hooks with templates

Custom hooks let you transform an arbitrary external payload into an agent message with a Mustache template. Each custom hook has its own path, template, and optional skill activation.

Custom hook for GitHub push events
json
{
  "webhooks": {
    "enabled": true,
    "secret": "your-webhook-secret",
    "hooks": {
      "github": {
        "name": "github",
        "path": "/api/hooks/github",
        "messageTemplate": "Push to {{repository.name}} by {{sender.login}}: {{head_commit.message}}",
        "skill": "code-review",
        "active": true
      }
    }
  }
}
GitHub delivers a push payload
bash
curl -X POST http://localhost:8080/api/hooks/github \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-webhook-secret" \
  -d '{
    "repository": {"name": "acme/billing"},
    "sender": {"login": "alice"},
    "head_commit": {"message": "Fix invoice rounding"}
  }'
Rendered message passed to the agent
text
Push to acme/billing by alice: Fix invoice rounding

Delivery state machine

Every incoming webhook is recorded as a delivery with its own state. Inspect deliveries in Dashboard → Webhooks.

PENDING

Request accepted, queued for processing. Transient state.

Initial

DELIVERED

Agent turn completed successfully, response (if any) was delivered back.

Terminal

FAILED

Processing failed: template rendering, skill activation, or tool loop error. Inspect the delivery to see why.

Terminal

RETRY

Transient failure eligible for retry. The runtime retries with backoff before moving to FAILED.

Transient

What to do next