Prerequisites
- ollim-bot running (quickstart)
- Two environment variables set in
.env:
| Variable | Required | Default | Description |
|---|---|---|---|
WEBHOOK_PORT | Yes | — | Port for the HTTP server (e.g. 8420) |
WEBHOOK_SECRET | Yes | — | Secret token for authenticating requests |
If
WEBHOOK_PORT is set but WEBHOOK_SECRET is missing, the server
refuses to start.Setup
Write a webhook spec
Create a markdown file in
~/.ollim-bot/webhooks/. The filename
is arbitrary — the id field in the frontmatter determines the
URL path.~/.ollim-bot/webhooks/github-ci.md
Restart the bot
The webhook server starts automatically when the bot launches.
You’ll see in the logs:
Spec file format
Each webhook spec is a.md file in ~/.ollim-bot/webhooks/ with
YAML frontmatter and a markdown body.
Frontmatter fields
| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | URL path — requests go to /hook/{id} |
fields | object | — | Validation rules for the payload (JSON Schema) |
isolated | bool | false | Run the fork in isolated mode |
model | string | null | Override the model (e.g. haiku) |
thinking | bool | true | Enable extended thinking |
allow-ping | bool | true | Allow the fork to ping the user |
update-main-session | string | on_ping | When to write back to main session |
skills | list[string] | null | null | Skill names to load at fire time |
subagent | string | null | null | Subagent to delegate the core task to |
Markdown body
The body is a prompt template — instructions for what the agent should do with the incoming data. The validated JSON payload is passed to the agent separately (as a fenced data block in the prompt), so you don’t need placeholders. Just describe the task and reference field names naturally.Fields schema
Thefields value is a set of validation rules using JSON Schema.
It defines which fields the webhook accepts, their types, and any
constraints.
Schema authoring tips
Schema authoring tips
How requests are processed
When an HTTP request hits/hook/{id}, the bot authenticates it,
validates the payload against the spec’s field rules, and fires a
background fork with the validated
data. The caller receives 202 Accepted immediately — the bot
processes the webhook asynchronously.
Invalid requests are rejected with descriptive errors:
| Condition | Status | Response body |
|---|---|---|
| Bad or missing Bearer token | 401 | {"error": "unauthorized"} |
| Unknown webhook path | 404 | {"error": "webhook not found: <slug>"} |
| Invalid JSON body | 400 | {"error": "invalid json"} |
| Schema validation failure | 400 | {"error": "validation failed", "details": [...]} |
Request processing pipeline
Request processing pipeline
- Auth check — verifies the secret token in the request header.
- Spec lookup — matches the URL path to a spec’s
idfield. - JSON parse — reads the request body as JSON.
- Schema validation — validates the payload against the spec’s
fieldsrules. - Prompt construction — the bot builds a prompt combining the task instructions (markdown body) with the validated JSON payload as a fenced data block, keeping webhook data clearly separated from instructions.
- 202 Accepted — response sent immediately.
- Subagent validation — if the spec references a
subagent, the bot verifies it exists. Unknown subagents skip dispatch entirely. - Injection screening — free-form text fields are checked for attempts to trick the bot (30-second timeout — if screening fails, the webhook proceeds). Flagged payloads are skipped and logged.
- Skill validation — if the spec references
skills, the bot verifies each one exists in~/.ollim-bot/skills/. Missing skills skip dispatch entirely. - Dispatch — a background fork runs with the spec’s configuration.
Input security layers
Input security layers
Webhooks accept external input, so four layers of defense prevent
outside data from tricking the bot:
| Layer | What it catches |
|---|---|
| Schema validation | Wrong types, undeclared fields, oversized strings |
| Data labeling | Webhook data is clearly separated from bot instructions |
| Injection screening | Free-form text checked for attempts to trick the bot |
| Size limits | 10 KB payload cap, 500-character strings, 20 properties max |
Troubleshooting
Webhook server not starting
Webhook server not starting
Check that both
WEBHOOK_PORT and WEBHOOK_SECRET are set in
your .env file. If only WEBHOOK_PORT is set, the server logs
an error and stays disabled.Getting 401 Unauthorized
Getting 401 Unauthorized
Getting 404 for a webhook path
Getting 404 for a webhook path
Specs are re-read each time a request arrives, so changes take
effect immediately without restarting. Verify the file exists in
~/.ollim-bot/webhooks/ and that the id field in the frontmatter
matches the path in your URL.Webhook accepted but no bot action
Webhook accepted but no bot action
Several things can cause a webhook to be accepted (202) but produce no action:
- Injection screening flagged a field value. Look for
Webhook <slug>: flagged fields [...], skipping dispatchin the logs. - Missing skills — the spec references a skill that doesn’t exist in
~/.ollim-bot/skills/. Look forWebhook <slug>: unknown skills [...], skipping. - Missing subagent — the spec references a subagent that doesn’t exist. Look for
Webhook <slug>: unknown subagent '...', skipping.
Next steps
Background forks
How background forks work — the execution model webhooks use.
Ping budget
How the ping budget controls when forks can notify you.
Google integration
Connect Google services for tasks, calendar, and email access.
Discord tools
The tools available to the agent during webhook-triggered forks.
