Real-time HTTP POST notifications when events fire in your account. Register an endpoint instead of polling.
https://api.dyva.ai/v1Register endpoints via the API. Each webhook subscribes to one or more event types.
/v1/webhooksAuth RequiredCreate a new webhook subscription.
| 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. |
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/dyva",
"events": [
"message.created",
"conversation.created"
],
"secret": "whsec_k8j7h6g5f4d3s2a1...",
"active": true,
"created_at": "2026-03-09T12:00:00Z"
}curl -X POST https://api.dyva.ai/v1/webhooks \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/dyva",
"events": ["message.created", "conversation.created"]
}'/v1/webhooksAuth RequiredList all webhooks for the current account.
{
"data": [
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/dyva",
"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.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The unique identifier of the webhook. |
| Name | Type | Required | Description |
|---|---|---|---|
url | string | Optional | Updated HTTPS endpoint. |
events | string[] | Optional | Updated list of event types. |
{
"id": "wh_f1e2d3c4b5a6",
"url": "https://yourapp.com/webhooks/dyva-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.
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The unique identifier of the webhook. |
{
"id": "wh_f1e2d3c4b5a6",
"deleted": true
}Subscribe to any combination of these event types.
| 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 | |
dyva.created | A new character was created. |
dyva.updated | A character's configuration was changed. |
dyva.deleted | A character was deleted. |
dyva.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. |
Every delivery sends a JSON payload with a standard envelope. 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. |
{
"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?",
"dyva_id": "rp_7k9m2x4v"
}
}Every request includes an X-Dyva-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with your webhook secret. Always verify before processing.
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/dyva", (req, res) => {
const signature = req.headers["x-dyva-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");
});No 2xx response within 5 seconds triggers retries 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 failed. 100 consecutive failures disables the webhook automatically. Re-enable it via the API once your endpoint is healthy.