Jodisius pushes what Ronnie does — completed calls and booked appointments — to your systems as signed JSON webhooks, and lets you put Ronnie on your own website with a one-line chat widget. Both are configured from your Connections page after logging in; this page documents the technical contract.
Add any public HTTPS URL on your Connections page. Events are delivered by POST within about five minutes of occurring. Failed deliveries are retried automatically, up to 3 attempts.
| Event | Fires when |
|---|---|
call.completed | A phone call handled by Ronnie finishes |
appointment.created | Ronnie books a callback or appointment from a call |
test.ping | You press “Send test” on the Connections page |
| Header | Value |
|---|---|
X-Jodisius-Event | The event name, e.g. call.completed |
X-Jodisius-Signature | sha256=<hex> — HMAC-SHA256 of the raw request body, keyed with your webhook’s signing secret (shown once, at creation) |
Content-Type | application/json |
{
"event": "call.completed",
"delivery_id": "9c1f…",
"sent_at": "2026-07-22T14:08:11Z",
"call": {
"id": "…",
"direction": "inbound",
"caller_name": "…",
"caller_number": "+1…",
"status": "completed",
"duration_seconds": 184,
"summary": "…",
"transcript": "…",
"recording_url": "https://…",
"campaign": null,
"occurred_at": "2026-07-22T14:03:00Z"
}
}
Fields the platform doesn’t have for a given call arrive as null — values are never invented.
{
"event": "appointment.created",
"delivery_id": "5aa2…",
"sent_at": "2026-07-22T15:02:40Z",
"appointment": {
"id": "…",
"caller_name": "…",
"callback_number": "+1…",
"requested_at": "2026-07-23T19:00:00Z",
"reason": "…",
"raw_time_phrase": "tomorrow at 3pm",
"created_at": "2026-07-22T15:00:12Z"
}
}
requested_at is null when the caller didn’t give an explicit time — the platform never guesses one.
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(header), Buffer.from(expected));
}
Reply with any 2xx status within 10 seconds. Anything else — or a timeout — counts as a failed attempt and will be retried.
Both consume these webhooks natively: use Webhooks by Zapier → Catch Hook or Make’s Custom webhook module, paste the URL they give you into your Connections page, and press Send test. From there, route Ronnie’s calls and appointments to thousands of apps.
Enable the widget on your Connections page to get your key, then paste one line before </body>:
<script src="https://jodisius.com/assets/ronnie-widget.js"
data-widget-key="jw_…" async></script>
Ronnie answers visitors from your knowledge shelves and business notes only. When the answer isn’t there, she promises a team follow-up instead of guessing. The widget is off by default, capped per day (limit adjustable), can be restricted to your own domains, and its key can be rotated at any time — rotation instantly disables every old embed.
Questions or a system that needs something beyond this? Reach out from your portal — integrations are an active part of the roadmap.