Two public surfaces let the outside world reach an agent: a webhook (for webhook-type agents) that runs the agent from an external event, and an embed widget (for interactive agents) that drops a chat launcher on any site.
Webhook
POST to the agent's webhook URL; the request body becomes the agent's input. For a generic (unbound) agent the platform path segment is none and you must sign the request.
POST https://hooks.flowfn.com/v1/app/agent/hook/none/<webhook_token>
Signing
Compute HMAC-SHA256 (hex) over the exact raw body bytes, keyed with the agent's webhook secret, and send it in the X-Flowfn-Signature header as sha256=<hex>:
SECRET='your-agent-webhook-secret'
TOKEN='your-webhook-token'
BODY='{"event":"user.created","user":{"id":"u_123"}}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -X POST "https://hooks.flowfn.com/v1/app/agent/hook/none/$TOKEN" \
-H 'Content-Type: application/json' \
-H "X-Flowfn-Signature: sha256=$SIG" \
-d "$BODY"
# 200 -> { "job_id": "...", "status": "queued" }
import crypto from 'node:crypto';
const url = 'https://hooks.flowfn.com/v1/app/agent/hook/none/' + WEBHOOK_TOKEN;
const body = JSON.stringify({ event: 'user.created', user: { id: 'u_123' } });
const sig = crypto.createHmac('sha256', SECRET).update(body).digest('hex');
await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Flowfn-Signature': 'sha256=' + sig },
body,
});
The call enqueues a run and returns { job_id, status: "queued" }. Platform-bound agents (Stripe, GitHub, Slack, …) instead verify that provider's own signature header — choose the platform when you create the webhook. Inbound calls are rate-limited per agent (about 10 per minute).
Embed the chat widget
For an interactive agent, add the loader script with the agent's embed_token in data-token — it injects a floating launcher button:
<script async
src="https://app.flowfn.com/agent-widget.js"
data-token="<embed_token>"
data-color="#96d35f"></script>
Or embed the widget directly as an iframe (no launcher):
<iframe src="https://app.flowfn.com/a/<embed_token>"
width="380" height="560" frameborder="0"
sandbox="allow-scripts allow-forms allow-same-origin"></iframe>
Restrict where the widget may load by listing your sites under the agent's allowed domains — an iframe load from any other domain is refused.