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:
inst1001. API adresinin parçasıdır.https://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:
tokenparametresi (sorgu, form ya da JSON gövdesinde).X-Api-TokenHTTP başlığı — anahtarın sunucu loglarında görünmemesi için önerilir.
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-dataapplication/json- Sorgu parametresi (
?token=...&to=...)
Yanıtlar her zaman JSON'dur. Başarılı gönderim:
{"sent":"true","message":"ok","id":1234}
Hata durumunda uygun HTTP kodu ve error alanı döner:
{"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ılan | Anlamı |
|---|---|
| 905321234567 | Ülke koduyla telefon (önerilen biçim). Boşluk, +, tire ve parantez temizlenir. |
| +90 532 123 45 67 | Kabul edilir, 905321234567 olarak işlenir. |
| 05321234567 · 5321234567 | Türkiye numarası olarak kabul edilir, başına 90 eklenir. |
| 905321234567@c.us | WhatsApp kişi kimliği biçimi; numara olarak işlenir. |
| 120363041234567890@g.us | Grup. Kimliği Gruplar uç noktasından alın. |
unsent olur ve error alanında sebebi yazar.Hızlı başlangıç
- Müşteri panelinde Numara Ekle ile numara oluşturun; Instance ID ve gizli anahtarı kaydedin.
- Panelde gösterilen QR kodunu WhatsApp → Bağlı cihazlar → Cihaz bağla ile okutun.
- Aşağıdaki isteği kendi bilgilerinizle gönderin; yanıtta
"sent":"true"görmelisiniz. - 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."
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["body"] = "Merhaba, siparişiniz hazır.",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/chat", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"body" => "Merhaba, siparişiniz hazır.",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/chat");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
body: "Merhaba, siparişiniz hazır.",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/chat", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"body": "Merhaba, siparişiniz hazır.",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/chat", data=parametreler)
print(yanit.json())
Metin mesajı gönderme
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar (ya da X-Api-Token başlığı). |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. Biçimler |
| bodyZORUNLU | Mesaj 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ĞLI | Kendi 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ĞLI | 0–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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["body"] = "Merhaba Ahmet Bey, 10482 numaralı siparişiniz kargoya verildi.",
["referenceId"] = "SIPARIS-10482",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/chat", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"body" => "Merhaba Ahmet Bey, 10482 numaralı siparişiniz kargoya verildi.",
"referenceId" => "SIPARIS-10482",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/chat");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
body: "Merhaba Ahmet Bey, 10482 numaralı siparişiniz kargoya verildi.",
referenceId: "SIPARIS-10482",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/chat", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"body": "Merhaba Ahmet Bey, 10482 numaralı siparişiniz kargoya verildi.",
"referenceId": "SIPARIS-10482",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/chat", data=parametreler)
print(yanit.json())
{"sent":"true","message":"ok","id":1234}
id, mesajın Gateway'deki numarasıdır. Durumunu GET /messages?id=1234 ile sorgulayabilirsiniz.
Belge gönderme
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.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. |
| documentZORUNLU | Dosya adresi (https) ya da base64 içerik. En fazla 16 MB. |
| filenameÖNERİLİR | Alı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ĞLI | Dosyanın altındaki açıklama, en fazla 1.024 karakter. |
| referenceId, priorityİSTEĞE BAĞLI | Metin 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."
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["document"] = "https://ornek.com/faturalar/2026-0142.pdf",
["filename"] = "Fatura-2026-0142.pdf",
["caption"] = "Faturanız ektedir.",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/document", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"document" => "https://ornek.com/faturalar/2026-0142.pdf",
"filename" => "Fatura-2026-0142.pdf",
"caption" => "Faturanız ektedir.",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/document");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
document: "https://ornek.com/faturalar/2026-0142.pdf",
filename: "Fatura-2026-0142.pdf",
caption: "Faturanız ektedir.",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/document", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"document": "https://ornek.com/faturalar/2026-0142.pdf",
"filename": "Fatura-2026-0142.pdf",
"caption": "Faturanız ektedir.",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/document", data=parametreler)
print(yanit.json())
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);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"document" => base64_encode(file_get_contents("Fatura.pdf")),
"filename" => "Fatura.pdf",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/document");
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($parametreler), CURLOPT_RETURNTRANSFER => true]);
echo curl_exec($ch);
import base64, requests
with open("Fatura.pdf", "rb") as f:
icerik = base64.b64encode(f.read()).decode()
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/document", data={
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"document": icerik,
"filename": "Fatura.pdf",
})
print(yanit.json())
Resim gönderme
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!"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["image"] = "https://ornek.com/urunler/kampanya.jpg",
["filename"] = "kampanya.jpg",
["caption"] = "Hafta sonuna özel %20 indirim!",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/image", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"image" => "https://ornek.com/urunler/kampanya.jpg",
"filename" => "kampanya.jpg",
"caption" => "Hafta sonuna özel %20 indirim!",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/image");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
image: "https://ornek.com/urunler/kampanya.jpg",
filename: "kampanya.jpg",
caption: "Hafta sonuna özel %20 indirim!",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/image", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"image": "https://ornek.com/urunler/kampanya.jpg",
"filename": "kampanya.jpg",
"caption": "Hafta sonuna özel %20 indirim!",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/image", data=parametreler)
print(yanit.json())
Video gönderme
Sohbette oynatılabilir video (MP4 önerilir). Dosya alanı video; adres ya da base64 olarak, belge ile aynı kurallarla verilir.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. |
| videoZORUNLU | Video adresi (https) ya da base64. En fazla 16 MB. |
| filenameİSTEĞE BAĞLI | Uzantıyla dosya adı (ör. tanitim.mp4). Uzantı video olmalıdır. |
| captionİSTEĞE BAĞLI | Açıklama, en fazla 1.024 karakter. |
| referenceId, priorityİSTEĞE BAĞLI | Metin 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["video"] = "https://ornek.com/tanitim.mp4",
["filename"] = "tanitim.mp4",
["caption"] = "Yeni ürünümüz",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/video", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"video" => "https://ornek.com/tanitim.mp4",
"filename" => "tanitim.mp4",
"caption" => "Yeni ürünümüz",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/video");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
video: "https://ornek.com/tanitim.mp4",
filename: "tanitim.mp4",
caption: "Yeni ürünümüz",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/video", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"video": "https://ornek.com/tanitim.mp4",
"filename": "tanitim.mp4",
"caption": "Yeni ürünümüz",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/video", data=parametreler)
print(yanit.json())
Ses dosyası ve sesli not
/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.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. |
| audioZORUNLU | Ses dosyası adresi (https) ya da base64 (mp3, ogg, m4a, wav…). |
| filenameİSTEĞE BAĞLI | Uzantıyla dosya adı (ör. duyuru.mp3). |
| referenceId, priorityİSTEĞE BAĞLI | Metin 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["audio"] = "https://ornek.com/duyuru.mp3",
["filename"] = "duyuru.mp3",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/voice", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"audio" => "https://ornek.com/duyuru.mp3",
"filename" => "duyuru.mp3",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/voice");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
audio: "https://ornek.com/duyuru.mp3",
filename: "duyuru.mp3",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/voice", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"audio": "https://ornek.com/duyuru.mp3",
"filename": "duyuru.mp3",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/voice", data=parametreler)
print(yanit.json())
Sticker gönderme
Sticker yalnızca WebP biçiminde olabilir (512×512 önerilir). Dosya alanı sticker; açıklama almaz.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. |
| stickerZORUNLU | WebP dosyasının adresi (https) ya da base64. |
| filenameİSTEĞE BAĞLI | ör. tesekkurler.webp |
| referenceId, priorityİSTEĞE BAĞLI | Metin 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["sticker"] = "https://ornek.com/tesekkurler.webp",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/sticker", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"sticker" => "https://ornek.com/tesekkurler.webp",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/sticker");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
sticker: "https://ornek.com/tesekkurler.webp",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/sticker", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"sticker": "https://ornek.com/tesekkurler.webp",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/sticker", data=parametreler)
print(yanit.json())
Konum gönderme
Haritada açılan konum mesajı gönderir; mağaza, şube ya da teslimat adresi için kullanışlıdır.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alıcı telefon numarası ya da grup kimliği. |
| latZORUNLU | Enlem, ondalık (ör. 41.0082). |
| lngZORUNLU | Boylam, ondalık (ör. 28.9784). |
| addressİSTEĞE BAĞLI | Konumun altında görünen ad / adres. |
| referenceId, priorityİSTEĞE BAĞLI | Metin 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["lat"] = "41.0082",
["lng"] = "28.9784",
["address"] = "Tempo Bilişim Merkez Ofis",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/location", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"lat" => "41.0082",
"lng" => "28.9784",
"address" => "Tempo Bilişim Merkez Ofis",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/location");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
lat: "41.0082",
lng: "28.9784",
address: "Tempo Bilişim Merkez Ofis",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/location", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"lat": "41.0082",
"lng": "28.9784",
"address": "Tempo Bilişim Merkez Ofis",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/location", data=parametreler)
print(yanit.json())
Kişi kartı gönderme
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.
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| toZORUNLU | Alı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ĞLI | Metin 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["to"] = "905321234567",
["contact"] = "905551112233",
["name"] = "Tempo Destek",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/contact", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"to" => "905321234567",
"contact" => "905551112233",
"name" => "Tempo Destek",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/contact");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
to: "905321234567",
contact: "905551112233",
name: "Tempo Destek",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/contact", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"to": "905321234567",
"contact": "905551112233",
"name": "Tempo Destek",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/contact", data=parametreler)
print(yanit.json())
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_ackolayı 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ş
| Parametre | Açıklama |
|---|---|
| tokenZORUNLU | Gizli anahtar. |
| statusİSTEĞE BAĞLI | all (varsayılan), queue (bekleyen), sent (gönderilen), unsent (gönderilemeyen), cancelled (iptal edilen). |
| idİSTEĞE BAĞLI | Tek mesaj: gönderim yanıtındaki id. |
| referenceIdİSTEĞE BAĞLI | Gönderirken verdiğiniz kendi numaranız. |
| page, limitİSTEĞE BAĞLI | Sayfalama. 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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["referenceId"] = "SIPARIS-10482",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/messages?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"referenceId" => "SIPARIS-10482",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
referenceId: "SIPARIS-10482",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"referenceId": "SIPARIS-10482",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/messages", params=parametreler)
print(yanit.json())
{
"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"
}
]
}
| Alan | Değerler |
|---|---|
| status | queue kuyrukta · sent WhatsApp'a gönderildi · unsent gönderilemedi (error alanına bakın) · cancelled müşteri panelinden iptal edildi |
| ack | server WhatsApp sunucusuna ulaştı (tek tik) · device alıcının telefonuna teslim edildi (çift tik) · read okundu (mavi tik) |
| …_at | Oluşturma, gönderim, teslim ve okunma zamanları (Türkiye saati, yyyy-MM-dd HH:mm:ss). |
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=👍"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["msgId"] = "1234",
["emoji"] = "👍",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/reaction", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"msgId" => "1234",
"emoji" => "👍",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/reaction");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
msgId: "1234",
emoji: "👍",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/reaction", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"msgId": "1234",
"emoji": "👍",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/reaction", data=parametreler)
print(yanit.json())
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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["status"] = "queue",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/messages/clear", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"status" => "queue",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/messages/clear");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
status: "queue",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/messages/clear", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"status": "queue",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/messages/clear", data=parametreler)
print(yanit.json())
GET /messages/statistics
Numaranın mesaj sayıları.
{
"queue": 3,
"sent": 1840,
"delivered": 1795,
"read": 1512,
"unsent": 4,
"cancelled": 120,
"sent_today": 86
}
Gruplar
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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/groups?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/groups?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/groups?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/groups", params=parametreler)
print(yanit.json())
[
{ "id": "120363041234567890@g.us", "name": "Satış Ekibi", "participants": 14 },
{ "id": "120363049876543210@g.us", "name": "Depo Bildirimleri", "participants": 6 }
]
Bağlantı durumu
curl -G "https://wa.tempomsg.com/inst1001/instance/status" \ --data-urlencode "token=GIZLI_ANAHTAR"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/instance/status?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/instance/status?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/instance/status?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/instance/status", params=parametreler)
print(yanit.json())
{
"status": { "accountStatus": { "status": "authenticated", "substatus": "connected" } },
"phone": "905408524675"
}
| status / substatus | Anlamı |
|---|---|
| authenticated / connected | Numara bağlı, mesaj gönderilebilir. |
| qr / qr | QR kodu okutulmayı bekliyor. |
| loading / loading | Bağlantı başlatılıyor. |
| disconnected / failed · stopped | Bağlantı koptu. Panelden QR ile yeniden bağlayın; mesajlar kuyrukta bekler. |
QR kodu
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
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.
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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/instance/restart", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/instance/restart");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/instance/restart", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/instance/restart", data=parametreler)
print(yanit.json())
Numara bilgisi ve kuyruk
GET /instance/me
Bağlı numaranın WhatsApp kimliği, telefonu ve profil adı.
{
"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).
[
{
"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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["chatId"] = "905321234567",
["limit"] = "20",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/chats/messages?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"chatId" => "905321234567",
"limit" => "20",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/chats/messages?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
chatId: "905321234567",
limit: "20",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/chats/messages?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"chatId": "905321234567",
"limit": "20",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/chats/messages", params=parametreler)
print(yanit.json())
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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["chatId"] = "905321234567",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/contacts/check?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"chatId" => "905321234567",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/contacts/check?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
chatId: "905321234567",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/contacts/check?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"chatId": "905321234567",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/contacts/check", params=parametreler)
print(yanit.json())
{
"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.
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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["groupId"] = "120363012345678901@g.us",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/groups/group?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"groupId" => "120363012345678901@g.us",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/groups/group?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
groupId: "120363012345678901@g.us",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/groups/group?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"groupId": "120363012345678901@g.us",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/groups/group", params=parametreler)
print(yanit.json())
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"
{
"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). POSTisteği almalı ve 10 saniye içinde2xx(ör. 200) dönmeli. Uzun işlemleri arka planda yapın.- Her isteğin imzasını doğrulamalı.
Webhook ayarları
| Parametre | Açıklama |
|---|---|
| webhook_url | Olayların gönderileceği adres. Boş gönderirseniz webhook kapanır. |
| webhook_message_received | true/false — size gelen mesajlar (message_received). |
| webhook_message_create | Numaranızdan giden mesajlar (message_create); telefondan elle yazılanlar dahil. |
| webhook_message_ack | Teslim edildi ve okundu bildirimleri (message_ack). |
| webhook_instance_status | Bağlantı durumu değişiklikleri (instance_status). |
| webhook_message_reaction | Mesajlara emoji ile verilen tepkiler (message_reaction). |
| webhook_download_media | true ise gelen resim, belge ve seslerde data.media alanına 24 saat geçerli indirme bağlantısı eklenir. |
| webhook_retries | Adresiniz yanıt vermezse olayın en fazla deneme sayısı (1–10). Boş gönderilirse sistem varsayılanı (3) geçerli olur. |
| webhook_secret_regenerate | true 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["webhook_url"] = "https://ornek.com/whatsapp/webhook",
["webhook_message_received"] = "true",
["webhook_message_ack"] = "true",
["webhook_instance_status"] = "true",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/instance/settings", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"webhook_url" => "https://ornek.com/whatsapp/webhook",
"webhook_message_received" => "true",
"webhook_message_ack" => "true",
"webhook_instance_status" => "true",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/instance/settings");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
webhook_url: "https://ornek.com/whatsapp/webhook",
webhook_message_received: "true",
webhook_message_ack: "true",
webhook_instance_status: "true",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/instance/settings", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"webhook_url": "https://ornek.com/whatsapp/webhook",
"webhook_message_received": "true",
"webhook_message_ack": "true",
"webhook_instance_status": "true",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/instance/settings", data=parametreler)
print(yanit.json())
{
"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_type | Ne zaman |
|---|---|
| message_received | Numaranıza bir kişiden ya da gruptan mesaj geldiğinde. |
| message_create | Numaranızdan mesaj gittiğinde (API'den ya da telefondan). |
| message_ack | Gönderdiğiniz mesaj teslim edildiğinde (device) ve okunduğunda (read). |
| instance_status | Bağlantı durumu değiştiğinde (bağlandı, koptu, QR bekliyor). |
| message_reaction | Bir mesaja emoji ile tepki verildiğinde (tepki kaldırılırsa reaction boş gelir). |
| webhook_test | Test isteği gönderdiğinizde. |
message_received — kişiden gelen mesaj
{
"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
{
"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
{
"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
{
"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
{
"event_type": "instance_status",
"instanceId": "inst1001",
"referenceId": "",
"data": { "status": "disconnected", "substatus": "failed", "phone": "905408524675" }
}
message_received — dosya ile gelen mesaj
{
"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
{
"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
{
"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ık | Açıklama |
|---|---|
| X-Tempo-Imza | sha256= + gövdenin, imza anahtarınızla hesaplanmış HMAC-SHA256 değeri (küçük harf hex). |
| X-Tempo-Olay | Olay türü (event_type ile aynı). |
| X-Tempo-Olay-Id | Olayın benzersiz numarası. Aynı olay tekrar denenirse aynı numarayla gelir; çift işlemeyi önlemek için kullanın. |
| Content-Type | application/json; charset=utf-8 |
| User-Agent | TempoWAGateway/1.0 |
// 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
});
<?php
$govde = file_get_contents('php://input'); // ham gövde
$beklenen = 'sha256=' . hash_hmac('sha256', $govde, WEBHOOK_SECRET);
$gelen = $_SERVER['HTTP_X_TEMPO_IMZA'] ?? '';
if (!hash_equals($beklenen, $gelen)) {
http_response_code(401);
exit;
}
$olay = json_decode($govde, true);
switch ($olay['event_type']) {
case 'message_received': /* gelen mesaj */ break;
case 'message_ack': /* teslim / okundu */ break;
}
http_response_code(200);
// Node.js + Express: gövdeyi ham (raw) alın, JSON'a sonra çevirin
import express from "express";
import crypto from "node:crypto";
const app = express();
app.post("/whatsapp/webhook", express.raw({ type: "application/json" }), (req, res) => {
const beklenen = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SECRET).update(req.body).digest("hex");
const gelen = req.get("X-Tempo-Imza") || "";
if (gelen.length !== beklenen.length ||
!crypto.timingSafeEqual(Buffer.from(gelen), Buffer.from(beklenen))) {
return res.sendStatus(401);
}
const olay = JSON.parse(req.body.toString("utf8"));
console.log(olay.event_type, olay.data);
res.sendStatus(200);
});
# Flask
import hmac, hashlib
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/whatsapp/webhook")
def webhook():
govde = request.get_data() # ham gövde (bytes)
beklenen = "sha256=" + hmac.new(WEBHOOK_SECRET.encode(), govde, hashlib.sha256).hexdigest()
if not hmac.compare_digest(beklenen, request.headers.get("X-Tempo-Imza", "")):
abort(401)
olay = request.get_json()
print(olay["event_type"], olay["data"])
return "", 200
İletim ve tekrar deneme
- Adresiniz 10 saniye içinde
2xxdönerse olay iletildi sayılır. - Zaman aşımı ya da
2xxdışı yanıtta olay yeniden denenir: toplam en fazla 3 deneme (numara başınawebhook_retriesile 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.timealanını kullanın. - Aynı olay birden fazla gelebilir (ör. yanıtınız zaman aşımına uğradıysa).
X-Tempo-Olay-Idile 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"
using var http = new HttpClient();
var veri = new FormUrlEncodedContent(new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
});
var yanit = await http.PostAsync("https://wa.tempomsg.com/inst1001/instance/webhook-test", veri);
Console.WriteLine(await yanit.Content.ReadAsStringAsync());
$parametreler = [
"token" => "GIZLI_ANAHTAR",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/instance/webhook-test");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($parametreler),
CURLOPT_RETURNTRANSFER => true,
]);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/instance/webhook-test", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: parametreler,
});
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
}
yanit = requests.post("https://wa.tempomsg.com/inst1001/instance/webhook-test", data=parametreler)
print(yanit.json())
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"
using var http = new HttpClient();
var sorgu = string.Join("&", new Dictionary<string, string>
{
["token"] = "GIZLI_ANAHTAR",
["limit"] = "20",
}.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value)));
var json = await http.GetStringAsync("https://wa.tempomsg.com/inst1001/instance/webhook-log?" + sorgu);
Console.WriteLine(json);
$parametreler = [
"token" => "GIZLI_ANAHTAR",
"limit" => "20",
];
$ch = curl_init("https://wa.tempomsg.com/inst1001/instance/webhook-log?" . http_build_query($parametreler));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$yanit = curl_exec($ch);
curl_close($ch);
echo $yanit;
const parametreler = new URLSearchParams({
token: "GIZLI_ANAHTAR",
limit: "20",
});
const yanit = await fetch("https://wa.tempomsg.com/inst1001/instance/webhook-log?" + parametreler);
console.log(await yanit.json());
import requests
parametreler = {
"token": "GIZLI_ANAHTAR",
"limit": "20",
}
yanit = requests.get("https://wa.tempomsg.com/inst1001/instance/webhook-log", params=parametreler)
print(yanit.json())
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ı
| HTTP | Anlamı ve çözümü |
|---|---|
| 400 | Parametre eksik ya da hatalı (ör. to biçimi, boş body). error alanı neyin yanlış olduğunu yazar. |
| 401 | Instance ID ya da gizli anahtar hatalı. Anahtar yenilendiyse yazılımınızdaki anahtarı güncelleyin. |
| 403 | Lisans 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. |
| 409 | Numara bağlı değil (QR ile bağlayın) ya da işlem o anki durumda yapılamıyor. |
| 413 | Dosya 16 MB sınırını aşıyor. |
| 429 | Dakikalık istek sınırı aşıldı. Birkaç saniye bekleyip tekrar deneyin. |
| 502 | WhatsApp bağlantı motoruna geçici olarak ulaşılamadı. Kısa süre sonra tekrar deneyin. |
Limitler
| Konu | Sınır |
|---|---|
| API isteği | Numara başına dakikada 60 istek |
| Günlük gönderim | Numara 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 |
| Metin | 4.096 karakter · açıklama (caption) 1.024 karakter |
| Dosya | 16 MB |
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:
| Ayar | Tempo WhatsApp Gateway değeri |
|---|---|
| API adresi | https://wa.tempomsg.com |
| Instance ID | Panelde numaranın kimliği, ör. inst1001 |
| Token | Panelde üretilen gizli anahtar |
Geçişten önce şunları kontrol edin:
- Gönderim adreslerinin
/{instanceId}/messages/chat,/messages/documentve/messages/imageolduğunu. - Webhook alıcınızın olay içeriklerini (
event_type,data.from,data.body…) okuduğunu. - Webhook isteklerinin imzasını doğruladığınızı.
- Teslim ve okundu eşleştirmesi için
referenceIdkullandığı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.
Tüm uç noktaları içeren OpenAPI 3 dosyasını indirip Postman, Insomnia, Swagger UI ya da kod üretme araçlarına aktarabilirsiniz:
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.