A webhook automation gives you one URL. Anyone or anything that canDocumentation Index
Fetch the complete documentation index at: https://docs.usekairo.ai/llms.txt
Use this file to discover all available pages before exploring further.
POST to it triggers the automation, and the result lands in your Telegram chat — same delivery as a scheduled run.
This is the contract third-party services see: GitHub Actions, Linear, Zapier, monitoring tools, iOS Shortcuts, your own scripts. If you can curl, you can fire a Kairo automation.
Creating a webhook automation
Webhook automations are created from the web app, not from chat:- Go to Automations → New automation.
- Switch the trigger type from Schedule to Webhook.
- Give it a name and write the instruction Kairo should run when the webhook fires (e.g. “Send me a Telegram message summarizing the payload”).
- Save. A modal shows your webhook URL once — copy it now and paste it into the service that will call it.
URL shape
whk_ prefix + 32 random bytes, URL-safe). It’s the only credential — there’s no separate API key, no signature header.
Sending requests
SendPOST with Content-Type: application/json (or application/x-www-form-urlencoded) and any JSON body. The body is delivered to Kairo’s planner as context, so include whatever fields you want Kairo to be able to reference.
Accepted
| Aspect | Value |
|---|---|
| Methods | POST only |
| Content types | application/json, application/x-www-form-urlencoded |
| Max body size | 256 KB |
| Empty body | OK — treated as {} |
Responses
| Status | Meaning |
|---|---|
202 Accepted | Token resolved, run accepted. Body: { "ok": true, "run_id": "<uuid>" }. Kairo runs the automation asynchronously and replies to your Telegram. |
404 Not Found | Token doesn’t match any automation (deleted, rotated, or wrong). |
410 Gone | Token resolves, but the automation is paused. Re-enable it from the web app. |
413 Payload Too Large | Body over 256 KB. |
415 Unsupported Media Type | Content type isn’t JSON or form-encoded. |
429 Too Many Requests | Rate limit hit. Honor the Retry-After header. |
Idempotency
Set theIdempotency-Key header to safely retry the same logical event:
- Within 24 hours, repeating the same
(automation, key)pair replays the original202response and does not re-fire the run. - Without the header, every request fires — useful for cron callers that intentionally re-send the same payload on a schedule.
Rate limits
Each automation is capped at 60 requests per minute. Excess requests get429 with a Retry-After header indicating seconds until the next slot.
What gets stored
Every accepted webhook call creates a row in your automation’s run history (visible in the web app). Kairo stores:- The full payload, truncated to 32 KB if larger (the truncated marker is
{ "_truncated": true, "_preview": "<first 32KB>" }). - The trigger time.
- The reply Kairo sent to Telegram.
- Run status (
success/error) and duration.
[redacted] in all log output.
Failure handling
- Pre-acceptance failures (404, 410, 413, 415, 429) don’t count against the automation. Only the HTTP caller sees them.
- Post-acceptance failures (something went wrong while Kairo was running the automation) are recorded and counted.
- After 5 consecutive run failures the automation auto-pauses. You’ll get a Telegram message letting you know, and the webhook URL starts returning
410 Goneuntil you re-enable it.
Rotating the token
If your webhook URL leaks, rotate it:- Web app → Automations → the row → ⋯ → Rotate token.
- Confirm. The old URL stops working immediately — there’s no grace period.
- The new URL is shown in a one-time-reveal modal. Update it everywhere it’s used.
What’s not supported (yet)
- Sender signing (HMAC). Kairo mints the URL; sender authentication isn’t the threat model.
- Per-source secrets or IP allow-lists.
- Custom payload schemas — Kairo’s planner reads your JSON freeform.
- Multipart,
text/plain, or XML payloads.