Tempo WhatsApp GatewayAPI Dokümanı

Tempo WhatsApp Gateway API

Kendi yazılımınızdan (ERP, CRM, e-ticaret, muhasebe) WhatsApp üzerinden mesaj, belge ve resim gönderin; teslim, okundu ve gelen mesaj bilgisini webhook ile anında alın. Instance ID ve gizli anahtarla çalışan sade bir REST API'dir; her dilden birkaç satırla kullanılır.

Genel bakış

Her WhatsApp numaranız bir instance'tır. Numara eklediğinizde müşteri panelinde iki bilgi üretilir:

Instance IDNumaranın kimliği, ör. inst1001. API adresinin parçasıdır.
Gizli anahtar (token)40 karakterlik anahtar. Yalnızca bir kez gösterilir; kaybolursa panelden yenilenir.
API adresihttps://wa.tempomsg.com/{instanceId}/

Bu bilgileri müşteri panelinde API Bilgileri ekranında bulursunuz. Tüm istekler HTTPS ile yapılmalıdır.

Kimlik doğrulama

Her istekte gizli anahtar gönderilir. İki yol vardır:

  • token parametresi (sorgu, form ya da JSON gövdesinde).
  • X-Api-Token HTTP başlığı — anahtarın sunucu loglarında görünmemesi için önerilir.
Gizli anahtarı tarayıcıda çalışan koda (web sayfası JavaScript'i, mobil uygulama) koymayın; yalnızca kendi sunucunuzdan kullanın. Anahtar ele geçerse panelden hemen yenileyin, eski anahtar o anda geçersiz olur.

Hatalı instance ya da anahtar: 401 ve {"error":"instance veya token hatalı"}.

İstek ve yanıt biçimi

Parametreler şu biçimlerden biriyle gönderilebilir; hepsi aynı sonucu verir:

  • application/x-www-form-urlencoded (önerilen)
  • multipart/form-data
  • application/json
  • Sorgu parametresi (?token=...&to=...)

Yanıtlar her zaman JSON'dur. Başarılı gönderim:

200 OK
{"sent":"true","message":"ok","id":1234}

Hata durumunda uygun HTTP kodu ve error alanı döner:

400 Bad Request
{"error":"to geçersiz: ülke koduyla telefon numarası (905321234567) veya grup ID'si (...@g.us) olmalı"}

Telefon ve grup biçimi

to alanına şunlardan biri yazılır:

YazılanAnlamı
905321234567Ülke koduyla telefon (önerilen biçim). Boşluk, +, tire ve parantez temizlenir.
+90 532 123 45 67Kabul edilir, 905321234567 olarak işlenir.
05321234567 · 5321234567Türkiye numarası olarak kabul edilir, başına 90 eklenir.
905321234567@c.usWhatsApp kişi kimliği biçimi; numara olarak işlenir.
120363041234567890@g.usGrup. Kimliği Gruplar uç noktasından alın.
Mesaj yalnızca WhatsApp kullanan numaralara iletilir. Numara WhatsApp'ta yoksa mesaj durumu unsent olur ve error alanında sebebi yazar.

Hızlı başlangıç

  1. Müşteri panelinde Numara Ekle ile numara oluşturun; Instance ID ve gizli anahtarı kaydedin.
  2. Panelde gösterilen QR kodunu WhatsApp → Bağlı cihazlar → Cihaz bağla ile okutun.
  3. Aşağıdaki isteği kendi bilgilerinizle gönderin; yanıtta "sent":"true" görmelisiniz.
  4. Teslim ve okundu bilgisini almak için bir webhook adresi tanımlayın.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/chat" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "body=Merhaba, siparişiniz hazır."

Metin mesajı gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/chat
ParametreAçıklama
tokenZORUNLUGizli anahtar (ya da X-Api-Token başlığı).
toZORUNLUAlıcı telefon numarası ya da grup kimliği. Biçimler
bodyZORUNLUMesaj metni, en fazla 4.096 karakter. Emoji ve satır sonu (\n) desteklenir. WhatsApp biçimleri kullanılabilir: *kalın*, _italik_, ~üstü çizili~.
referenceIdİSTEĞE BAĞLIKendi kayıt numaranız (ör. sipariş no), en fazla 100 karakter. Mesaj listesinde ve teslim/okundu webhook'unda size geri döner; eşleştirmeyi kolaylaştırır.
priorityİSTEĞE BAĞLI0–10 arası öncelik, varsayılan 5. Küçük sayı önce gönderilir (0 en acil). Toplu kampanyalar için 9–10, şifre/OTP gibi acil mesajlar için 0–1 kullanın.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/chat" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "body=Merhaba Ahmet Bey, 10482 numaralı siparişiniz kargoya verildi." \
  --data-urlencode "referenceId=SIPARIS-10482"
Yanıt · 200 OK
{"sent":"true","message":"ok","id":1234}

id, mesajın Gateway'deki numarasıdır. Durumunu GET /messages?id=1234 ile sorgulayabilirsiniz.

Belge gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/document

PDF, Excel, Word, ZIP gibi her türlü dosya. Dosya iki şekilde verilebilir:

  • Adres: herkese açık bir https:// adresi. Gateway dosyayı indirip gönderir. İç ağ adresleri (localhost, 192.168.x.x vb.) güvenlik nedeniyle kabul edilmez.
  • Base64: dosya içeriği base64 olarak (başında data:application/pdf;base64, olabilir). Dosya sunucunuzda erişilebilir değilse bunu kullanın.
ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
documentZORUNLUDosya adresi (https) ya da base64 içerik. En fazla 16 MB.
filenameÖNERİLİRAlıcının göreceği dosya adı, uzantısıyla (ör. Fatura-2026-0142.pdf). Dosya türü uzantıdan belirlenir.
captionİSTEĞE BAĞLIDosyanın altındaki açıklama, en fazla 1.024 karakter.
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.

Adres ile

curl -X POST "https://wa.tempomsg.com/inst1001/messages/document" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "document=https://ornek.com/faturalar/2026-0142.pdf" \
  --data-urlencode "filename=Fatura-2026-0142.pdf" \
  --data-urlencode "caption=Faturanız ektedir."

Base64 ile

var base64 = Convert.ToBase64String(await File.ReadAllBytesAsync("Fatura.pdf"));

using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["token"] = "GIZLI_ANAHTAR",
    ["to"] = "905321234567",
    ["document"] = base64,
    ["filename"] = "Fatura.pdf",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/document", veri);
Base64 içerik dosyadan yaklaşık %33 büyüktür; 16 MB'lık dosya için istek gövdesi ~21 MB olur. Büyük dosyalarda adres ile göndermek daha hızlıdır.

Resim gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/image

Resim, sohbet içinde önizlemeli görünür (belge olarak değil). Parametreler belge ile aynıdır; dosya alanının adı image'dır. filename resim uzantısı taşımalıdır (.jpg, .png, .webp).

curl -X POST "https://wa.tempomsg.com/inst1001/messages/image" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "image=https://ornek.com/urunler/kampanya.jpg" \
  --data-urlencode "filename=kampanya.jpg" \
  --data-urlencode "caption=Hafta sonuna özel %20 indirim!"

Video gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/video

Sohbette oynatılabilir video (MP4 önerilir). Dosya alanı video; adres ya da base64 olarak, belge ile aynı kurallarla verilir.

ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
videoZORUNLUVideo adresi (https) ya da base64. En fazla 16 MB.
filenameİSTEĞE BAĞLIUzantıyla dosya adı (ör. tanitim.mp4). Uzantı video olmalıdır.
captionİSTEĞE BAĞLIAçıklama, en fazla 1.024 karakter.
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/video" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "video=https://ornek.com/tanitim.mp4" \
  --data-urlencode "filename=tanitim.mp4" \
  --data-urlencode "caption=Yeni ürünümüz"

Ses dosyası ve sesli not

POSThttps://wa.tempomsg.com/{instanceId}/messages/audio

/messages/audio ses dosyasını oynatılabilir dosya olarak, /messages/voice ise WhatsApp sesli notu (mikrofon simgesiyle) olarak gönderir. Sesli not için MP3 de verebilirsiniz; Gateway gerekli biçime çevirir. Dosya alanının adı her ikisinde de audio'dur; sesli not açıklama almaz.

POSThttps://wa.tempomsg.com/{instanceId}/messages/voice
ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
audioZORUNLUSes dosyası adresi (https) ya da base64 (mp3, ogg, m4a, wav…).
filenameİSTEĞE BAĞLIUzantıyla dosya adı (ör. duyuru.mp3).
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/voice" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "audio=https://ornek.com/duyuru.mp3" \
  --data-urlencode "filename=duyuru.mp3"

Sticker gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/sticker

Sticker yalnızca WebP biçiminde olabilir (512×512 önerilir). Dosya alanı sticker; açıklama almaz.

ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
stickerZORUNLUWebP dosyasının adresi (https) ya da base64.
filenameİSTEĞE BAĞLIör. tesekkurler.webp
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/sticker" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "sticker=https://ornek.com/tesekkurler.webp"

Konum gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/location

Haritada açılan konum mesajı gönderir; mağaza, şube ya da teslimat adresi için kullanışlıdır.

ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
latZORUNLUEnlem, ondalık (ör. 41.0082).
lngZORUNLUBoylam, ondalık (ör. 28.9784).
addressİSTEĞE BAĞLIKonumun altında görünen ad / adres.
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/location" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "lat=41.0082" \
  --data-urlencode "lng=28.9784" \
  --data-urlencode "address=Tempo Bilişim Merkez Ofis"

Kişi kartı gönderme

POSThttps://wa.tempomsg.com/{instanceId}/messages/contact

Bir ya da birkaç telefon numarasını kişi kartı olarak paylaşır; alıcı tek dokunuşla rehberine ekleyebilir. Kartı kendiniz hazırlamak isterseniz /messages/vcard ile vCard metni gönderin.

POSThttps://wa.tempomsg.com/{instanceId}/messages/vcard
ParametreAçıklama
tokenZORUNLUGizli anahtar.
toZORUNLUAlıcı telefon numarası ya da grup kimliği.
contactZORUNLU/messages/contact için: paylaşılacak numara(lar), virgülle en fazla 5 (ör. 905321234567,905551112233).
nameİSTEĞE BAĞLI/messages/contact için: kartta görünecek ad (tek numarada).
vcardZORUNLU/messages/vcard için: BEGIN:VCARD … END:VCARD metni, en fazla 8.000 karakter. Birden fazla kart art arda yazılabilir.
referenceId, priorityİSTEĞE BAĞLIMetin mesajındaki gibi.
curl -X POST "https://wa.tempomsg.com/inst1001/messages/contact" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "to=905321234567" \
  --data-urlencode "contact=905551112233" \
  --data-urlencode "name=Tempo Destek"

Kuyruk ve gönderim sırası

Gönderim istekleri hemen kuyruğa alınır ve yanıt beklemeden döner. Yanıttaki "sent":"true" mesajın kuyruğa alındığını gösterir; WhatsApp'a gerçekten gidip gitmediği, teslim edilip okunduğu ayrıca izlenir:

  • Webhook ile (önerilen): message_ack olayı teslim ve okunduğunda size bildirir.
  • Sorgu ile: GET /messages ile mesajın durumuna bakın.

Numaranızın engellenmemesi için aynı numaradan iki mesaj arasında 3–8 saniye rastgele bekleme yapılır. Numara bağlantısı koparsa mesajlar kuyrukta bekler, bağlantı gelince gönderilir. Geçici hatalarda mesaj en fazla 5 kez yeniden denenir.

Mesaj durumu ve geçmiş

GEThttps://wa.tempomsg.com/{instanceId}/messages
ParametreAçıklama
tokenZORUNLUGizli anahtar.
statusİSTEĞE BAĞLIall (varsayılan), queue (bekleyen), sent (gönderilen), unsent (gönderilemeyen), cancelled (iptal edilen).
idİSTEĞE BAĞLITek mesaj: gönderim yanıtındaki id.
referenceIdİSTEĞE BAĞLIGönderirken verdiğiniz kendi numaranız.
page, limitİSTEĞE BAĞLISayfalama. limit en fazla 100. Kayıtlar en yeniden eskiye sıralanır.
curl -G "https://wa.tempomsg.com/inst1001/messages" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "referenceId=SIPARIS-10482"
Yanıt · 200 OK
{
  "total": 1,
  "page": 1,
  "limit": 100,
  "messages": [
    {
      "id": 1234,
      "referenceId": "SIPARIS-10482",
      "to": "905321234567",
      "type": "chat",
      "body": "Siparişiniz kargoya verildi.",
      "filename": "",
      "status": "sent",
      "ack": "read",
      "error": "",
      "attempts": 1,
      "created_at": "2026-11-15 09:12:03",
      "sent_at": "2026-11-15 09:12:07",
      "delivered_at": "2026-11-15 09:12:08",
      "read_at": "2026-11-15 09:14:51"
    }
  ]
}
AlanDeğerler
statusqueue kuyrukta · sent WhatsApp'a gönderildi · unsent gönderilemedi (error alanına bakın) · cancelled müşteri panelinden iptal edildi
ackserver WhatsApp sunucusuna ulaştı (tek tik) · device alıcının telefonuna teslim edildi (çift tik) · read okundu (mavi tik)
…_atOluşturma, gönderim, teslim ve okunma zamanları (Türkiye saati, yyyy-MM-dd HH:mm:ss).
Alıcı okundu bilgisini kapattıysa read gelmez; mesaj device durumunda kalır.

Mesaj işlemleri

Gönderdiğiniz mesajlara tepki verme, herkesten silme, gönderilemeyenleri yeniden gönderme, kayıt temizleme ve özet sayılar. msgId alanına gönderim yanıtındaki id'yi (ör. 1234) ya da webhook'ta gelen WhatsApp mesaj kimliğini (true_905321234567@c.us_3EB0…) yazabilirsiniz.

POST /messages/reaction

Mesaja emoji ile tepki verir. msgId, emoji (ör. 👍). Boş emoji tepkiyi kaldırır. Numara bağlı olmalıdır.

curl -X POST "https://wa.tempomsg.com/inst1001/messages/reaction" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "msgId=1234" \
  --data-urlencode "emoji=👍"

POST /messages/delete

Gönderilmiş mesajı herkesten siler. msgId; WhatsApp mesaj kimliği kullanıyorsanız gerekirse chatId de gönderin. WhatsApp yalnızca yakın zamanda gönderilen mesajların silinmesine izin verir.

POST /messages/resendByStatus

status: unsent (gönderilemeyenler) ya da cancelled (iptal edilenler). Hepsi yeniden kuyruğa alınır; yanıtta count döner.

POST /messages/resendById

id: gönderilemeyen ya da iptal edilen tek mesajı yeniden kuyruğa alır.

POST /messages/clear

status: queue kuyruktakileri iptal eder (yanlışlıkla başlatılan toplu gönderimi durdurmak için); sent, unsent, cancelled ilgili kayıtları siler. Yanıtta count döner.

curl -X POST "https://wa.tempomsg.com/inst1001/messages/clear" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "status=queue"

GET /messages/statistics

Numaranın mesaj sayıları.

Yanıt · 200 OK
{
  "queue": 3,
  "sent": 1840,
  "delivered": 1795,
  "read": 1512,
  "unsent": 4,
  "cancelled": 120,
  "sent_today": 86
}

Gruplar

GEThttps://wa.tempomsg.com/{instanceId}/groups

Numaranızın üye olduğu grupları listeler. Gruba mesaj göndermek için buradaki id'yi to alanına yazın. Numaranın grupta mesaj yazma izni olmalıdır.

curl -G "https://wa.tempomsg.com/inst1001/groups" \
  --data-urlencode "token=GIZLI_ANAHTAR"
Yanıt · 200 OK
[
  { "id": "120363041234567890@g.us", "name": "Satış Ekibi", "participants": 14 },
  { "id": "120363049876543210@g.us", "name": "Depo Bildirimleri", "participants": 6 }
]

Bağlantı durumu

GEThttps://wa.tempomsg.com/{instanceId}/instance/status
curl -G "https://wa.tempomsg.com/inst1001/instance/status" \
  --data-urlencode "token=GIZLI_ANAHTAR"
Yanıt · 200 OK
{
  "status": { "accountStatus": { "status": "authenticated", "substatus": "connected" } },
  "phone": "905408524675"
}
status / substatusAnlamı
authenticated / connectedNumara bağlı, mesaj gönderilebilir.
qr / qrQR kodu okutulmayı bekliyor.
loading / loadingBağlantı başlatılıyor.
disconnected / failed · stoppedBağlantı koptu. Panelden QR ile yeniden bağlayın; mesajlar kuyrukta bekler.

QR kodu

GEThttps://wa.tempomsg.com/{instanceId}/instance/qr

Numara QR beklerken PNG resim döner (image/png). Numara bağlıysa ya da oturum başlıyorsa 409 ve açıklama döner. QR kodu yaklaşık 20 saniyede bir yenilenir; kendi ekranınızda gösterecekseniz birkaç saniyede bir yeniden isteyin. Çoğu durumda müşteri panelindeki QR ekranını kullanmanız yeterlidir.

curl -G "https://wa.tempomsg.com/inst1001/instance/qr" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  -o qr.png

Bağlantıyı kes / yeniden başlat

POSThttps://wa.tempomsg.com/{instanceId}/instance/logout

WhatsApp oturumunu kapatır (telefonda "Bağlı cihazlar" listesinden çıkar). Instance ID ve gizli anahtar değişmez; yeniden bağlamak için QR okutulur.

POSThttps://wa.tempomsg.com/{instanceId}/instance/restart

Oturumu yeniden başlatır; bağlantı takılırsa kullanın. Bağlantı korunur, QR gerekmez.

curl -X POST "https://wa.tempomsg.com/inst1001/instance/restart" \
  --data-urlencode "token=GIZLI_ANAHTAR"

Numara bilgisi ve kuyruk

GET /instance/me

Bağlı numaranın WhatsApp kimliği, telefonu ve profil adı.

Yanıt · 200 OK
{
  "id": "905321234567@c.us",
  "phone": "905321234567",
  "name": "Tempo Market"
}

GET /instance/qrCode

QR kodunu resim yerine metin olarak döner ({"qrCode":"2@…"}); kendi ekranınızda QR kütüphanesiyle çizmek için. Numara bağlıysa 409.

POST /instance/clear

Numaranın kuyruğunda bekleyen tüm mesajları iptal eder; bağlantıya dokunmaz. Yanıtta cancelled sayısı döner.

Sohbetler

Numaranın WhatsApp sohbetleri. Bu uç noktalar doğrudan telefondaki verileri okur; numara bağlı olmalıdır. chatId alanına telefon numarası (905321234567), 905321234567@c.us ya da grup kimliği yazılabilir.

GET /chats

Son mesajıyla birlikte sohbet listesi, en yeniden eskiye. page, limit (en fazla 100).

Yanıt · 200 OK
[
  {
    "id": "905321234567@c.us",
    "name": "Ahmet Yılmaz",
    "picture": "",
    "isGroup": false,
    "last_message": { "body": "Teşekkürler", "fromMe": false, "time": 1794716400 }
  }
]

GET /chats/ids

Yalnızca sohbet kimlikleri (dizi).

GET /chats/messages

Bir sohbetin son mesajları. chatId, page, limit (en fazla 100). Her kayıtta id, from, to, author (grupta yazan), fromMe, type, body, ack, time (Unix zamanı) bulunur.

curl -G "https://wa.tempomsg.com/inst1001/chats/messages" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "chatId=905321234567" \
  --data-urlencode "limit=20"

POST /chats/read

Sohbetteki gelen mesajları okundu (mavi tik) olarak işaretler. chatId.

Kişiler ve numara kontrolü

Numaranın rehberi ve bir numaranın WhatsApp kullanıp kullanmadığının kontrolü. Numara bağlı olmalıdır.

GET /contacts

Kişi listesi: id, number, name, pushname, isMyContact, isBusiness. page, limit (en fazla 500).

GET /contacts/ids

Yalnızca kişi kimlikleri (dizi).

GET /contacts/contact

Tek kişinin bilgisi. chatId.

GET /contacts/check

Numara WhatsApp kullanıyor mu? chatId (ör. 905321234567). Toplu gönderim öncesi listenizi temizlemek için kullanın; WhatsApp kullanmayan numaralar kaydedilir ve /contacts/invalid ile listelenir.

curl -G "https://wa.tempomsg.com/inst1001/contacts/check" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "chatId=905321234567"
Yanıt · 200 OK
{
  "status": "valid",
  "chatId": "905321234567@c.us"
}

GET /contacts/invalid

Kontrolde WhatsApp kullanmadığı görülen numaralar: phone, checked_at.

GET /contacts/image

Kişinin profil resmi adresi: {"success":"https://…"}. Kişi profil resmini gizlediyse boş döner. chatId.

Kişi engelleme, sohbet arşivleme ve sohbet silme WhatsApp altyapısı tarafından desteklenmediği için API'de yoktur.

Grup ayrıntısı

GET /groups/ids

Yalnızca grup kimlikleri (dizi).

GET /groups/group

Grubun adı, açıklaması ve üyeleri. groupId (ör. 120363012345678901@g.us). Üye rolü: participant, admin, superadmin.

curl -G "https://wa.tempomsg.com/inst1001/groups/group" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "groupId=120363012345678901@g.us"

Medya yükleme

Aynı dosyayı çok sayıda alıcıya gönderecekseniz bir kez yükleyin, dönen adresi document, image, video gibi alanlarda kullanın. Yüklenen dosyalar 30 gün saklanır.

POST /media/upload

file: multipart/form-data ile dosya ya da base64 içerik. filename (base64 için önerilir). En fazla 16 MB.

curl "https://wa.tempomsg.com/inst1001/media/upload" \
  -F "token=GIZLI_ANAHTAR" \
  -F "file=@Katalog-2026.pdf"
Yanıt · 200 OK
{
  "success": "https://wa.tempomsg.com/medya/3f9c…",
  "filename": "Katalog-2026.pdf",
  "mimetype": "application/pdf",
  "size": 482113,
  "expires_days": 30
}

POST /media/delete

Yüklenen dosyayı süresinden önce siler. url: yükleme yanıtındaki adres.

POST /media/deleteByDate

date (yyyy-MM-dd) tarihinden önce yüklenen ve gelen tüm dosyaları siler; yanıtta count döner.

Webhook nedir

Webhook, bir olay olduğunda (müşteriniz size yazdığında, mesajınız teslim edildiğinde ya da okunduğunda, bağlantı koptuğunda) Gateway'in sizin belirlediğiniz adrese anında JSON gönderdiği sistemdir. Durum sorgulamak için sürekli istek atmanıza gerek kalmaz.

Webhook adresiniz:

  • İnternetten erişilebilir bir https:// adresi olmalı (iç ağ adresleri kabul edilmez).
  • POST isteği almalı ve 10 saniye içinde 2xx (ör. 200) dönmeli. Uzun işlemleri arka planda yapın.
  • Her isteğin imzasını doğrulamalı.

Webhook ayarları

POSThttps://wa.tempomsg.com/{instanceId}/instance/settings
ParametreAçıklama
webhook_urlOlayların gönderileceği adres. Boş gönderirseniz webhook kapanır.
webhook_message_receivedtrue/false — size gelen mesajlar (message_received).
webhook_message_createNumaranızdan giden mesajlar (message_create); telefondan elle yazılanlar dahil.
webhook_message_ackTeslim edildi ve okundu bildirimleri (message_ack).
webhook_instance_statusBağlantı durumu değişiklikleri (instance_status).
webhook_message_reactionMesajlara emoji ile verilen tepkiler (message_reaction).
webhook_download_mediatrue ise gelen resim, belge ve seslerde data.media alanına 24 saat geçerli indirme bağlantısı eklenir.
webhook_retriesAdresiniz yanıt vermezse olayın en fazla deneme sayısı (1–10). Boş gönderilirse sistem varsayılanı (3) geçerli olur.
webhook_secret_regeneratetrue gönderilirse yeni imza anahtarı üretilir ve yanıtta bir kez gösterilir.

Gönderilmeyen alanlar değişmez. Adres ilk kez tanımlandığında imza anahtarı (webhook_secret) üretilir ve yanıtta yalnızca bir kez gösterilir; saklayın. Mevcut ayarları görmek için aynı adrese GET isteği yapın.

curl -X POST "https://wa.tempomsg.com/inst1001/instance/settings" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "webhook_url=https://ornek.com/whatsapp/webhook" \
  --data-urlencode "webhook_message_received=true" \
  --data-urlencode "webhook_message_ack=true" \
  --data-urlencode "webhook_instance_status=true"
Yanıt · 200 OK
{
  "webhook_url": "https://ornek.com/whatsapp/webhook",
  "webhook_message_received": true,
  "webhook_message_create": false,
  "webhook_message_ack": true,
  "webhook_instance_status": true,
  "webhook_message_reaction": false,
  "webhook_download_media": true,
  "webhook_retries": 5,
  "webhook_secret_set": true,
  "webhook_secret": "9f2c4e…(yalnızca ilk tanımda ya da yenilemede döner)",
  "success": "settings updated"
}

Olaylar ve örnek içerikler

Her olay aynı zarf içinde gelir: event_type (olay türü), instanceId, referenceId ve olayın verisi data.

event_typeNe zaman
message_receivedNumaranıza bir kişiden ya da gruptan mesaj geldiğinde.
message_createNumaranızdan mesaj gittiğinde (API'den ya da telefondan).
message_ackGönderdiğiniz mesaj teslim edildiğinde (device) ve okunduğunda (read).
instance_statusBağlantı durumu değiştiğinde (bağlandı, koptu, QR bekliyor).
message_reactionBir mesaja emoji ile tepki verildiğinde (tepki kaldırılırsa reaction boş gelir).
webhook_testTest isteği gönderdiğinizde.

message_received — kişiden gelen mesaj

POST · webhook adresiniz
{
  "event_type": "message_received",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": {
    "id": "false_905321234567@c.us_3EB0C76A1F5B2D8E",
    "from": "905321234567@c.us",
    "to": "905408524675@c.us",
    "author": "",
    "pushname": "Ahmet Yılmaz",
    "ack": "",
    "type": "chat",
    "body": "Merhaba, siparişim ne zaman gelir?",
    "media": "",
    "fromMe": false,
    "self": false,
    "isForwarded": false,
    "time": 1794700325
  }
}

from mesajı yazan, to sizin numaranızdır. type: chat, image, video, audio, document. time Unix zaman damgasıdır (saniye).

message_received — gruptan gelen mesaj

POST · webhook adresiniz
{
  "event_type": "message_received",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": {
    "id": "false_120363041234567890@g.us_3EB0A1B2C3D4_905321234567@c.us",
    "from": "120363041234567890@g.us",
    "to": "905408524675@c.us",
    "author": "905321234567@c.us",
    "pushname": "Ahmet Yılmaz",
    "type": "chat",
    "body": "Sevkiyat yola çıktı.",
    "fromMe": false,
    "time": 1794700390
  }
}

Grup mesajında from grup kimliği, author mesajı yazan kişidir.

message_create — giden mesaj

POST · webhook adresiniz
{
  "event_type": "message_create",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": {
    "id": "true_905321234567@c.us_3EB0F1E2D3C4B5A6",
    "from": "905408524675@c.us",
    "to": "905321234567@c.us",
    "type": "chat",
    "body": "Siparişiniz kargoya verildi.",
    "fromMe": true,
    "self": true,
    "time": 1794700327
  }
}

message_ack — teslim / okundu

POST · webhook adresiniz
{
  "event_type": "message_ack",
  "instanceId": "inst1001",
  "referenceId": "SIPARIS-10482",
  "data": {
    "id": "true_905321234567@c.us_3EB0F1E2D3C4B5A6",
    "ack": "read",
    "to": "905321234567",
    "messageId": 1234
  }
}

messageId gönderim yanıtındaki id, referenceId gönderirken verdiğiniz kendi numaranızdır; kendi kaydınızı bunlarla eşleştirin. ack: device teslim edildi, read okundu, played sesli mesaj dinlendi. Aynı mesaj için önce device, sonra read gelir; durumu geri götüren bildirim gönderilmez.

instance_status — bağlantı durumu

POST · webhook adresiniz
{
  "event_type": "instance_status",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": { "status": "disconnected", "substatus": "failed", "phone": "905408524675" }
}

message_received — dosya ile gelen mesaj

POST · webhook adresiniz
{
  "event_type": "message_received",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": {
    "id": "false_905321234567@c.us_3EB0A1B2C3D4E5F6",
    "from": "905321234567@c.us",
    "to": "905408524675@c.us",
    "author": "",
    "pushname": "Ahmet Yılmaz",
    "ack": "",
    "type": "document",
    "body": "Siparişin dekontu ekte",
    "media": "https://wa.tempobilisim.com.tr/medya/4f9c2d…",
    "mimetype": "application/pdf",
    "filename": "dekont.pdf",
    "fromMe": false,
    "self": false,
    "isForwarded": false,
    "time": 1794700411
  }
}

Webhook ayarlarında medyayı indir açıksa resim, belge, ses ve videolarda media alanına indirme bağlantısı, mimetype ve filename eklenir. Bağlantı 24 saat geçerlidir; dosyayı bu süre içinde kendi sisteminize kaydedin. Kapalıysa media boş gelir.

message_reaction — tepki

POST · webhook adresiniz
{
  "event_type": "message_reaction",
  "instanceId": "inst1001",
  "referenceId": "SIPARIS-10482",
  "data": {
    "id": "false_905321234567@c.us_3EB0F00D1234ABCD",
    "from": "905321234567@c.us",
    "to": "905408524675@c.us",
    "author": "",
    "fromMe": false,
    "reaction": "👍",
    "reactedMessageId": "true_905321234567@c.us_3EB0C76A1F5B2D8E",
    "messageId": 1234,
    "time": 1794700520
  }
}

reactedMessageId tepki verilen WhatsApp mesajıdır. Bu mesaj sizin API'den gönderdiğiniz bir mesajsa messageId ve referenceId dolu gelir.

webhook_test

POST · webhook adresiniz
{
  "event_type": "webhook_test",
  "instanceId": "inst1001",
  "referenceId": "",
  "data": { "message": "Tempo WA Gateway test olayı", "time": 1794700400 }
}

İmza doğrulama

Her webhook isteği şu başlıklarla gelir:

BaşlıkAçıklama
X-Tempo-Imzasha256= + gövdenin, imza anahtarınızla hesaplanmış HMAC-SHA256 değeri (küçük harf hex).
X-Tempo-OlayOlay türü (event_type ile aynı).
X-Tempo-Olay-IdOlayın benzersiz numarası. Aynı olay tekrar denenirse aynı numarayla gelir; çift işlemeyi önlemek için kullanın.
Content-Typeapplication/json; charset=utf-8
User-AgentTempoWAGateway/1.0
İmzayı, gövdeyi JSON'a çevirmeden önce ham hâliyle hesaplayın. JSON'u ayrıştırıp yeniden yazmak boşlukları değiştirir ve imza tutmaz. Karşılaştırmayı sabit süreli fonksiyonla yapın (aşağıdaki örneklerdeki gibi).
// ASP.NET Core (minimal API)
app.MapPost("/whatsapp/webhook", async (HttpRequest istek) =>
{
    using var okuyucu = new StreamReader(istek.Body);
    var govde = await okuyucu.ReadToEndAsync();          // gövdeyi ham hâliyle okuyun

    var beklenen = "sha256=" + Convert.ToHexString(
        HMACSHA256.HashData(Encoding.UTF8.GetBytes(WEBHOOK_SECRET), Encoding.UTF8.GetBytes(govde))).ToLowerInvariant();
    var gelen = istek.Headers["X-Tempo-Imza"].ToString();
    if (!CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(gelen), Encoding.ASCII.GetBytes(beklenen)))
        return Results.Unauthorized();

    using var olay = JsonDocument.Parse(govde);
    var tur = olay.RootElement.GetProperty("event_type").GetString();
    // tur: message_received, message_create, message_ack, instance_status, webhook_test
    return Results.Ok();                                 // 2xx dönün; işi arka planda yapın
});

İletim ve tekrar deneme

  • Adresiniz 10 saniye içinde 2xx dönerse olay iletildi sayılır.
  • Zaman aşımı ya da 2xx dışı yanıtta olay yeniden denenir: toplam en fazla 3 deneme (numara başına webhook_retries ile ya da panelden değiştirilebilir), denemeler arası bekleme her seferinde 30 saniye artar.
  • Olaylar sırayla ama paralel iletilebilir; sıralama için data.time alanını kullanın.
  • Aynı olay birden fazla gelebilir (ör. yanıtınız zaman aşımına uğradıysa). X-Tempo-Olay-Id ile tekrarları ayıklayın.

Test ve iletim kaydı

POST /instance/webhook-test

Tanımlı adresinize bir webhook_test olayı gönderir. Kurulumdan sonra ilk deneme için kullanın.

curl -X POST "https://wa.tempomsg.com/inst1001/instance/webhook-test" \
  --data-urlencode "token=GIZLI_ANAHTAR"

GET /instance/webhook-log

Son iletimleri listeler: olay türü, durum (delivered, retrying, failed), HTTP kodu, süre ve hata. Adresiniz olay almıyorsa ilk bakılacak yer burasıdır. limit en fazla 200.

curl -G "https://wa.tempomsg.com/inst1001/instance/webhook-log" \
  --data-urlencode "token=GIZLI_ANAHTAR" \
  --data-urlencode "limit=20"

POST /instance/webhook-test-alicisi

Henüz kendi webhook adresiniz hazır değilse Gateway size geçici bir test alıcısı adresi verir. Bu adresi webhook_url olarak tanımlayın; gelen olayları GET /instance/webhook-test-alicisi ile görün (imza doğrulama sonucu dahil).

Hata kodları

HTTPAnlamı ve çözümü
400Parametre eksik ya da hatalı (ör. to biçimi, boş body). error alanı neyin yanlış olduğunu yazar.
401Instance ID ya da gizli anahtar hatalı. Anahtar yenilendiyse yazılımınızdaki anahtarı güncelleyin.
403Lisans süresi dolmuş, askıya alınmış ya da numara pasif (lisans numara sayısı düşürülmüş). Tempo Bilişim ile görüşün.
409Numara bağlı değil (QR ile bağlayın) ya da işlem o anki durumda yapılamıyor.
413Dosya 16 MB sınırını aşıyor.
429Dakikalık istek sınırı aşıldı. Birkaç saniye bekleyip tekrar deneyin.
502WhatsApp bağlantı motoruna geçici olarak ulaşılamadı. Kısa süre sonra tekrar deneyin.

Limitler

KonuSınır
API isteğiNumara başına dakikada 60 istek
Günlük gönderimNumara başına günde 1000 mesaj
Yeni numara (ısınma)İlk 7 gün günde en fazla 100 mesaj. Yeni numaranın WhatsApp tarafından engellenmemesi içindir.
Mesaj aralığıAynı numaradan iki mesaj arası 3–8 saniye
Metin4.096 karakter · açıklama (caption) 1.024 karakter
Dosya16 MB
Numaranızı korumak için: yalnızca sizinle iletişime izin veren kişilere mesaj gönderin, toplu reklam göndermeyin. Çok sayıda kişinin sizi engellemesi ya da şikâyet etmesi WhatsApp'ın numarayı kapatmasına yol açabilir.

Mevcut entegrasyonu taşıma

Yazılımınız şu an başka bir WhatsApp API servisiyle çalışıyorsa, instance ve token yapısındaki servislerden geçişte çoğunlukla aşağıdaki üç ayarı değiştirmeniz yeterlidir:

AyarTempo WhatsApp Gateway değeri
API adresihttps://wa.tempomsg.com
Instance IDPanelde numaranın kimliği, ör. inst1001
TokenPanelde üretilen gizli anahtar

Geçişten önce şunları kontrol edin:

  1. Gönderim adreslerinin /{instanceId}/messages/chat, /messages/document ve /messages/image olduğunu.
  2. Webhook alıcınızın olay içeriklerini (event_type, data.from, data.body …) okuduğunu.
  3. Webhook isteklerinin imzasını doğruladığınızı.
  4. Teslim ve okundu eşleştirmesi için referenceId kullandığınızı.

Emin olmadığınız bir nokta varsa Swagger ekranından isteklerinizi deneyerek yanıtları karşılaştırabilirsiniz.

OpenAPI (Swagger) ve Postman

Swagger ekranı: tüm uç noktaları tarayıcıda görüp gizli anahtarınızla doğrudan deneyebilirsiniz.

Swagger ekranını aç

Tüm uç noktaları içeren OpenAPI 3 dosyasını indirip Postman, Insomnia, Swagger UI ya da kod üretme araçlarına aktarabilirsiniz:

openapi.json dosyasını indir

Postman'de: Import → dosyayı seçin → koleksiyon oluşur. Ortam değişkenlerine instanceId ve token değerlerinizi yazın.

© 2026 Tempo Bilişim · Tempo WhatsApp Gateway · Sorularınız için Tempo Bilişim destek ekibine başvurun.