Webhooks
Webhooks let a client backend receive signed Ringnity events. Use them when a CRM, helpdesk, analytics system, or automation service needs to react without polling.
Need credentials first? Start with Server API.
Receiver URL
Must be HTTPS and publicly reachable. Localhost is not accepted for production delivery.
Signed Payload
Verify X-Ringnity-Signature before trusting the JSON body.
Delivery Logs
Every test delivery records status, response code, body preview, duration, and error message.
Supported event names
These names can be stored in a webhook subscription and used by the test endpoint. Production automation is rolled out per event; conversation.message.received is the live-smoke-tested preview event.
| Event | Status | Meaning |
|---|---|---|
| conversation.created | Subscribable preview | A new support conversation exists. |
| conversation.assigned | Subscribable preview | A conversation has an assigned agent or team. |
| conversation.message.received | Live smoke tested | A visitor/customer message was received. |
| conversation.closed | Subscribable preview | A conversation was closed. |
| contact.created | Subscribable preview | A contact was created through Server API or Ringnity flow. |
| contact.updated | Subscribable preview | A contact was updated. |
| ticket.created | Subscribable preview | A support ticket was created. |
| ticket.updated | Subscribable preview | A support ticket was updated. |
| agent.presence.changed | Subscribable preview | An agent presence value changed. |
| call.started | Staged | Call event source must be stable before production automation. |
| call.ended | Staged | Call event source must be stable before production automation. |
Create a webhook
Store one destination per receiver. If you omit secret, Ringnity generates one and returns it only once in the create response.
curl -X POST "https://api.ringnity.com/api/server/webhooks" \
-H "Authorization: Bearer SERVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "your-tenant-slug CRM webhook",
"url": "https://client.example.com/ringnity/webhook",
"secret": "shared-secret-from-your-receiver",
"events": [
"conversation.message.received",
"conversation.closed"
]
}'Delivery format
Headers
POST /ringnity/webhook Content-Type: application/json User-Agent: Ringnity-Webhooks/1.0 X-Ringnity-Event: conversation.message.received X-Ringnity-Delivery: evt_... X-Ringnity-Timestamp: 1781107000 X-Ringnity-Signature: sha256=<hmac>
Test payload
{
"id": "evt_test_1781107000000",
"type": "conversation.message.received",
"createdAt": "2026-06-11T00:00:00.000Z",
"tenant": {
"slug": "your-tenant-slug"
},
"data": {
"test": true,
"message": "This is a Ringnity webhook test event from the Server API preview."
}
}Verify the signature
Use the raw request body. Do not parse and stringify JSON before verifying, because that changes the bytes that were signed.
import crypto from "node:crypto";
function verifyRingnityWebhook({ secret, timestamp, signatureHeader, rawBody }) {
const received = signatureHeader.replace(/^sha256=/, "");
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(received, "hex"),
Buffer.from(expected, "hex")
);
}Delivery and retry policy
In the current preview, Ringnity records delivery results but does not automatically retry failed deliveries. Treat the receiver as idempotent so retry policy changes can be enabled without duplicate side effects.
| Condition | Status | What to do |
|---|---|---|
| 2xx response | success | Ringnity stores the delivery as delivered. |
| Non-2xx response | failed | Response code/body are stored in delivery logs. |
| Network error or timeout | failed | Error message and duration are stored in delivery logs. |
| Webhook disabled | skipped | No HTTP request is sent. |
| Event not subscribed | skipped | No HTTP request is sent. |
Dashboard manual retry is not part of the current preview. Use POST /api/server/webhooks/test to validate a receiver after fixing it, then inspect delivery logs.
Test and inspect
Send a test event
curl -X POST "https://api.ringnity.com/api/server/webhooks/test" \
-H "Authorization: Bearer SERVER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhookId": "webhook-id",
"event": "conversation.message.received"
}'Read delivery logs
curl "https://api.ringnity.com/api/server/webhooks/deliveries?limit=10" \ -H "Authorization: Bearer SERVER_API_KEY"
Exact API reference
This guide shows the common webhook flow. Use Scalar when you need exact request fields, response bodies, status codes, and error examples generated from OpenAPI.
Open Scalar API referenceRunnable receiver
The SDK repository includes a Node.js receiver in sun_demo_webhook. The live smoke receiver health check is:
curl "https://sadavir.id/ringnity/webhook/health"