Asosiy qismga o'tish
ChatVendor ChatVendor

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

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

Ruxsat: webhooks:manage

So'rov tanasi (application/json)

urlstring (uri)majburiy
eventsstring: 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[]majburiy

Javob 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

Ruxsat: webhooks:manage

Parametrlar

webhookpath · stringmajburiy

Webhook 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

Ruxsat: webhooks:manage

Parametrlar

webhookpath · stringmajburiy

Webhook 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 tushdi
message.sentXabar yuborildi
message.deliveredXabar yetib bordi
message.failedXabar yuborilmadi
device.onlineTelefon ulandi
device.offlineTelefon uzildi
chat.messageChat: yangi xabar
chat.message.editedChat: xabar tahrirlandi
chat.message.deletedChat: xabar o'chirildi
chat.actionChat: guruh hodisasi
chat.reactionChat: reaksiyalar o'zgardi
chat.operator_requestedChat: operator so'raldi
lead.newLid: yangi
lead.updatedLid: yangilandi
scenario.doneSsenariy: tugadi
scenario.failedSsenariy: xato
scenario.cancelledSsenariy: bekor qilindi
channel.connectedTarmoq ulandi
channel.disconnectedTarmoq uzildi
channel.revokedTarmoq sessiyasi bekor qilindi
bot.callbackBot: tugma bosildi
bot.inline_queryBot: inline so'rov
bot.inline_chosenBot: inline natija tanlandi
bot.precheckoutBot: to'lov oldi so'rovi
bot.shippingBot: yetkazib berish so'rovi
bot.join_requestBot: qo'shilish so'rovi
bot.stoppedBot: foydalanuvchi botni blokladi/blokdan chiqardi
bot.reactionBot: reaksiya
bot.business_messageBot: biznes xabari
bot.paid_mediaBot: pullik media sotib olindi
bot.paymentBot: hisob-faktura to'landi
call.incomingQo'ng'iroq: kiruvchi
call.endedQo'ng'iroq: tugadi
call.groupQo'ng'iroq: ovozli chat o'zgardi
secret.chatMaxfiy chat: so'raldi / qabul qilindi / rad etildi
contact.referralKontakt: yangi referal
contact.link_clickKontakt: havola bosildi
contact.updatedKontakt: teglar/o'zgaruvchilar o'zgardi
comment.newInstagram: yangi komment
order.createdBuyurtma: yaratildi
order.paidBuyurtma: to'landi
order.expiredBuyurtma: obuna tugadi
order.updatedBuyurtma: yetkazib berish holati o'zgardi
booking.createdBandlov: yaratildi
booking.confirmedBandlov: tasdiqlandi
booking.cancelledBandlov: bekor qilindi

Payload

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.