Webhooks
Webhooks deliver real-time HTTP POST notifications to your server when events happen in your REPLR account. Instead of polling the API, register an endpoint and receive updates the moment they occur.
https://api.replr.ai/v1Setup
Register webhook endpoints via the API to start receiving events. Each webhook can subscribe to one or more event types.
/v1/webhooksAuth RequiredCreate a new webhook subscription.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Required | The HTTPS endpoint that will receive webhook events. |
events | string[] | Required | List of event types to subscribe to. |
secret | string | Optional | Signing secret for payload verification. Auto-generated if omitted. |
Response
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/replr",
"events": [
"message.created",
"conversation.created"
],
"secret": "whsec_k8j7h6g5f4d3s2a1...",
"active": true,
"created_at": "2026-03-09T12:00:00Z"
}Examples
curl -X POST https://api.replr.ai/v1/webhooks \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/replr",
"events": ["message.created", "conversation.created"]
}'/v1/webhooksAuth RequiredList all webhooks for the current account.
Response
{
"data": [
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/replr",
"events": [
"message.created",
"conversation.created"
],
"active": true,
"created_at": "2026-03-09T12:00:00Z"
},
{
"id": "wh_a6b5c4d3e2f1",
"url": "https://yourapp.com/webhooks/billing",
"events": [
"subscription.created",
"subscription.cancelled"
],
"active": true,
"created_at": "2026-03-08T09:15:00Z"
}
],
"total": 2
}/v1/webhooks/:idAuth RequiredUpdate the URL or subscribed events for an existing webhook.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The unique identifier of the webhook. |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Optional | Updated HTTPS endpoint. |
events | string[] | Optional | Updated list of event types. |
Response
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/replr-v2",
"events": [
"message.created",
"message.failed",
"conversation.created"
],
"active": true,
"created_at": "2026-03-09T12:00:00Z"
}/v1/webhooks/:idAuth RequiredRemove a webhook and stop receiving events.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The unique identifier of the webhook. |
Response
{
"id": "wh_f1e2d3c4b5a6",
"deleted": true
}Events
Subscribe to any combination of the following event types. Use the event type string when creating or updating a webhook.
| Event Type | Description |
|---|---|
| Conversations | |
conversation.created | A new conversation was started. |
conversation.deleted | A conversation was deleted. |
| Messages | |
message.created | A new message was sent or received. |
message.failed | A message failed to deliver. |
| Characters | |
replr.created | A new character was created. |
replr.updated | A character's configuration was changed. |
replr.deleted | A character was deleted. |
replr.published | A character was published to the marketplace. |
| Subscriptions | |
subscription.created | A new subscription was started. |
subscription.updated | A subscription plan was changed. |
subscription.cancelled | A subscription was cancelled. |
| Integrations | |
integration.connected | A platform integration was connected. |
integration.disconnected | A platform integration was disconnected. |
integration.error | A platform integration encountered an error. |
Payload Format
Every webhook delivery sends a JSON payload with a standard envelope. The top-level fields are always present; the data object varies by event type.
| Field | Type | Description |
|---|---|---|
id | string | Unique event identifier. Use this for deduplication. |
type | string | The event type, e.g. "message.created". |
created_at | string | ISO 8601 timestamp of when the event occurred. |
data | object | Event-specific payload containing the relevant resource. |
Example payload
{
"id": "evt_a1b2c3d4e5f6",
"type": "message.created",
"created_at": "2026-03-09T14:22:31Z",
"data": {
"conversation_id": "conv_x9y8z7w6",
"message_id": "msg_m4n5o6p7",
"role": "user",
"content": "Hello, how does this work?",
"replr_id": "rp_7k9m2x4v"
}
}Signature Verification
Every webhook request includes an X-Replr-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret. Always verify this signature before processing the event to ensure the request came from REPLR.
import crypto from "crypto";
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}
// In your request handler
app.post("/webhooks/replr", (req, res) => {
const signature = req.headers["x-replr-signature"];
const rawBody = req.body; // raw string, not parsed JSON
if (!verifyWebhook(rawBody, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(rawBody);
// Process the event...
res.status(200).send("ok");
});Retry Policy
If your endpoint does not respond with a 2xx status code within 5 seconds, REPLR will retry the delivery with exponential backoff.
| Attempt | Delay |
|---|---|
| 1st retry | 10 seconds |
| 2nd retry | 60 seconds |
| 3rd retry | 300 seconds (5 minutes) |
After 3 failed retries, the event is marked as failed. If a webhook accumulates 100 consecutive failures, it is automatically disabled. You can re-enable it by updating the webhook via the API once your endpoint is healthy again.
Best Practices
- •Respond with 2xx quickly. Return a 200 status as soon as you receive the webhook. Defer any heavy processing to a background job or queue so you do not hit the 5-second timeout.
- •Process events asynchronously. Enqueue the event payload and process it outside the request lifecycle. This keeps your endpoint fast and resilient under high throughput.
- •Verify signatures on every request. Always check the
X-Replr-Signatureheader before trusting the payload. This prevents spoofed events from being processed. - •Handle duplicate deliveries. Use the
idfield on each event for idempotency. Store processed event IDs and skip any that you have already handled. - •Use HTTPS endpoints only. Webhook URLs must use HTTPS. Plaintext HTTP endpoints are rejected when creating or updating a webhook.
- •Monitor delivery health. Track failure rates on your end. If your endpoint starts failing, fix the issue before it hits the 100-failure disable threshold.