Server API Preview

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.

EventStatusMeaning
conversation.createdSubscribable previewA new support conversation exists.
conversation.assignedSubscribable previewA conversation has an assigned agent or team.
conversation.message.receivedLive smoke testedA visitor/customer message was received.
conversation.closedSubscribable previewA conversation was closed.
contact.createdSubscribable previewA contact was created through Server API or Ringnity flow.
contact.updatedSubscribable previewA contact was updated.
ticket.createdSubscribable previewA support ticket was created.
ticket.updatedSubscribable previewA support ticket was updated.
agent.presence.changedSubscribable previewAn agent presence value changed.
call.startedStagedCall event source must be stable before production automation.
call.endedStagedCall 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.

ConditionStatusWhat to do
2xx responsesuccessRingnity stores the delivery as delivered.
Non-2xx responsefailedResponse code/body are stored in delivery logs.
Network error or timeoutfailedError message and duration are stored in delivery logs.
Webhook disabledskippedNo HTTP request is sent.
Event not subscribedskippedNo HTTP request is sent.
Manual retry

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 reference

Runnable 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"