Webhooks (Inbound)
Polyant accepts inbound webhooks for two distinct purposes:
- Channel inbound — the WhatsApp/Twilio webhook that delivers user messages.
- Room events — external systems (Stripe, GitHub, custom apps) pushing events into a Room (see Room tab).
This page focuses on the second case: Room event webhooks.
Endpoint
POST /webhooks/<webhookToken>Where <webhookToken> is the unique token generated when you create an event source (Room tab → Event Sources). The token is shown next to the source’s URL and can be regenerated.
Request
- Method:
POST. - Content-Type:
application/json(preferred) orapplication/x-www-form-urlencoded. - Body: any JSON payload up to 64 KB. Larger payloads still receive
200 OK(see Response), with body{"ok": false, "error": "payload too large"}.
Response
Webhooks always return 200 OK, even if no event definition matched, the token is unknown, or the payload was too large. The JSON body reports the outcome ({"ok": true} on success, {"ok": false, "error": "..."} otherwise). Processing is fire-and-forget so the external sender never sees a delay.
If the backlog cap (100 pending events per source) is full, new events are dropped silently. Use the Room → Backlog screen to monitor depth.
What happens internally
- Body parsed; size validated.
- The matcher (LLM tier
fast) evaluates definitions in priority order until one matches. - If a definition matches, the event is inserted into
event_backlogwithstatus = pending. - The Room scheduler will pick it up on the next 30 s tick (or immediately if a human reply on the outbound channel triggers
triggerImmediate()).
If no definition matches, the request is logged but no work is done.
Why everything is “silent”
Returning 200 OK even on no-match keeps webhook senders happy. Stripe, GitHub, and friends will mark the webhook as failed and back off if the response is anything else. Operationally you observe matching success/failure on the Backlog screen, not in HTTP responses.
Worked example: Stripe
Configure Stripe to send all events to:
https://<your-host>/webhooks/<webhookToken>Pick the events you care about (invoice.paid, customer.subscription.deleted, etc.). Stripe sends a JSON payload with type and data.object. In Polyant, define one event definition per business event you care about; the description should reference the discriminator (e.g. “type is invoice.paid”).
Stripe webhook URLs work like any other webhook URL — keep the <webhookToken> portion of the URL secret (rotate via the event source if it leaks). Stripe-style signature verification is not currently performed by the engine.