UPPU API belgesi

Webhook'lar

UPPU her olayı HTTPS uç noktanıza imzalı bir POST isteğiyle, her istekte tek olay olarak gönderir. Bu sayfa uç noktanın nasıl kurulacağını, imzanın nasıl doğrulanacağını, yanıtı ve yeniden denemeleri, kesintiden sonra eksiğin nasıl tamamlanacağını ve her olayın neye benzediğini anlatır.

Uç noktayı kurun

Uç noktaları firma sahibi UPPU panelinde yönetir: firmanın ayarları, ardından Webhook'lar (parola onayından sonra); bir API anahtarıyla API'den de yönetilir. Bir firmanın en çok 5 uç noktası olur.

Etkinleştirme. Yeni uç nokta ancak iki denetimden sonra olay alır; ikisi de son 60 dakika içinde geçmiş olmalıdır:

  1. Alıcınızı imza doğrulamasıyla birlikte yayına alın.
  2. Test olayı gönder: UPPU sırrınızla imzalanmış örnek bir olay gönderir; uç noktanız 2xx dönmelidir.
  3. Yanlış imzalı deneme gönder: UPPU yanlış bir sırla imzalanmış webhook.test gönderir; uç noktanız onu 2xx dışında herhangi bir durumla reddetmelidir. Bu, imzayı denetlediğinizi gösterir.
  4. Etkinleştir.

Uç nokta etkin değilken oluşan olaylar ona teslim edilmez; onları GET /v1/events ile alın.

UPPU'nun çıkış adresi panelin Webhook'lar sayfasında yazar ve değişmeden 30 gün önce duyurulur. Yalnızca IP süzgecine güvenmeyin: olayın UPPU'dan geldiğini kanıtlayan imzadır.

Uç noktaları API'den yönetin

webhooks:manage kapsamlı bir API anahtarı paneldeki uç noktaların aynısını /v1/webhook-endpoints'te yönetir: listeler, oluşturur, değiştirir ve siler, test olayı ya da yanlış imzalı deneme gönderir, etkinleştirir ve kapatır, imza sırrını döndürür. Bu kapsam hiçbir hazır seçimde yoktur ve var olan anahtarlarda yoktur: firma sahibi Geliştiriciler sayfasında Özel seçimle bir anahtara ekler. Kurallar, 5 uç nokta sınırı ve denetim kayıtları panelinkilerdir; bir uç nokta daha 409 plan_limit_reached alır.

Haftalık test olayı

Bir uç nokta haftalık test olayını açabilir: panelin uç nokta formundan ya da API'de weekly_test: true ile (varsayılan kapalı). UPPU o zaman haftada bir, uç nokta etkin ya da başarısızken, uç noktanın sırrıyla imzalanmış test: true'lu bir webhook.test gönderir. Geçmeyen haftalık test yalnızca uyarıdır: panel uç noktada, API weekly_test.failed_at'te gösterir. Uç nokta bu yüzden hiç askıya alınmaz ve teslimatlar sürer. Uyarıyı geçen haftalık test ya da test olayı, haftalık testin kapatılması ve yeni adres kaldırır.

İstek

Başlık Değer
Content-Type application/json; charset=utf-8
User-Agent UPPU-Webhooks/1.0
webhook-id Olayın kimliği; yeniden denemelerde, yeniden gönderimlerde ve uç noktalarda aynı; gövdenin id'sine eşit
webhook-timestamp Unix saniyesi, her denemede yeni
webhook-signature v1,<base64>; sır yenilenirken boşlukla ayrılmış iki değer
Uppu-Event-Type Olay türü, örneğin message.status
Uppu-Delivery-Id Bu uç noktaya bu teslimat; yeniden gönderim onu korur
Uppu-Attempt İlk denemede 1

Gövde sıkıştırılmış UTF-8 JSON'dur ve her denemede aynı baytlardır:

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6a",
  "object": "event",
  "type": "message.received",
  "api_version": "v1",
  "created_at": "2026-10-20T09:15:01.020Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {"id": "01j9z0ch5k2m4n6p8q0r2s4t6v", "type": "whatsapp"},
  "test": false,
  "data": {}
}

İmzayı doğrulayın

UPPU her isteği Standard Webhooks yöntemiyle imzalar:

  1. Anahtar: sırdan whsec_'i atın, kalanı base64 ile çözün. Anahtar çözülen baytlardır, sırrın metni değil.
  2. İmzalanan içerik: webhook-id + . + webhook-timestamp + . + ham gövde, tam alındığı gibi. Denetimden önce JSON'u asla çözüp yeniden kodlamayın.
  3. İmza: imzalanan içeriğin anahtarla HMAC-SHA256'sı, dolgulu standart base64.
  4. Karşılaştırın: webhook-signature'ı boşluklardan bölün; değeri sizin imzanıza sabit zamanlı karşılaştırmayla eşit olan bir v1,<değer> parçası isteği geçerli kılar.
  5. Reddedin: webhook-id'si olmayan, zaman damgası yalnızca rakam olmayan ya da zaman damgası saatinizden 300 saniyeden fazla uzak olan isteği (saatinizi NTP ile eşit tutun).

Sır yenilenirken UPPU 24 saat boyunca hem yeni hem eski sırla imzalar; iki sır da isteği doğrular. Alıcınızı bu 24 saat içinde yeni sırra geçirin.

Hazır kod: PHP, Node.js, Python ve C#.

Deneme vektörü. Standard Webhooks belirtiminin yayımlanmış deneme vektörü bir uygulamayı çevrimdışı sınar:

Değer
Sır whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw
webhook-id msg_p5jXN8AQM9LWM0D4loKWxJek
webhook-timestamp 1614265330
Gövde {"test": 2432232314}
webhook-signature v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=

Saatinizi vektörün zaman damgasına ayarlayarak sınayın; sır herkese açık bir örnektir, asla gerçek bir sır değildir.

Hızlı yanıt verin

Yeniden deneme, sıra ve askıya alma

Kaçırılan olaylar

GET /v1/events (kapsam events:read, anahtar başına saniyede 2 istek) son 7 günün olaylarını webhook'larla aynı kimlik ve gövdelerle, eskiden yeniye döner.

Olaylar

OlayVarsayılan abonelikSıralama
message.receivedevetkişi
message.statusevetkişi
message.createdhayırkişi
contact.identity_changedevetkişi
contact.consent_changedhayırkişi
contact.erasedevetkişi
template.updatedhayırşablon
channel.status_changedevetkanal
channel.health_changedhayırkanal
conversation.updatedhayırkişi
contact.reachability_changedevetkişi
contact.updated (henüz üretilmiyor)hayırkişi
account.service_stop_scheduledevetfirma hesabı
account.service_resumedevetfirma hesabı
webhook.testher zaman gönderilirsırasız

v1 içinde bilinmeyen olay türleri ve alanlar gelebilir: onları yok sayın. Aşağıdaki örnekler olayların tamamını gösterir; kimlikler ve değerler örnektir.

message.received

Bir kişi herhangi bir kanaldan mesaj gönderdi. data.message mesajdır, data.contact kişidir (identities bu kanaldaki tür başına güncel kimliği taşır; örneğin phone, bsuid, psid, igsid, telegram ya da web_visitor), data.conversation konuşma, data.service_window yanıt penceresidir (web sohbetinde ve Telegram'da null).

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6a",
  "object": "event",
  "type": "message.received",
  "api_version": "v1",
  "created_at": "2026-10-20T09:15:01.020Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "message": {
      "object": "message",
      "id": "01jab3t6ms2m4n6p8q0r2s4t6v",
      "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
      "channel_type": "whatsapp",
      "conversation_id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "direction": "in",
      "author": {
        "type": "contact",
        "label": "Deniz",
        "api_key_prefix": null
      },
      "content": {
        "type": "text",
        "text": {
          "body": "Hello, where is my order?"
        }
      },
      "context": null,
      "template": null,
      "preview": "Hello, where is my order?",
      "status": "received",
      "status_changed_at": null,
      "error": null,
      "client_reference": null,
      "provider_message_id": "PROVIDER-MESSAGE-ID",
      "sent_at": "2026-10-20T09:15:00.000Z",
      "received_at": "2026-10-20T09:15:01.000Z",
      "created_at": "2026-10-20T09:15:01.000Z"
    },
    "contact": {
      "id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "display_name": "Deniz",
      "identities": {
        "phone": "+447700900100",
        "bsuid": "TR.ExampleUser1"
      }
    },
    "conversation": {
      "id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "status": "open",
      "handling": "api"
    },
    "service_window": {
      "open": true,
      "closes_at": "2026-10-21T09:13:00.000Z"
    }
  }
}

message.status

Giden bir mesajın durumu ilerledi: accepted, unknown, sent, delivered, read, failed ya da expired (queued hiç gelmez). Her yazar için gönderilir: API anahtarınız, ekip, UPPU Bot, panelin kampanyası. Gönderiminizle data.message.id ya da data.message.client_reference üzerinden eşleyin; failed'da data.error.code nedeni söyler. expired (kod ttl_expired), UPPU'nun zamanında sağlayıcıya veremediği ttl'li bir gönderimden sonra gelir: hiçbir şey gönderilmedi, previous_status queued. Önceki bir deneme sağlayıcıdan hata yanıtı aldıysa ttl gönderimi bunun yerine o hatayla failed bitirir. Sağlayıcı mesajı yine de aldıysa (UPPU ona ulaşamadı ve denemeyi gitmemiş saydı; seyrek), o denemenin sonraki durumu expired'dan sonra gelir. Kampanya durdurulduğunda ya da iptal edildiğinde sağlayıcıya henüz ulaşmamış kampanya mesajı (yazar türü campaign) da expired (kod ttl_expired) ya da önceki denemenin hatasıyla failed biter.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6b",
  "object": "event",
  "type": "message.status",
  "api_version": "v1",
  "created_at": "2026-10-20T09:20:03.010Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "message": {
      "id": "01jab3a1k9f2m4n6p8q0r2s4t6",
      "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
      "conversation_id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "provider_message_id": "PROVIDER-MESSAGE-ID",
      "client_reference": "order-1001",
      "author": {
        "type": "api",
        "api_key_prefix": "Ab12Cd34Ef56"
      }
    },
    "status": "delivered",
    "previous_status": "sent",
    "occurred_at": "2026-10-20T09:20:03.004Z",
    "error": null
  }
}

message.created

Giden bir mesaj kuyruğa alındı: gelen kutusunda bir temsilci, UPPU, UPPU Bot, panelin bir kampanyası (yazar türü campaign, toplu şablon mesajları) ya da bir API anahtarı tarafından. data message.received biçimindedir; direction out, status queued. Ekibin yanıtlarını kendi sisteminizde göstermek için kullanın.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6c",
  "object": "event",
  "type": "message.created",
  "api_version": "v1",
  "created_at": "2026-10-20T09:20:00.130Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "message": {
      "object": "message",
      "id": "01jab3a1k9f2m4n6p8q0r2s4t6",
      "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
      "channel_type": "whatsapp",
      "conversation_id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "direction": "out",
      "author": {
        "type": "api",
        "label": "Order bot",
        "api_key_prefix": "Ab12Cd34Ef56"
      },
      "content": {
        "type": "text",
        "text": {
          "body": "Your order has shipped.",
          "preview_url": false
        }
      },
      "context": null,
      "template": null,
      "preview": "Your order has shipped.",
      "status": "queued",
      "status_changed_at": "2026-10-20T09:20:00.120Z",
      "error": null,
      "client_reference": "order-1001",
      "provider_message_id": null,
      "sent_at": null,
      "received_at": null,
      "created_at": "2026-10-20T09:20:00.120Z"
    },
    "contact": {
      "id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "display_name": "Deniz",
      "identities": {
        "phone": "+447700900100",
        "bsuid": "TR.ExampleUser1"
      }
    },
    "conversation": {
      "id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "status": "open",
      "handling": "api"
    },
    "service_window": {
      "open": true,
      "closes_at": "2026-10-21T09:13:00.000Z"
    }
  }
}

contact.identity_changed

Bir kişinin WhatsApp kullanıcı kimliği değişti. data.contact_id aynı kalır; saklı kimliği previous'tan current'a güncelleyin. reason değişikliği neyin bildirdiğini söyler: çoğunlukla user_changed_user_id (WhatsApp'ın konuşmadaki bildirimi), kişi telefon numarasını değiştirdiyse user_changed_number (WhatsApp o zaman ona yeni bir kullanıcı kimliği de verir), sahne simülatöründe user_id_update. Bilmediğiniz nedenleri kabul edin.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6d",
  "object": "event",
  "type": "contact.identity_changed",
  "api_version": "v1",
  "created_at": "2026-10-20T10:00:00.050Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
    "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "previous": {
      "type": "bsuid",
      "value": "TR.ExampleUser1"
    },
    "current": {
      "type": "bsuid",
      "value": "TR.ExampleUser2"
    },
    "reason": "user_id_update",
    "occurred_at": "2026-10-20T10:00:00.000Z"
  }
}

contact.consent_changed

Bir izin kaydı eklendi: API ile, STOP, DUR ya da İPTAL yazan kişiyle, WhatsApp'ın pazarlama reddiyle, işletmenin pazarlama mesajlarını WhatsApp'ta durduran kişiyle (source meta_user_preferences; yalnızca pazarlama; WhatsApp'ta yeniden açmak izin değildir: kayıt ve olay yok), UPPU panelinde bir ekip üyesiyle (source agent_recorded) ya da CSV içe aktarmasıyla (source import; yeni her kayıt için bir olay). Olay yazılan kaydı bildirir, kişinin geçerli durumunu değil: daha yeni bir geri çekmeden önce toplanmış izin de kaydedilir ve granted olayı üretir, geri çekme geçerli kalır. Geçerli durumu GET /v1/contacts/{id} yanıtının consents özetinden okuyun. İzin kurallarını UPPU kendisi uygular; olayı kendi listelerinizi güncel tutmak için kullanın.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6e",
  "object": "event",
  "type": "contact.consent_changed",
  "api_version": "v1",
  "created_at": "2026-10-20T09:16:00.030Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
    "consent": {
      "id": "01jab3cn5t2m4n6p8q0r2s4t6v",
      "channel_type": "whatsapp",
      "purpose": "marketing",
      "state": "withdrawn",
      "source": "inbound_keyword",
      "recorded_at": "2026-10-20T09:16:00.000Z"
    }
  }
}

contact.erased

UPPU bir kişiyi sildi (örneğin bir kişisel veri başvurusu üzerine). Kişinin sizdeki kopyasını silin ya da anonimleştirin.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6f",
  "object": "event",
  "type": "contact.erased",
  "api_version": "v1",
  "created_at": "2026-10-20T11:00:00.000Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v"
  }
}

template.updated

Bir WhatsApp şablonunun durumu, kategorisi ya da kalitesi değişti. PAUSED ya da REJECTED olan şablonu göndermeyi bırakın. Zarfın channel'ı null'dır.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6g",
  "object": "event",
  "type": "template.updated",
  "api_version": "v1",
  "created_at": "2026-10-20T08:00:00.000Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": null,
  "test": false,
  "data": {
    "template": {
      "object": "template",
      "id": "01jab3tp1a2m4n6p8q0r2s4t6v",
      "name": "order_update",
      "language": "tr",
      "category": "UTILITY",
      "status": "PAUSED",
      "quality": "YELLOW",
      "channel_ids": [
        "01j9z0ch5k2m4n6p8q0r2s4t6v"
      ]
    },
    "change": {
      "field": "status",
      "previous": "APPROVED",
      "current": "PAUSED",
      "reason": null
    }
  }
}

channel.status_changed

Bir kanalın durumu ya da kipi değişti; örneğin bağlandı, duraklatıldı ya da bağlantısı kesildi. reason nedenini söyler (örneğin token_invalid, disconnected, connected); bilmediğiniz nedenleri kabul edin.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6h",
  "object": "event",
  "type": "channel.status_changed",
  "api_version": "v1",
  "created_at": "2026-10-20T09:00:00.000Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "status": "paused",
    "previous_status": "active",
    "mode": "live",
    "previous_mode": "live",
    "reason": "token_invalid"
  }
}

channel.health_changed

Bir kanalın sağlık özeti değişti (green, amber, red, unknown); reasons yeşil olmayan denetimleri listeler.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6j",
  "object": "event",
  "type": "channel.health_changed",
  "api_version": "v1",
  "created_at": "2026-10-20T09:00:00.500Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "health": {
      "status": "red",
      "previous_status": "green",
      "reasons": [
        "token_invalid"
      ],
      "checked_at": "2026-10-20T09:00:00.000Z"
    },
    "messaging_limit": "TIER_1K",
    "quality": "GREEN"
  }
}

conversation.updated

Bir konuşma değişti: onu kimin tuttuğu, durumu ya da ataması. data.conversation konuşmanın o anki hâlidir (GET /v1/conversations/{id}'nin döndürdüğü nesne), data.change neyin değiştiği, data.reason neden ve data.actor kimin yaptığı (type member, anahtarınızın api_key_prefix'iyle api, bot ya da system). Yeni uç noktada bu olay kapalı gelir: ona açıkça abone olun. UPPU onu yalnızca uç noktalarınızdan biri abone olduğu sürece yazar; GET /v1/events'te de yalnızca o zaman bulunur.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6k",
  "object": "event",
  "type": "conversation.updated",
  "api_version": "v1",
  "created_at": "2026-10-20T12:00:00.012Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
    "type": "whatsapp"
  },
  "test": false,
  "data": {
    "conversation": {
      "object": "conversation",
      "id": "01jab39zcv2m4n6p8q0r2s4t6v",
      "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6v",
      "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "status": "open",
      "handling": "api",
      "assigned": false,
      "handed_over_at": "2026-10-20T12:00:00.000Z",
      "held_by": "team",
      "handover_reason": "api",
      "opened_at": "2026-10-20T11:55:00.000Z",
      "resolved_at": null,
      "last_inbound_at": "2026-10-20T11:55:00.000Z",
      "last_message_at": "2026-10-20T11:56:00.000Z",
      "service_window": {
        "open": true,
        "closes_at": "2026-10-21T11:53:00.000Z"
      }
    },
    "change": "handed_over",
    "reason": "api",
    "actor": {
      "type": "api",
      "api_key_prefix": "k7Hq2mP0aZ1x"
    },
    "occurred_at": "2026-10-20T12:00:00.000Z"
  }
}

contact.reachability_changed

Telegram: kişi botu engelledi ya da engeli kaldırdı ya da Telegram bir gönderimi reddetti. reachable blocked_by_contact ya da send_forbidden ile false, unblocked_by_contact ya da contact_wrote ile true'dur.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6m",
  "object": "event",
  "type": "contact.reachability_changed",
  "api_version": "v1",
  "created_at": "2026-10-21T10:00:00.040Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": {
    "id": "01j9z0tg5k2m4n6p8q0r2s4t6v",
    "type": "telegram"
  },
  "test": false,
  "data": {
    "contact_id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
    "channel_id": "01j9z0tg5k2m4n6p8q0r2s4t6v",
    "identity": {
      "type": "telegram",
      "value": "123456789"
    },
    "reachable": false,
    "reason": "blocked_by_contact",
    "occurred_at": "2026-10-21T10:00:00.000Z"
  }
}

contact.updated

Bir kişi değişti: adı, kimlikleri (eklenen ya da yerine yenisi gelen kimlik; örneğin WhatsApp kullanıcı kimliği ya da sitenizin imzaladığı kullanıcı kimliği), firmanın kişi alanları ya da bir birleştirme ve geri alınması. data.contact kişinin o anki hâlidir (GET /v1/contacts/{id}'nin bütün kanallar anahtarına döndürdüğü nesne), data.changes değişen alanlar (display_name, identities, merged_into, notes, attributes; önceki değerler hiçbir zaman), data.reason değişikliğin nedenidir (member_edited, provider_name, pre_chat, identity_added, identity_rotated, signed_handoff, merged ya da merge_reverted). Yeni uç noktada bu olay kapalı gelir: ona açıkça abone olun. UPPU onu yalnızca uç noktalarınızdan biri abone olduğu sürece yazar; GET /v1/events'te de yalnızca o zaman bulunur.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6m",
  "object": "event",
  "type": "contact.updated",
  "api_version": "v1",
  "created_at": "2026-10-26T12:00:00.012Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": null,
  "test": false,
  "data": {
    "contact": {
      "object": "contact",
      "id": "01j8x7ct5k2m4n6p8q0r2s4t6v",
      "display_name": "Ayşe Yılmaz",
      "blocked": false,
      "merged_into": null,
      "identities": [
        {
          "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6w",
          "type": "web_visitor",
          "value": "wv_01jab3vs5k2m4n6p8q0r2s4t6v",
          "current": true
        },
        {
          "channel_id": "01j9z0ch5k2m4n6p8q0r2s4t6w",
          "type": "external",
          "value": "user-1001",
          "current": true
        }
      ],
      "service_windows": [],
      "consents": [],
      "created_at": "2026-10-25T09:30:00.000Z",
      "notes": null,
      "attributes": {
        "customer_no": "A-1001"
      }
    },
    "changes": [
      "display_name",
      "identities"
    ],
    "reason": "signed_handoff",
    "occurred_at": "2026-10-26T12:00:00.000Z"
  }
}

account.service_stop_scheduled

UPPU ödemeyi daha önce kaydetmezse firmanın hizmeti faturalandırma nedeniyle data.stop_at anında durur: ödemesi uzun süredir gecikti (reason billing_overdue) ya da aboneliği sona erdi (subscription_ended). UPPU'nun durma uyarısıyla, durmadan en az 72 saat önce gönderilir; durma her zaman bir iş günü Türkiye saatiyle 10:00'dadır. O andan sonra anahtarın IP izin listesini geçen çağıranın her API yanıtı geçerli durma anını UPPU-Service-Stop-At başlığında taşır. An yalnızca ileri kayar: UPPU'nun uyarısı kimseye ulaşmayıp yeniden gönderilirse ikinci bir account.service_stop_scheduled daha geç anı bildirir; başlık her zaman güncel anı taşır.

{
  "id": "01jace0s7p2m4n6p8q0r2s4t6m",
  "object": "event",
  "type": "account.service_stop_scheduled",
  "api_version": "v1",
  "created_at": "2026-10-26T07:00:00.012Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": null,
  "test": false,
  "data": {
    "stop_at": "2026-10-29T07:00:00.000Z",
    "reason": "billing_overdue",
    "occurred_at": "2026-10-26T07:00:00.000Z"
  }
}

account.service_resumed

Faturalandırma nedeniyle durmuş hizmet yeniden çalışıyor: stopped_at durduğu, resumed_at yeniden açıldığı an. service_stopped ile ölen teslimatları panelden yeniden gönderin; hiçbir şey kendiliğinden yeniden gönderilmez. account.service_stop_scheduled gibi yeni uç noktada varsayılan olarak seçilidir ve ona abone her uç noktaya kanal süzgecinden bağımsız gider.

{
  "id": "01jace0r3s2m4n6p8q0r2s4t6m",
  "object": "event",
  "type": "account.service_resumed",
  "api_version": "v1",
  "created_at": "2026-10-30T11:42:10.512Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": null,
  "test": false,
  "data": {
    "stopped_at": "2026-10-29T07:00:00.000Z",
    "resumed_at": "2026-10-30T11:42:10.500Z",
    "occurred_at": "2026-10-30T11:42:10.500Z"
  }
}

webhook.test

Panelin ve API'nin test olayı ve yanlış imzalı denemesi ile haftalık test olayı gönderir, her zaman test: true ile. Saklanmaz ve GET /v1/events'te hiç görünmez.

{
  "id": "01jace0e1v2m4n6p8q0r2s4t6n",
  "object": "event",
  "type": "webhook.test",
  "api_version": "v1",
  "created_at": "2026-10-20T09:15:02.481Z",
  "team_id": "01j8x7tm5k2m4n6p8q0r2s4t6v",
  "channel": null,
  "test": true,
  "data": {
    "note": "UPPU test olayı",
    "endpoint_id": "01jab3ep5k2m4n6p8q0r2s4t6v"
  }
}