Webhook, Hermetry’nin bir olay gerçekleştiğinde çağırdığı, sisteminizdeki bir adrestir. Bir bilet sistemini, bir ERP’yi, bir mesaj veri yolunu ya da kendi servisinizi beslemek için kullanın. Webhook’lar yöneticiler tarafından Webhooks bölümünde (menünün Developer kısmında) yönetilir. Webhook gönderimi, bunları içeren bir plan gerektirir.
Webhook oluşturma
- Webhooks bölümünü açın ve New Webhook seçeneğini seçin.
- Bir Name girin ve isterseniz bir Description ekleyin (“Bu webhook ne için?”).
- URL girin. HTTPS olmalıdır: “Webhook URL must be a valid HTTPS URL.”
- Events altında en az bir olay seçin. Listede yalnızca kuruluşunuzun kullandığı modüllerin olayları görünür.
- İsteğe bağlı olarak:
- Custom headers (optional): Her çağrıda gönderilen en fazla 20 başlık; örneğin alıcınızın kontrol ettiği bir yetkilendirme belirteci.
Content-Type,User-Agent,Host,Content-LengthveX-Webhook-*ayarlanamaz. Değerler tek satır olmalı ve en fazla 1.000 karakter olabilir. - Event filters (optional, advanced): Bir olayı yalnızca içeriği (payload) eşleştiğinde iletir (aşağıya bakın).
- Tags (optional, comma-separated): Webhook’larınızı düzenlemek için etiketler; en fazla 20.
- Rate limit (optional, deliveries/minute): Boş bırakılırsa sınırsız anlamına gelir.
- Custom headers (optional): Her çağrıda gönderilen en fazla 20 başlık; örneğin alıcınızın kontrol ettiği bir yetkilendirme belirteci.
- Kaydedin. Signing secret değerini şimdi kopyalayın: yalnızca bir kez gösterilir.
IoT modüllerinin tüm olayları, örnek içeriklerle birlikte Webhook event reference sayfasında listelenmiştir.
Olay filtreleri
Olay filtresi, bir olaydan içeriğin eşleşmesi gereken alanlarına giden bir JSON eşlemesidir. İçerik eşleşmezse iletim atlanır. Filtresi olmayan olaylar her zaman iletilir.
{
"alarm.created": { "severity": "CRITICAL" },
"device.disconnected": { "profileId": "6f1c0a2e-0000-4000-8000-000000000001" }
}
Her yol, olayın data alanındaki bir alanı belirtir ve originator.type gibi noktalı olabilir. Listelenen her alan kendi değerine eşit olmalıdır (sayılar ve metinler metin olarak karşılaştırılır, dolayısıyla "2", 2 ile eşleşir). En fazla 50 olayın filtresi olabilir.
Bir iletimin görünümü
Hermetry, şu başlıklarla bir POST gönderir:
| Başlık | Değer |
|---|---|
Content-Type | application/json (varsayılan biçim) veya application/cloudevents+json; charset=utf-8 |
User-Agent | Hermetry-Webhooks/1.0 |
X-Webhook-Event | Olay adı, örneğin device.disconnected |
X-Webhook-Delivery | İletim kimliği. Bir iletimin her yeniden denemesinde ve yeniden iletiminde aynıdır. |
X-Webhook-Timestamp | Bu denemenin imzalandığı Unix saniyesi |
X-Webhook-Signature-V2 | sha256= + "<timestamp>.<body>" değerinin sırrınızla HMAC-SHA256 özeti. Bunu kullanın. |
X-Webhook-Signature | Yalnızca gövdenin HMAC-SHA256 özeti. Eski biçim, bir geçiş dönemi için korunmaktadır. |
X-Webhook-Signature-Prev, X-Webhook-Signature-V2-Prev | Gizli anahtar değişimi sırasında önceki sırla aynı imzalar |
X-Webhook-Manual | Bir yönetici tarafından elle gönderilen olaylarda true |
X-Idempotency-Key | Bir akışın webhook bloğuyla gönderdiği iletilerde |
Varsayılan biçimde gövde bir zarf (envelope) şeklindedir:
{
"webhookId": "…",
"tenantId": "…",
"event": "device.disconnected",
"createdAt": "2026-11-03T12:00:30.000Z",
"data": { "deviceId": "…", "name": "router-17", "reason": "timeout", "…": "…" }
}
Bir yönetici tarafından elle gönderilen olayda ayrıca "manual": true bulunur. Zaman aşımı içinde herhangi bir 2xx durum koduyla yanıt verin. Yanıt gövdesinin ilk 4 KB’ı iletim günlüğünde tutulur.
CloudEvents biçimi
Bir uç nokta bunun yerine yapılandırılmış modda CloudEvents 1.0 alabilir. API üzerinden "format": "cloudevents" ayarlayın (POST veya PATCH /api/webhooks/..., aşağıya bakın). "json" varsayılandır.
{
"specversion": "1.0",
"id": "8d2c…",
"source": "urn:hermetry:tenant:<tenantId>",
"type": "com.hermetry.device.connected",
"datacontenttype": "application/json",
"time": "2026-11-03T10:00:30.000Z",
"data": { "deviceId": "…", "name": "router-17", "transport": "mqtts", "…": "…" },
"tenantid": "<tenantId>",
"webhookid": "<webhookId>"
}
data, varsayılan biçimin data altında tuttuğunun aynısını içerir. id, her yeniden deneme ve yeniden iletimde aynıdır, bu yüzden source ve id üzerinden tekilleştirme yapın. İmza başlıkları her iki biçimde de aynıdır. Toplu (batch) ve ikili (binary) modlar sunulmamaktadır.
İmzayı doğrulayın
Ayrıştırmadan önce ham gövde üzerinden doğrulayın ve eski zaman damgalarını reddedin.
import crypto from 'crypto';
function verifyWebhook(body: string, timestamp: string, signatureV2: string, secret: string): boolean {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex');
// Reject deliveries older than 5 minutes.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const a = Buffer.from(expected);
const b = Buffer.from(signatureV2);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Gizli anahtar değişimi sırasında, X-Webhook-Signature-V2 veya X-Webhook-Signature-V2-Prev değerlerinden biri eşleştiğinde çağrıyı kabul edin.
İletim, yeniden deneme ve ölü harfler
| Ayar | Varsayılan | Aralık |
|---|---|---|
| Request Timeout (ms) | 15,000 | 1.000 ile 120.000 arası |
| Max Delivery Attempts (ilk deneme dahil) | 3 | 1 ile 10 arası |
| Retry Backoff (ms): 1., 2., … yeniden denemeden önceki bekleme | 60000,300000,900000 | 1 ile 9 değer arası, her biri 1.000 ile 86.400.000 arası; listenin sonrasında son değer |
| Circuit Breaker Threshold: Uç noktanın kapatılmasından önceki ardışık hata sayısı | 10 | 1 ile 100.000 arası |
| Default Rate Limit (per minute): Kendi limiti olmayan uç noktalar için | sınırsız | boş veya 0 = sınırsız |
Bunları Webhooks > ayarlar (dişli düğmesi) bölümünde belirleyin. Bir iletim şu durumlardan biridedir: PENDING, SUCCESS, FAILED (yeniden denenecek) veya DEAD_LETTERED (tüm denemeler kullanıldı).
- Her iletim; durumu, denemeleri, yanıt kodu, hata, süre ve bir sonraki yeniden deneme zamanıyla günlüğe kaydedilir.
- Hız sınırını aşan bir uç nokta, iletilerini yaklaşık 60 saniye sonra alır; hiçbiri atılmaz.
- Art arda hata eşiğine ulaşıldıktan sonra uç nokta kapatılır ve otomatik devre dışı olarak görünür. Sıradaki yeniden denemeler durur. Sayacı sıfırlamak için yeniden açın, ardından başarısız olanları yeniden iletin veya tekrar oynatın.
- İletimler en az bir kez yapılır.
X-Webhook-Delivery(veya CloudEventsid) üzerinden tekilleştirme yapın. - Olayların sırayla ulaşacağı garanti edilmez. İçerikteki zamanları kullanın.
Cihaz bağlantısı ve cihaz değişikliği olaylarının kendi hacim koruması vardır: varsayılan olarak, her tür için kuruluş başına dakikada en fazla 600. Bkz. Webhook event reference.
Gizli anahtarı döndürün
Rotate signing secret seçeneğini seçin (Owner rolü). Yeni sır bir kez gösterilir. Önceki sır 48 saat geçerli kalır ve bu süre boyunca her çağrı iki imzayı da taşır. Bu pencere açıkken yeniden döndürmek yalnızca mevcut sırrı değiştirir; öncekinin bitiş tarihi korunur.
Test
Bir webhook’un satır işlemlerinden veya sayfasından:
- Send test event hemen
testadlı bir olay gönderir ve sonucu gösterir (“Test delivered — HTTP 200 in 85 ms”). Bir test asla devre kesiciye (circuit breaker) sayılmaz. - Trigger event… örnek bir içerikle (en fazla 64 KB JSON nesnesi) seçtiğiniz gerçek, imzalı bir olay gönderir; bu olay
manual: trueveX-Webhook-Manual: trueile işaretlenir. Uç noktanın olay filtresine uyar: filtrenin düşüreceği bir örnek reddedilir. - View deliveries iletimleri listeler; başarısız veya ölü harfe düşmüş bir iletim yeniden iletilebilir ve tüm ölü harfler aynı anda tekrar oynatılabilir.
Ağ kuralları
Webhook adresleri genel HTTPS adresleri olmalıdır. Özel, loopback, link-local ve bulut meta veri adresleri kaydederken ve her çağrı yapılırken reddedilir; yönlendirmeler izlenmez. Kasıtlı olarak dahili bir hedef için, bir yönetici API üzerinden webhook’a açık bir ipAllowlist (en fazla 50 adres veya CIDR aralığı) tanımlayabilir.
Webhook API
Yollar /tenant/<tenantId> altındadır. Tümü bir yöneticinin yetkilerini gerektirir.
| Yöntem | Yol | İşlevi |
|---|---|---|
| GET | /api/webhooks/events | Abone olabileceğiniz olaylar |
| GET, POST | /api/webhooks | Listele (page 1’den, pageSize, search, sort, isActive, autoDisabled); oluştur: 201 { webhook, secret } |
| GET, PATCH, DELETE | /api/webhooks/{webhookId} | Oku, değiştir, sil |
| POST | /api/webhooks/{webhookId}/rotate-secret | { webhook, newSecret, overlapMs } (Owner) |
| POST | /api/webhooks/{webhookId}/test | { delivery } |
| POST | /api/webhooks/{webhookId}/trigger | { event, payload } → { message, deliveryId } |
| GET | /api/webhooks/{webhookId}/deliveries | { data, total }; filtreler status, event, createdFrom, createdTo |
| POST | /api/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver | FAILED veya DEAD_LETTERED durumundaki bir teslimatı yeniden kuyruğa al |
| GET, POST | /api/webhooks/{webhookId}/deliveries/replay-dead-letter | Her ölü harfi say veya yeniden kuyruğa al |
| GET | /api/webhooks/metrics, /api/webhooks/report | Teslimat istatistikleri (?webhookId=&days=) |
Oluşturma gövdesi: name, description, url, events, headers, eventFilters, tags, rateLimitPerMinute (1 ile 100.000 arası), ipAllowlist, format (json veya cloudevents).
| Ret | Anlamı |
|---|---|
403 WEBHOOKS_NOT_IN_PLAN | Planınız webhook’ları içermiyor |
409 ENDPOINT_DISABLED | Uç nokta kapalı; önce açın |
409 DELIVERY_NOT_REDELIVERABLE | Teslimat beklemede veya zaten başarıyla tamamlandı |
422 EVENT_FILTERED_OUT | Uç noktanın filtresi, tetiklediğiniz örneği eleyecekti |
422 | Kuruluşunuzdaki hiçbir modülün sunmadığı bir olay |

