Webhook'lar
Webhook’lar, LabelGrid hesabınızda bir olay gerçekleştiğinde gerçek zamanlı bildirimler almanızı sağlar. İş akışlarını otomatikleştirmek ve harici sistemlerle entegre olmak için webhook’ları kullanın.
Geliştiriciler için: Webhook’ları API üzerinden programatik olarak da yönetebilirsiniz. Uç noktalar ve örnekler için LabelGrid API Belgeleri sayfasına bakın.
Webhook’lar Nasıl Çalışır
Section titled “Webhook’lar Nasıl Çalışır”- Bir webhook yapılandırırsınız - Bir URL ve hangi olayların dinleneceğini belirtirsiniz
- Bir olay gerçekleşir - Örneğin bir yayın bir mağazaya teslim edilir
- LabelGrid bir POST isteği gönderir - Sunucunuz olay verilerini alır
- Sisteminiz bunu işler - Olaya göre iş akışlarını otomatikleştirin
Webhook’lara Erişim
Section titled “Webhook’lara Erişim”- Sağ üst köşedeki profil simgenize tıklayın
- Açılır menüden Webhooks seçeneğini seçin
Webhook Oluşturma
Section titled “Webhook Oluşturma”- Create Webhook düğmesine tıklayın
- Bu webhook’u tanımlamak için bir Name girin
- Bildirimleri almak istediğiniz URL’yi girin
- Bu webhook’u hangi Events öğelerinin tetikleyeceğini seçin
- Create düğmesine tıklayın
Webhook Gizli Anahtarı
Section titled “Webhook Gizli Anahtarı”Bir webhook oluşturduğunuzda bir gizli anahtar (secret key) alırsınız. Gelen isteklerin gerçekten LabelGrid’den geldiğini doğrulamak için bunu kullanın:
- Gizli anahtarı güvenli bir şekilde saklayın
- Gelen isteklerdeki imzayı doğrulayın
- Anahtar ele geçirilirse yeniden oluşturun
Kullanılabilir Olaylar
Section titled “Kullanılabilir Olaylar”Webhook’unuzu bu olayları dinleyecek şekilde yapılandırın. Olay Tanımlayıcısı (Event Identifier), yükün event özelliğinde ve X-Webhook-Event başlığında göreceğiniz değerdir:
| Olay Tanımlayıcısı | Açıklama |
|---|---|
delivery.completed | Bir yayın bir kanala başarıyla teslim edildiğinde tetiklenir |
delivery.failed | Bir kanala teslimat başarısız olduğunda tetiklenir |
takedown.completed | Bir kaldırma (takedown) talebi tamamlandığında tetiklenir |
release.review.status_changed | Bir yayının inceleme durumu değiştiğinde tetiklenir |
release.distributed | Bir yayın dağıtıldığında tetiklenir |
payment.statement_ready | Bir ödeme hesap özeti görüntülenmeye hazır olduğunda tetiklenir |
Tek bir webhook için birden fazla olay seçebilir ya da farklı olay türleri için ayrı webhook’lar oluşturabilirsiniz.
Webhook’ları Yönetme
Section titled “Webhook’ları Yönetme”Webhook’larınızı Görüntüleme
Section titled “Webhook’larınızı Görüntüleme”Webhook listesi şunları gösterir:
| Sütun | Açıklama |
|---|---|
| Name | Atadığınız webhook adı |
| URL | Bildirimlerin gönderildiği adres |
| Events | Yapılandırılan olay sayısı |
| Status | Aktif veya Pasif |
| Success / Fail | Başarılı ve başarısız teslimat sayısı |
| Last Triggered | Webhook’un en son ne zaman çağrıldığı |
Bir Webhook’u Düzenleme
Section titled “Bir Webhook’u Düzenleme”- Webhook satırındaki Edit işlemine tıklayın
- Adı, URL’yi veya olayları değiştirin
- Save düğmesine tıklayın
Etkinleştirme / Devre Dışı Bırakma
Section titled “Etkinleştirme / Devre Dışı Bırakma”Bir webhook’u silmeden aktif durumunu değiştirin:
- Active - Webhook bildirimleri alır
- Inactive - Webhook duraklatılmıştır, bildirim gönderilmez
Bir Webhook’u Silme
Section titled “Bir Webhook’u Silme”- Webhook satırındaki Delete işlemine tıklayın
- Silme işlemini onaylayın
Webhook’ları Test Etme
Section titled “Webhook’ları Test Etme”Production ortamında bir webhook’a güvenmeden önce test edin:
- Webhook’unuzdaki Test işlemine tıklayın
- LabelGrid, URL’nize bir test yükü gönderir
- Uç noktanızın bunu doğru şekilde alıp işlediğini kontrol edin
Webhook Günlüklerini Görüntüleme
Section titled “Webhook Günlüklerini Görüntüleme”Webhook etkinliğini izleyin ve sorunları giderin:
- Bir webhook’taki View Logs işlemine tıklayın
- Tüm webhook teslimatlarının geçmişini görün
Günlük Ayrıntıları
Section titled “Günlük Ayrıntıları”Her günlük kaydı şunları gösterir:
| Alan | Açıklama |
|---|---|
| Event Type | Bu teslimatı hangi olayın tetiklediği |
| Response Status | Sunucunuzdan dönen HTTP durum kodu |
| Duration | İsteğin ne kadar sürdüğü |
| Attempt | Yeniden deneme sayısı |
| Timestamp | Teslimatın ne zaman gerçekleştiği |
Webhook Yük Biçimi
Section titled “Webhook Yük Biçimi”Bir olay gerçekleştiğinde LabelGrid, URL’nize bir JSON yükü içeren bir POST isteği gönderir:
{ "event": "delivery.completed", "timestamp": "2026-05-05T10:00:00+00:00", "webhook_id": "123", "data": { // Event-specific data }}timestamp alanı ISO 8601 biçimini kullanır. webhook_id, yapılandırdığınız webhook’un ID’sidir (X-Webhook-Id başlığıyla eşleşir).
Olay Yükleri
Section titled “Olay Yükleri”data nesnesinin yapısı, event türüne göre değişir. Aşağıdaki tüm alan türleri, yükte serileştirildiği haliyle JSON türleridir.
delivery.completed
Section titled “delivery.completed”Bir yayın teslimatı kesin başarı durumuna ulaştığında, kanal başına bir kez tetiklenir.
{ "event": "delivery.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete" }}| Alan | Tür | Açıklama |
|---|---|---|
distro_queue_id | integer | Bu teslimat denemesi için dahili kuyruk ID’si |
release_id | integer | Teslim edilen yayın |
release_cat | string | null | Yayın katalog referansınız |
outlet_id | integer | Hedef kanalın ID’si |
outlet_name | string | null | Okunabilir kanal adı (ör. "Spotify") |
status | string | Bu olay için her zaman "complete" |
delivery.failed
Section titled “delivery.failed”Bir yayın teslimatı kesin başarısızlık durumuna ulaştığında, kanal başına bir kez tetiklenir. delivery.completed ile aynı yük, artı bir message alanı.
{ "event": "delivery.failed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "error", "message": "Outlet rejected the delivery: missing ISRC." }}| Alan | Tür | Açıklama |
|---|---|---|
status | string | error, fault, rejected, batch_exception değerlerinden biri |
message | string | null | Kanaldan veya dağıtım süreç hattından gelen başarısızlık nedeni |
takedown.completed
Section titled “takedown.completed”Bir kaldırma talebi başarılı olduğunda, kanal başına bir kez tetiklenir. delivery.completed ile aynı yapı, artı bir takedown: true bayrağı.
{ "event": "takedown.completed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "distro_queue_id": 456, "release_id": 789, "release_cat": "ABC123", "outlet_id": 12, "outlet_name": "Spotify", "status": "complete", "takedown": true }}release.distributed
Section titled “release.distributed”Yayın distributed teslimat durumuna geçtiğinde, yayın başına bir kez tetiklenir. Yalnızca distributed durumuna geçişte tetiklenir; yayın zaten dağıtılmışken sonraki kayıt işlemlerinde tetiklenmez.
{ "event": "release.distributed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "release_cat": "ABC123", "release_title": "Summer EP", "delivery_status": "distributed" }}release.review.status_changed
Section titled “release.review.status_changed”Bir yayın inceleme durumları arasında her geçiş yaptığında tetiklenir.
{ "event": "release.review.status_changed", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "release_id": 789, "release_cat": "ABC123", "release_title": "Summer EP", "previous_status": "to_review", "new_status": "approved" }}| Alan | Tür | Açıklama |
|---|---|---|
previous_status | string | Önceki durum. draft, to_review, approved, rejected, require_changes, audit değerlerinden biri |
new_status | string | Yeni durum. Aynı değer kümesi |
payment.statement_ready
Section titled “payment.statement_ready”Bir ödeme hesap özeti oluşturulup görüntülenmeye hazır olduğunda tetiklenir.
{ "event": "payment.statement_ready", "timestamp": "2026-05-18T10:00:00+00:00", "webhook_id": "123", "data": { "payment_request_id": 1024, "invoice_number": "INV-2026-001", "period": "2026-04-30", "amount": 1234.56, "total_due_usd": 1234.56, "currency": "USD" }}| Alan | Tür | Açıklama |
|---|---|---|
payment_request_id | integer | Dahili ödeme talebi ID’si |
invoice_number | string | Hesap özetine ait fatura referansı |
period | string | null | Dönem sonu tarihi (ISO 8601 tarihi, YYYY-MM-DD) |
amount | number | currency cinsinden hesap özeti tutarı |
total_due_usd | number | USD’ye çevrilmiş hesap özeti toplamı |
currency | string | ISO 4217 para birimi kodu (varsayılan USD) |
Webhook İmzalarını Doğrulama
Section titled “Webhook İmzalarını Doğrulama”Her webhook teslimatı, gerçekten LabelGrid’den geldiğini doğrulayabilmeniz için imzalanır. Olayı işlemeden önce imzayı her zaman doğrulayın.
İstek Başlıkları
Section titled “İstek Başlıkları”Her webhook POST isteği şu başlıkları içerir:
| Başlık | Açıklama |
|---|---|
X-Webhook-Signature | Ham istek gövdesinin HMAC-SHA256 değeri, küçük harfli onaltılık, algoritma öneki olmadan |
X-Webhook-Timestamp | Teslimatın ISO 8601 zaman damgası (gövdedeki timestamp özelliğiyle aynı değer) |
X-Webhook-Event | Olay tanımlayıcısı (ör. delivery.completed) |
X-Webhook-Id | Teslimatı alan webhook’un ID’si |
User-Agent | LabelGrid-Webhooks/1.0 |
Content-Type | application/json |
Algoritma
Section titled “Algoritma”- Algoritma: HMAC-SHA256
- Kodlama: Küçük harfli onaltılık (hexadecimal)
- Önek: Yok. Değer yalnızca onaltılık özettir,
sha256=...değildir - İmzalanan içerik: Ham JSON istek gövdesinin tamamı (gövdenin kendisi zaten zaman damgasını bir özellik olarak içerdiğinden, zaman damgası örtük olarak imzalanır)
Doğrulama Adımları
Section titled “Doğrulama Adımları”- JSON ayrıştırma veya herhangi bir dönüşüm yapmadan önce ham istek gövdesini okuyun. Ayrıştırılmış JSON’u yeniden serileştirmek farklı baytlar üretebilir ve imzayı bozabilir.
HMAC-SHA256(raw_body, your_webhook_secret)değerini hesaplayın ve küçük harfli onaltılık özeti alın.- Sabit zamanlı (constant-time) bir karşılaştırma kullanarak
X-Webhook-Signatureile karşılaştırın. - (Önerilir)
X-Webhook-Timestamp, yineleme (replay) tolerans pencerenizden eskiyse isteği reddedin; 5 dakika öneririz.
PHP Örneği
Section titled “PHP Örneği”$rawBody = file_get_contents('php://input');$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$expected = hash_hmac('sha256', $rawBody, $webhookSecret);
if (! hash_equals($expected, $signature)) { http_response_code(401); exit('Invalid signature');}
// Reject deliveries older than 5 minutesif (abs(time() - strtotime($timestamp)) > 300) { http_response_code(401); exit('Stale delivery');}
$payload = json_decode($rawBody, true);// ... process the eventhttp_response_code(200);Node.js Örneği
Section titled “Node.js Örneği”const crypto = require('crypto');
// Express: capture raw body BEFORE any JSON middlewareapp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const rawBody = req.body; // Buffer const signature = req.header('X-Webhook-Signature') || ''; const timestamp = req.header('X-Webhook-Timestamp') || '';
const expected = crypto .createHmac('sha256', webhookSecret) .update(rawBody) .digest('hex');
const sigBuf = Buffer.from(signature, 'hex'); const expBuf = Buffer.from(expected, 'hex');
if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) { return res.status(401).send('Invalid signature'); }
if (Math.abs(Date.now() - new Date(timestamp).getTime()) > 5 * 60 * 1000) { return res.status(401).send('Stale delivery'); }
const payload = JSON.parse(rawBody.toString('utf8')); // ... process the event res.sendStatus(200);});Python Örneği
Section titled “Python Örneği”import hmac, hashlibfrom datetime import datetime, timezone
raw_body = request.get_data() # Flask: bytes, before any JSON parsingsignature = request.headers.get('X-Webhook-Signature', '')timestamp = request.headers.get('X-Webhook-Timestamp', '')
expected = hmac.new( webhook_secret.encode('utf-8'), raw_body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signature): return ('Invalid signature', 401)
delivery_time = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))if abs((datetime.now(timezone.utc) - delivery_time).total_seconds()) > 300: return ('Stale delivery', 401)
return ('', 200) # process the event, then ackSık Yapılan Hatalar
Section titled “Sık Yapılan Hatalar”- Karma (hash) almadan önce gövdeyi yeniden serileştirmek. JSON’u otomatik ayrıştıran çerçeveler (Express
express.json(), Laravel’in varsayılan istek gövdesi) orijinal baytları kaybeder. Önce ham gövdeyi yakalayın. - Sabit zamanlı olmayan bir karşılaştırma kullanmak (
==,===). Zamanlama saldırılarına açıktır; her zamanhash_equals(PHP),crypto.timingSafeEqual(Node),hmac.compare_digest(Python) ya da dilinizdeki karşılığını kullanın. sha256=öneki beklemek. Başlık değeri, öneksiz, yalnızca onaltılık özettir.- Zaman damgası kontrolünü atlamak. Bu kontrol olmadan, sızdırılan bir imza süresiz olarak yeniden oynatılabilir.
Sınırlar ve Güvenilirlik
Section titled “Sınırlar ve Güvenilirlik”İstek Sınırları
Section titled “İstek Sınırları”| Sınır | Değer |
|---|---|
| İstek zaman aşımı | 10 saniye |
| Azami yük boyutu | 64 KB |
| Kullanıcı başına azami webhook sayısı | 10 |
Uç noktanız 10 saniye içinde yanıt vermezse, teslimat başarısız sayılır ve yeniden denenir.
Yeniden Deneme Çizelgesi
Section titled “Yeniden Deneme Çizelgesi”Uç noktanız 2xx dışında bir durum döndürürse veya zaman aşımına uğrarsa, LabelGrid üstel geri çekilme (exponential backoff) ile yeniden dener:
| Deneme | Yeniden denemeden önceki bekleme |
|---|---|
| 1 → 2 | 30 saniye |
| 2 → 3 | 1 dakika |
| 3 → 4 | 2 dakika |
| 4 → 5 | 4 dakika |
| 5 → 6 | 8 dakika |
| 6 → 7 | 16 dakika |
| 7 → 8 | 32 dakika |
| 8 → 9 | 64 dakika |
| 9 → 10 | 128 dakika |
Her aralık 0-30 saniyelik bir oynama (jitter) içerir. 10 denemeden (toplam yaklaşık 4,5 saat) sonra teslimat kalıcı olarak başarısız kaydedilir ve bir daha denenmez.
Otomatik Devre Dışı Bırakma
Section titled “Otomatik Devre Dışı Bırakma”Bir webhook kümülatif olarak 100 başarısız teslimat biriktirirse otomatik olarak devre dışı bırakılır. Uç noktanızı düzelttikten sonra webhook listesinden manuel olarak yeniden etkinleştirin. Devre dışı bırakılan bir webhook’u yeniden etkinleştirmek, başarısızlık sayacını sıfırlar.
Güvenilirlik için En İyi Uygulamalar
Section titled “Güvenilirlik için En İyi Uygulamalar”- Hızlı bir şekilde (10 saniye içinde) bir 2xx yanıtı döndürün
- Yanıtı verdikten sonra verileri eşzamansız olarak işleyin
- Her istekte imzayı doğrulayın (bkz. Webhook İmzalarını Doğrulama)
- Webhook listesinde başarısızlık sayınızı izleyin
- Kaçırılan olayları araştırırken teslimat günlüklerini kontrol edin
Kullanım Senaryoları
Section titled “Kullanım Senaryoları”Otomatik Bildirimler
Section titled “Otomatik Bildirimler”- Yayınlar yayına girdiğinde Slack mesajları gönderin
- Teslimatlar başarısız olduğunda ekibinize e-posta gönderin
- Dahili panoları güncelleyin
İş Akışı Otomasyonu
Section titled “İş Akışı Otomasyonu”- Yayınlar dağıtıldığında pazarlama kampanyalarını tetikleyin
- Yeni içerik hazır olduğunda web sitenizi güncelleyin
- Durumu harici proje yönetimi araçlarıyla eşitleyin
İzleme ve Uyarı
Section titled “İzleme ve Uyarı”- Teslimat hataları için anında uyarı alın
- Dağıtım ilerlemesini gerçek zamanlı takip edin
- İnceleme durumu değişikliklerini izleyin
Sorun Giderme
Section titled “Sorun Giderme”Webhook Olayları Almıyor
Section titled “Webhook Olayları Almıyor”- Durumu kontrol edin - Webhook aktif mi?
- URL’yi doğrulayın - Uç noktaya internetten erişilebiliyor mu?
- Olayları kontrol edin - Doğru olaylar seçili mi?
- Günlükleri inceleyin - Kayıtlı bir hata var mı?
Yüksek Başarısızlık Sayısı
Section titled “Yüksek Başarısızlık Sayısı”- Uç noktanızı kontrol edin - 200 OK döndürüyor mu?
- Yanıt süresini kontrol edin - Zaman aşımı içinde yanıt veriyor mu?
- Hata mesajlarını inceleyin - Sorun ne?
- Manuel test edin - Bir test webhook’u gönderin
Gizli Anahtarı Yeniden Oluşturma
Section titled “Gizli Anahtarı Yeniden Oluşturma”Webhook gizli anahtarınız ele geçirilirse:
- Webhook ayarlarında Regenerate Secret düğmesine tıklayın
- Uygulamanızı yeni gizli anahtarla güncelleyin
- Eski gizli anahtar anında çalışmayı durdurur
Yardıma mı ihtiyacınız var?
Section titled “Yardıma mı ihtiyacınız var?”Webhook’larla ilgili sorularınız varsa destek ekibimizle iletişime geçin.
LabelGrid’i henüz kullanmıyor musunuz?
Az önce okuduklarınızın tamamı platformumuzda mevcut.
LabelGrid’in neler yapabileceğini keşfedin →