Webhooklar
So'rab turish o'rniga biror narsa bo'lganda xabar oling.
Dasturchi → Webhooklar bo'limida (yoki POST /api/v1/webhooks) endpoint ro'yxatdan o'tkazing, hodisalarni tanlang va har bir yetkazishda X-ChatVendor-Signature sarlavhasini tekshiring. Muvaffaqiyatsiz yetkazishlar kechikish bilan qayta uriniladi.
Webhook'lar
Hodisa bo'lganda xabar oling: hodisalar, payload, imzo, qayta urinishlar.
Base URL: https://chatvendor.net/api/v1 · har javob {"success": true, "data": …}
GET
/webhooks
List webhook endpoints
webhooks:manage
Ruxsat: webhooks:manage
Javob 200 · Webhook[]
id stringurl stringevents string: message.queued | message.sent | message.delivered | message.failed | device.online | device.offline | chat.message | chat.message.edited | chat.message.deleted | chat.action | chat.reaction | chat.operator_requested | lead.new | lead.updated | scenario.done | scenario.failed | scenario.cancelled | channel.connected | channel.disconnected | channel.revoked | bot.callback | bot.inline_query | bot.inline_chosen | bot.precheckout | bot.shipping | bot.join_request | bot.stopped | bot.reaction | bot.business_message | bot.paid_media | bot.payment | call.incoming | call.ended | call.group | secret.chat | contact.referral | contact.link_click | contact.updated | comment.new | order.created | order.paid | order.expired | order.updated | booking.created | booking.confirmed | booking.cancelled[]enabled boolean
curl https://chatvendor.net/api/v1/webhooks \
-H "Authorization: Bearer cv_live_xxxxxxxxxxxx"
POST
/webhooks
Create a webhook endpoint
webhooks:manage
Ruxsat: webhooks:manage
So'rov tanasi (application/json)
urlstring (uri)majburiyeventsstring: message.queued | message.sent | message.delivered | message.failed | device.online | device.offline | chat.message | chat.message.edited | chat.message.deleted | chat.action | chat.reaction | chat.operator_requested | lead.new | lead.updated | scenario.done | scenario.failed | scenario.cancelled | channel.connected | channel.disconnected | channel.revoked | bot.callback | bot.inline_query | bot.inline_chosen | bot.precheckout | bot.shipping | bot.join_request | bot.stopped | bot.reaction | bot.business_message | bot.paid_media | bot.payment | call.incoming | call.ended | call.group | secret.chat | contact.referral | contact.link_click | contact.updated | comment.new | order.created | order.paid | order.expired | order.updated | booking.created | booking.confirmed | booking.cancelled[]majburiyJavob 201 · Webhook
id stringurl stringevents string: message.queued | message.sent | message.delivered | message.failed | device.online | device.offline | chat.message | chat.message.edited | chat.message.deleted | chat.action | chat.reaction | chat.operator_requested | lead.new | lead.updated | scenario.done | scenario.failed | scenario.cancelled | channel.connected | channel.disconnected | channel.revoked | bot.callback | bot.inline_query | bot.inline_chosen | bot.precheckout | bot.shipping | bot.join_request | bot.stopped | bot.reaction | bot.business_message | bot.paid_media | bot.payment | call.incoming | call.ended | call.group | secret.chat | contact.referral | contact.link_click | contact.updated | comment.new | order.created | order.paid | order.expired | order.updated | booking.created | booking.confirmed | booking.cancelled[]enabled boolean
curl -X POST https://chatvendor.net/api/v1/webhooks \
-H "Authorization: Bearer cv_live_xxxxxxxxxxxx"
-H "Content-Type: application/json" \
-d '{"url":"…","events":[]}'
PATCH
/webhooks/{webhook}
Update a webhook endpoint
webhooks:manage
Ruxsat: webhooks:manage
Parametrlar
webhookpath · stringmajburiyWebhook public id
Javob 200 · Webhook
id stringurl stringevents string: message.queued | message.sent | message.delivered | message.failed | device.online | device.offline | chat.message | chat.message.edited | chat.message.deleted | chat.action | chat.reaction | chat.operator_requested | lead.new | lead.updated | scenario.done | scenario.failed | scenario.cancelled | channel.connected | channel.disconnected | channel.revoked | bot.callback | bot.inline_query | bot.inline_chosen | bot.precheckout | bot.shipping | bot.join_request | bot.stopped | bot.reaction | bot.business_message | bot.paid_media | bot.payment | call.incoming | call.ended | call.group | secret.chat | contact.referral | contact.link_click | contact.updated | comment.new | order.created | order.paid | order.expired | order.updated | booking.created | booking.confirmed | booking.cancelled[]enabled boolean
curl -X PATCH https://chatvendor.net/api/v1/webhooks/{webhook} \
-H "Authorization: Bearer cv_live_xxxxxxxxxxxx"
DELETE
/webhooks/{webhook}
Delete a webhook endpoint
webhooks:manage
Ruxsat: webhooks:manage
Parametrlar
webhookpath · stringmajburiyWebhook public id
Javob 204
Deleted
curl -X DELETE https://chatvendor.net/api/v1/webhooks/{webhook} \
-H "Authorization: Bearer cv_live_xxxxxxxxxxxx"So'rab turish o'rniga hodisa bo'lganda xabar oling. Endpointni Developer → Webhooks bo'limida yoki yuqoridagi API orqali (webhooks:manage kalit) qo'shing. Har endpointga sir beriladi; har yetkazish imzolanadi.
Hodisalar
Messenjer hodisalari: chat.message, chat.message.edited, chat.message.deleted, chat.action, chat.operator_requested, lead.new, lead.updated, scenario.done|failed|cancelled, channel.connected|disconnected|revoked. Payload ichida channel_id va hodisa ma'lumotlari bo'ladi.
message.queuedXabar navbatga tushdimessage.sentXabar yuborildimessage.deliveredXabar yetib bordimessage.failedXabar yuborilmadidevice.onlineTelefon ulandidevice.offlineTelefon uzildichat.messageChat: yangi xabarchat.message.editedChat: xabar tahrirlandichat.message.deletedChat: xabar o'chirildichat.actionChat: guruh hodisasichat.reactionChat: reaksiyalar o'zgardichat.operator_requestedChat: operator so'raldilead.newLid: yangilead.updatedLid: yangilandiscenario.doneSsenariy: tugadiscenario.failedSsenariy: xatoscenario.cancelledSsenariy: bekor qilindichannel.connectedTarmoq ulandichannel.disconnectedTarmoq uzildichannel.revokedTarmoq sessiyasi bekor qilindibot.callbackBot: tugma bosildibot.inline_queryBot: inline so'rovbot.inline_chosenBot: inline natija tanlandibot.precheckoutBot: to'lov oldi so'rovibot.shippingBot: yetkazib berish so'rovibot.join_requestBot: qo'shilish so'rovibot.stoppedBot: foydalanuvchi botni blokladi/blokdan chiqardibot.reactionBot: reaksiyabot.business_messageBot: biznes xabaribot.paid_mediaBot: pullik media sotib olindibot.paymentBot: hisob-faktura to'landicall.incomingQo'ng'iroq: kiruvchicall.endedQo'ng'iroq: tugadicall.groupQo'ng'iroq: ovozli chat o'zgardisecret.chatMaxfiy chat: so'raldi / qabul qilindi / rad etildicontact.referralKontakt: yangi referalcontact.link_clickKontakt: havola bosildicontact.updatedKontakt: teglar/o'zgaruvchilar o'zgardicomment.newInstagram: yangi kommentorder.createdBuyurtma: yaratildiorder.paidBuyurtma: to'landiorder.expiredBuyurtma: obuna tugadiorder.updatedBuyurtma: yetkazib berish holati o'zgardibooking.createdBandlov: yaratildibooking.confirmedBandlov: tasdiqlandibooking.cancelledBandlov: bekor qilindiPayload
POST https://example.com/webhooks/sms
Content-Type: application/json
X-SMS-Event: message.delivered
X-SMS-Event-Id: evt_01k…
X-SMS-Delivery-Attempt: 1
X-SMS-Signature: t=1754825400,v1=8f3a…
{
"event_id": "evt_01k…",
"event": "message.delivered",
"timestamp": "2026-08-11T09:30:00+00:00",
"data": {
"id": "msg_01k…",
"status": "delivered",
"to": "+998901234567",
"segments": 1,
"client_reference": "order_4389",
"delivered_at": "2026-08-11T09:29:58+00:00"
}
}
Imzoni tekshirish
Compute HMAC SHA-256 over "{timestamp}.{raw body}" with your
endpoint's secret. Sign the raw body — re-encoding the JSON first will
change the bytes and the signature will not match. The timestamp is inside the signed
string, which is what stops a captured payload being replayed later.
// PHP
$raw = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_SMS_SIGNATURE'] ?? '';
parse_str(strtr($header, ',', '&'), $parts);
if (abs(time() - (int) $parts['t']) > 300) {
http_response_code(400); // too old, treat as replay
exit;
}
$expected = hash_hmac('sha256', $parts['t'] . '.' . $raw, $secret);
if (! hash_equals($expected, $parts['v1'])) {
http_response_code(401);
exit;
}
// Node.js (express, raw body required)
app.post('/webhooks/sms', express.raw({ type: 'application/json' }), (req, res) => {
const parts = Object.fromEntries(
req.get('X-SMS-Signature').split(',').map((p) => p.split('=')),
);
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(`${parts.t}.${req.body}`)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))) {
return res.sendStatus(401);
}
res.sendStatus(200); // acknowledge fast, process afterwards
});
Qayta urinishlar
Any 2xx counts as delivered. Anything else is retried 1 min, 5 min, 30 min, 2 h after the first attempt. An endpoint that fails 20 times in a row is disabled automatically — re-enable it once it is fixed.
Every event carries a unique event_id. A retry reuses it,
so store the ones you have processed and ignore repeats — a delivery that timed out on
your side may still have been received.
Reply quickly. We wait 10 seconds; do the real work after responding, not before.
Xabar bo'yicha callback'lar
Passing callback_url on a send delivers that message's
events to that URL as well. Those are not signed — there is no shared
secret behind a one-off URL — so treat them as a hint and confirm with
GET /api/v1/messages/{id} before acting on anything
that matters.