Trigger an agent from your app (webhook)
4 min · 5 steps
Give an agent a webhook trigger, then have one of your own apps fire it with a signed HTTP call. Pro+ feature. Everything stays on your machine.
A webhook trigger lets a generated app — or any caller on your machine — run an agent on demand. The local service exposes an inbound endpoint `http://127.0.0.1:19274/webhook/<agentId>`; a POST to it (carrying an HMAC signature over the request body) runs the agent and returns its final output. The endpoint listens on `127.0.0.1` only — nothing about the call leaves your machine, and Avery's servers are not in the path.
This is a Pro+ feature (`service.agent_bridge`). On Free, the agent's Settings → Webhook card shows a 'View plans' upsell instead of the URL.
## How auth works
Every request must be signed: `X-Avery-Signature` is an HMAC-SHA256 of the raw JSON body, keyed by a per-agent webhook secret. The secret lives only in your local keystore — never in the agent file, never echoed back after you reveal it once. The receiver verifies the signature in constant time before running anything, so a tampered or replayed body is rejected.
## Wiring an app to it
If you scaffolded the app with Avery, add the 'agent-webhook-client' generator when you build (or describe wanting to call an Avery agent in the prompt). It emits a server-side client `lib/avery-agent.ts` with a `triggerAgent(agentId, body)` helper, a proxy route at `app/api/avery/[agentId]/route.ts`, and an `AVERY_AGENT_WEBHOOK_SECRET` line in `.env.local`. The client is `server-only` — the secret is read from the server environment and the HMAC is computed with Node's crypto, so it can never reach the browser bundle. Paste the agent's rotated secret into `AVERY_AGENT_WEBHOOK_SECRET` and call `triggerAgent` from a route handler or server action.
A hand-rolled caller works too: POST the JSON body to the URL with `X-Avery-Signature: <hex HMAC-SHA256 of the body, keyed by the secret>`.
## What the agent receives / can't do
The request body arrives as the agent's trigger payload — bind into it with `{{trigger.body...}}`. The run uses the same connectors, scopes, and guardrails as a manual run. One limit: an agent with a User input node can't run from a webhook (there's nobody to answer the prompt) — the call fails with `E_USER_INPUT_NEEDS_MANUAL`. Send any per-call value in the request body instead.
Steps
- Set the agent's trigger to Webhook.
Open the agent → Settings → Trigger → pick 'webhook'. Save. (Make sure the agent has no 'User input' node — those need the manual trigger.)
- Open Settings → Webhook and copy the URL.
A Webhook card appears on the Settings tab for any webhook-triggered agent (Pro+). It shows the inbound URL `http://127.0.0.1:19274/webhook/<agentId>` — copy it. On Free the card shows a 'View plans' link instead.
- Reveal the secret (once) with 'Rotate secret'.
Click 'Rotate secret' to mint a fresh HMAC secret. It's shown ONE time — copy it now. Rotating again invalidates the previous secret, so any caller still signing with the old one starts getting 401s.
- Paste the secret into your app.
Put it in the app's `AVERY_AGENT_WEBHOOK_SECRET` (in `.env.local`). The generated `lib/avery-agent.ts` reads it server-side; a hand-rolled caller uses it as the HMAC key. Never commit it or expose it to the browser.
- Call triggerAgent from server code.
From a route handler or server action: `await triggerAgent('<agentId>', { /* your payload */ })`. It returns `{ runId, status, output }`. Watch the run land live in the agent's Runs tab.
Live recipes need the desktop
This article is a static preview. The in-app Help sidecar inside Avery NXR can fire each step against your live project — install the desktop to use it interactively.