Genel bakış

TurkeySMS API ile uygulamanızdan SMS ve OTP gönderebilir, gönderimlerinizi zamanlayabilir, rehberinizi yönetebilir, bakiye ve SMS başlıklarınızı sorgulayabilir, gönderim raporlarını alabilirsiniz. Tüm istekler HTTPS üzerinden POST yöntemiyle gönderilir ve yanıtlar JSON biçimindedir.

Bu sayfadaki bilgiler, API'nin canlı sistemdeki davranışına göre hazırlanmıştır. Bölümler, paneldeki API Merkezi düzenini izler.

BölümUç noktalar
Anahtar denetimi/auth/post/check/
Mesajlaşma/sms/send, /group/send, /group/sendMixed, /otp/send, /otp/detailed
Rehber/groups/create, /groups/edit, /groups/delete, /groups/list, /contacts/add, /blacklist/post/add, /blacklist/post/status
Sorgular ve raporlar/balance/, /senderid/check, /sms/status, /reports/basic, /reports/detailed
WebhookOlay bildirimleri sizin sunucunuza gönderilir

Başlarken

Gereksinimler

  • Aktif bir TurkeySMS hesabı. Hesap aktif değilse istekler reddedilir (çoğu uç noktada TS-1030).
  • Yeterli bakiye. Gönderim isteklerinde bakiye, gönderilecek toplam SMS sayısını karşılamalıdır.
  • Onaylı bir SMS başlığı. SMS ve grup gönderiminde title alanına hesabınızda onaylı bir başlık yazılır. Onaylı başlıklarınızı Başlık sorgu ile listeleyebilirsiniz.
  • Bir API anahtarı ve gerekli izinler. Her uç nokta belirli izinler ister (bkz. İzinler).

Hızlı başlangıç

  1. Panelde API Merkezi → Anahtarlarım → Yeni Anahtar adımlarıyla bir anahtar oluşturun. İlk SMS için «POST isteklerine izin ver» ve «SMS gönderimi» izinlerini açın.
  2. Anahtar yalnızca bir kez gösterilir. Kopyalayıp sunucunuzda güvenli bir yerde (ör. ortam değişkeni) saklayın.
  3. Anahtarınızı Anahtar denetimi uç noktasıyla doğrulayın.
  4. Aşağıdaki örnekle ilk SMS'inizi gönderin. Türkçe metinlerde sms_lang değerini 1 olarak gönderin.
curl -X POST https://api.turkeysms.com.tr/sms/send \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "title": "BASLIGINIZ",
  "sentto": "905XXXXXXXXX",
  "text": "Siparişiniz kargoya verildi.",
  "sms_lang": 1
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'title'    => 'BASLIGINIZ',
    'sentto'   => '905XXXXXXXXX',
    'text'     => 'Siparişiniz kargoya verildi.',
    'sms_lang' => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/sms/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "title":    "BASLIGINIZ",
    "sentto":   "905XXXXXXXXX",
    "text":     "Siparişiniz kargoya verildi.",
    "sms_lang": 1,
}

r = requests.post("https://api.turkeysms.com.tr/sms/send", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  title:    'BASLIGINIZ',
  sentto:   '905XXXXXXXXX',
  text:     'Siparişiniz kargoya verildi.',
  sms_lang: 1,
};

const r = await fetch('https://api.turkeysms.com.tr/sms/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı bir istekte result değeri true, result_code değeri TS-1024 olur. Ayrıntılar için SMS gönderimi bölümüne bakın.

Genel kurallar

Temel adres ve istek biçimi

  • Temel adres: https://api.turkeysms.com.tr. Uç nokta yolları bu adrese eklenir (ör. https://api.turkeysms.com.tr/sms/send). Adreste sürüm öneki yoktur.
  • Tüm uç noktalar yalnızca POST kabul eder.
  • Gövdeyi JSON (Content-Type: application/json, UTF-8) olarak gönderin. Form verisi de kabul edilir; örnekler JSON kullanır. Sorgu dizesi (query string) okunmaz.
  • Yolları bu sayfada yazıldığı gibi kullanın. /balance/ ve /auth/post/check/ sondaki eğik çizgiyle yazılır; /senderid/check ve diğerleri eğik çizgisiz yazılır. Yanlış yol yönlendirme (301) veya 404 döndürür.

Kimlik doğrulama

Her istekte API anahtarınızı gövdedeki api_key alanında gönderin. HTTP başlığıyla (ör. Authorization) gönderilen anahtar okunmaz.

API anahtarını yalnızca sunucu tarafında kullanın. Tarayıcıda çalışan koda, mobil uygulama paketine veya herkese açık bir depoya koymayın. Anahtarın açığa çıktığını düşünüyorsanız panelden yenileyin veya iptal edin (bkz. API anahtarları).

Yanıt biçimi

Çoğu uç nokta aşağıdaki zarfı kullanır. Başarılı yanıtlarda uç noktaya özel alanlar aynı nesneye eklenir.

JSON — hata örneği
{
  "result": false,
  "result_code": "TS-1031",
  "result_message": "Invalid API key. Authentication failed."
}

Raporlar ve Numara engelleme uç noktaları result yerine status alanını kullanır ("success" veya "error").

Sonucu HTTP koduna göre değil, gövdeye göre değerlendirin. Bazı uç noktalar başarısız sonucu HTTP 200 ile döndürür (ör. grup adı zaten varsa veya rapor bulunamazsa). result (veya status) ve result_code alanlarını kontrol edin. result_message metinleri İngilizcedir ve değişebilir; programınızda result_code değerini kullanın.

Beklenmeyen bir sunucu hatasında yanıt genellikle HTTP 500 ve result_code SRV-ERR olur (Anahtar denetiminde TS-5000). Nadiren yanıt JSON olmayabilir veya result_code yerine error alanı içerebilir; kodunuzda JSON çözümleme hatasını da yakalayın. İsteği kısa bir süre sonra yeniden deneyebilirsiniz; gönderim uç noktalarında yeniden denemeden önce mesajın gidip gitmediğini SMS durumu sorgu veya Raporlar ile kontrol edin.

Hız sınırı

/sms/send için hesap bazında dakikalık bir gönderim sınırı uygulanabilir. Bu sınır TurkeySMS tarafından hesabınıza tanımlanır. Sınır, istek sayısına göre değil, hesabınızdan son bir dakikada kaydedilen mesaj (alıcı) sayısına göre uygulanır. Sınıra ulaşıldığında yanıt HTTP 429 ve TS-1060 olur; bir süre bekleyip yeniden deneyin.

Bu sınır, API Merkezi'nde anahtar için tanımlayabileceğiniz saatlik, günlük ve aylık limitlerden ayrıdır (bkz. Limitler ve IP izin listesi).

Tarih ve saat

Tarihler YYYY-AA-GG, saatler SS:DD:SS (saat:dakika:saniye) veya bazı alanlarda SS:DD biçimindedir. Yanıtlarda dönen tarih ve saat değerleri saat dilimi bilgisi içermez.

API anahtarları

API anahtarları panelde API Merkezi → Anahtarlarım sekmesinden yönetilir. Her anahtarın kendi izinleri vardır; farklı sistemleriniz için ayrı anahtarlar oluşturup her birine yalnızca gereken izinleri vermenizi öneririz.

Anahtar oluşturma

  1. Yeni Anahtar düğmesiyle sihirbazı açın: «Bilgiler», «Yetkiler», «Limitler».
  2. Anahtar oluşturulduğunda yalnızca bir kez gösterilir. Sayfadan ayrıldıktan sonra yeniden görüntülenemez; kaybederseniz anahtarı yenileyin.

Anahtar durumları

Panelde anahtarlar «Aktif», «Duraklatıldı», «Süresi doldu» veya «İptal» durumunda görünür. Yalnızca Aktif durumdaki anahtarlar istek yapabilir; panelde başka bir durumda görünen anahtarlarla yapılan istekler TS-1031 veya TS-1035 ile reddedilir. Anahtar için bir geçerlilik tarihi tanımlandıysa, tarih geçtikten sonra yapılan istekler TS-1035 ile reddedilir. Duraklatılan bir anahtarı yeniden etkinleştirebilirsiniz; iptal edilen anahtar geri alınamaz.

Anahtar yenileme

Anahtar ayrıntısında Tehlikeli Bölge → Anahtarı yenile (rotate) ile yeni bir anahtar oluşturulur; izinler ve ayarlar yeni anahtara taşınır. «Eski anahtar 24 saat daha çalışsın» seçeneğini işaretlerseniz eski anahtar 24 saat daha geçerli kalır; bu sürede sistemlerinizi yeni anahtara geçirebilirsiniz. Seçeneği işaretlemezseniz eski anahtar hemen geçersiz olur. Süre dolduktan sonra eski anahtarla yapılan istekler TS-1035 veya TS-1031 ile reddedilir. Anahtar sızdıysa seçeneği işaretlemeyin.

İzinler

İzinler anahtar ayrıntısında İzinler sekmesinden açılıp kapatılır. Aşağıdaki tablo her iznin hangi uç noktalarda kontrol edildiğini ve izin kapalıysa dönen kodu gösterir. «POST isteklerine izin ver» bir gönderim yöntemi değil, ayrı bir izindir; yalnızca listelenen uç noktalarda kontrol edilir.

İzin (panel)Uç noktalarKapalıysa
POST isteklerine izin ver/sms/send, /sms/status, /otp/detailed, /reports/basic, /reports/detailedTS-1061
SMS gönderimi/sms/sendTS-1062
Grup gönderimi/group/send, /group/sendMixedTS-1067
OTP gönderimi/otp/sendTS-1036
Gelişmiş OTP/otp/detailedTS-1037
Grup oluştur/groups/createTS-1081
Grup düzenle/groups/editTS-1084
Grup sil/groups/deleteTS-1085
Grup listele/groups/listTS-1089
Numara ekle/contacts/addTS-1065
Numara engelle/blacklist/post/add, /blacklist/post/statusTS-1065
Bakiye sorgu/balance/TS-1065
SMS durumu sorgu/sms/status, /reports/basic, /reports/detailedTS-1063
Başlık sorgu/senderid/checkTS-1038

/auth/post/check/ için izin gerekmez. Bir anahtarın izinlerini bu uç noktayla sorgulayabilirsiniz.

Limitler ve IP izin listesi

Sihirbazdaki «Limitler» adımında ve anahtar ayrıntısındaki «Limitler» ve «Güvenlik» sekmelerinde bir anahtar için saatlik, günlük ve aylık limit, IP izin listesi ve geçerlilik tarihi tanımlayabilirsiniz. Bu kurallar yalnızca API Merkezi'nde tanımlandığında uygulanır. Boş bırakılan veya 0 olan limit sınır olmadığı anlamına gelir; izin listesi boşsa IP kısıtlaması yoktur.

KuralNe zaman reddedilirKod (HTTP)
Saatlik limitAnahtarla o saat içinde (ör. 14:00–14:59) yapılan istek sayısı limite ulaştığında.TS-1068 (429)
Günlük limitAnahtarla o gün yapılan istek sayısı limite ulaştığında.TS-1069 (429)
Aylık limitAnahtarla o takvim ayında yapılan istek sayısı limite ulaştığında.TS-1073 (429)
IP izin listesiİsteğin geldiği IP adresi listede yoksa. Anahtara özel bir liste varsa yalnızca o kullanılır; yoksa hesabın listesi kullanılır. Liste tek IP adresi veya CIDR aralığı (ör. 203.0.113.0/24) içerebilir.TS-1066 (403)
Geçerlilik tarihiTarih geçtikten sonra. Anahtar, tanımlanan günün sonuna kadar geçerlidir.TS-1035 (403)
  • Limitler, anahtarla yapılan tüm API isteklerini sayar: gönderim, sorgu, rapor ve rehber istekleri dahil.
  • Saat, gün ve ay Türkiye saatine (Europe/Istanbul) göre hesaplanır.
  • Bu kurallar nedeniyle reddedilen istekler limite sayılmaz.
  • HTTP 429 aldığınızda bir sonraki saat, gün veya ay başlangıcını bekleyin ya da limiti panelden artırın.
  • Bu limitler, TurkeySMS'in hesabınıza tanımladığı dakikalık gönderim sınırından (TS-1060) ayrıdır.

Anahtar denetimi

API anahtarınızın geçerli olup olmadığını, izinlerini ve hesap özetini döndürür. Bir entegrasyonu canlıya almadan önce izinleri kontrol etmek için kullanabilirsiniz.

POST https://api.turkeysms.com.tr/auth/post/check/

Gerekli izin: Yok. Aktif bir API anahtarı yeterlidir.

Adres sondaki eğik çizgiyle yazılır: /auth/post/check/. Eski /auth/check adresi kullanılmaz (404).

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız. 20–128 karakter.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/auth/post/check/ \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
];

$ch = curl_init('https://api.turkeysms.com.tr/auth/post/check/');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
}

r = requests.post("https://api.turkeysms.com.tr/auth/post/check/", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
};

const r = await fetch('https://api.turkeysms.com.tr/auth/post/check/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1000",
  "result_message": "Authentication audit successful",
  "key_details": {
    "status": "Active",
    "permissions": {
      "post_request": true,
      "send_single_sms": true,
      "send_otp": true,
      "check_balance": true,
      "check_senderid": true,
      "manage_groups": false,
      "send_group_sms": true,
      "send_otp_advanced": false,
      "create_group": false,
      "edit_group": false,
      "delete_group": false,
      "list_groups": false,
      "add_contact": false,
      "delete_contact": false,
      "block_number": false,
      "check_sms_status": true
    }
  },
  "account_summary": {
    "account_status": "Active",
    "balance": { "main": 1500, "international": 0 },
    "global_sending": false
  },
  "audit_info": {
    "request_ip": "203.0.113.10",
    "checked_at": "2026-10-01 14:30:00"
  }
}
AlanAçıklama
key_details.statusAnahtarın durumu. Yalnızca aktif anahtarlar yanıt aldığı için başarılı yanıtta Active olur.
key_details.permissions16 izin alanı (true/false). Karşılıkları aşağıdaki tabloda.
account_summary.account_statusHesabın durumu. Başarılı yanıtta Active olur.
account_summary.balance.mainHesabınızdaki SMS kredisi (tam sayı).
account_summary.balance.international, account_summary.global_sendingEk alanlar.
audit_info.request_ipİsteğin geldiği IP adresi.
audit_info.checked_atDenetimin yapıldığı tarih ve saat.

İzin alanlarının panel karşılıkları:

AlanPanel izni
post_requestPOST isteklerine izin ver
send_single_smsSMS gönderimi
send_group_smsGrup gönderimi
send_otpOTP gönderimi
send_otp_advancedGelişmiş OTP
create_groupGrup oluştur
manage_groupsGrup oluştur (eski ad; create_group ile aynı değeri taşır, geriye dönük uyumluluk için korunur)
edit_groupGrup düzenle
delete_groupGrup sil
list_groupsGrup listele
add_contactNumara ekle
delete_contactPanelde karşılığı yoktur; bu sayfada belgelenen uç noktalarda kullanılmaz.
block_numberNumara engelle
check_balanceBakiye sorgu
check_sms_statusSMS durumu sorgu
check_senderidBaşlık sorgu

Hata yanıtı

JSON — 400
{
  "result": false,
  "result_code": "TS-1031",
  "result_message": "Invalid API key"
}
KodHTTPAnlamı
TS-1031401api_key eksik, metin değil veya 20–128 karakter dışında.
TS-1031400Anahtar bulunamadı ya da «Aktif» durumda değil.
TS-1030400Hesap aktif değil.
TS-5000500Beklenmeyen sunucu hatası.

SMS gönderimi

Bir veya birden fazla numaraya aynı metni gönderir. İstek başarılı olduğunda mesajlar operatöre iletilmek üzere işleme alınır.

POST https://api.turkeysms.com.tr/sms/send

Gerekli izinler: «POST isteklerine izin ver» ve «SMS gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
senttostringZorunluAlıcı numarası. Birden fazla numarayı virgül, noktalı virgül veya satır sonuyla ayırın. Bir istekte en fazla 500 farklı numara (zamanlanmış gönderimde 50.000). Aynı numara birden fazla yazılırsa bir kez gönderilir.
titlestringZorunluHesabınızda onaylı SMS başlığı. En fazla 11 karakter; Türkçe karakterler (ç, ğ, ı, ö, ş, ü) iki karakter sayılır.
textstringZorunluMesaj metni. En fazla 2.000 karakter. Metindeki TS-L ifadesi satır sonuna çevrilir.
sms_langintİsteğe bağlıKarakter seti ve SMS sayısı hesabı: 0 İngilizce, 1 Türkçe, 2 Arapça/Unicode. Varsayılan 2. Türkçe metinlerde 1 gönderin (bkz. Mesaj dili ve SMS sayısı).
content_typeintİsteğe bağlıİçerik etiketi: 0 Transactional, 1 High Quality, 2 Advertising. Varsayılan 0. Yalnızca yanıtta etiket olarak döner; gönderimi etkilemez.
scheduled_datestringİsteğe bağlıDoluysa gönderim zamanlanır. Bkz. Zamanlanmış gönderim.
scheduled_timestringKoşulluscheduled_date gönderildiğinde zorunludur.

Numara biçimi

Numaraları uluslararası biçimde, başında + olmadan gönderin: 905XXXXXXXXX. API boşlukları, +, - ve parantezleri kaldırır; 00 ile başlayan numaralarda 00'ı siler; 05… ve 10 haneli 5… numaraları 905… biçimine çevirir. Numaralar tek tek doğrulanmaz; hatalı bir numara da işleme alınır ve SMS sayısına eklenir. Numaraları göndermeden önce kendi tarafınızda doğrulayın.

Kurallar

  • Bakiyeniz, tüm alıcılar için hesaplanan toplam SMS sayısını karşılamalıdır; karşılamıyorsa hiçbir mesaj gönderilmez (TS-1027).
  • Dakikalık gönderim sınırı bu uç noktada uygulanır (bkz. Hız sınırı).
  • Numara engelleme listeniz bu uç noktada uygulanmaz (bkz. Numara engelleme).

İstek örneği

curl -X POST https://api.turkeysms.com.tr/sms/send \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "title": "BASLIGINIZ",
  "sentto": "905XXXXXXXXX,905YYYYYYYYY",
  "text": "Randevunuz yarın 10:00'\''da.TS-LBilgi için bizi arayın.",
  "sms_lang": 1
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'title'    => 'BASLIGINIZ',
    'sentto'   => '905XXXXXXXXX,905YYYYYYYYY',
    'text'     => 'Randevunuz yarın 10:00\'da.TS-LBilgi için bizi arayın.',
    'sms_lang' => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/sms/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "title":    "BASLIGINIZ",
    "sentto":   "905XXXXXXXXX,905YYYYYYYYY",
    "text":     "Randevunuz yarın 10:00'da.TS-LBilgi için bizi arayın.",
    "sms_lang": 1,
}

r = requests.post("https://api.turkeysms.com.tr/sms/send", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  title:    'BASLIGINIZ',
  sentto:   '905XXXXXXXXX,905YYYYYYYYY',
  text:     'Randevunuz yarın 10:00\'da.TS-LBilgi için bizi arayın.',
  sms_lang: 1,
};

const r = await fetch('https://api.turkeysms.com.tr/sms/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1024",
  "result_message": "SMS dispatched successfully.",
  "sms_id": 48213377,
  "number_of_sms": 2,
  "total_recipients": 2,
  "success_count": 2,
  "sms_lang": "Turkish",
  "content_type": "Transactional",
  "country": "Turkey-TR"
}
AlanAçıklama
sms_idSon alıcıya ait mesaj kimliği. Tek alıcılı gönderimlerde SMS durumu sorgu ile kullanılır.
number_of_smsTüm alıcılar için toplam SMS sayısı.
total_recipientsTekrarlar çıkarıldıktan sonraki alıcı sayısı.
success_countİşleme alınan alıcı sayısı. Teslim edilen mesaj sayısı değildir; teslim durumu için Webhook veya SMS durumu sorgu kullanın.
sms_lang, content_typeGönderdiğiniz değerlerin etiketi.
countryİlk alıcının ülke etiketi (ör. Turkey-TR, yurt dışı için GlobalSMS-GL).

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1027",
  "result_message": "Insufficient SMS credits. Please top up your account."
}
KodHTTPAnlamı
TS-1033400Gövde geçerli JSON veya form verisi değil.
TS-1050401api_key eksik veya 30 karakterden kısa.
TS-1025400sentto eksik, 7 karakterden kısa veya içinde numara yok.
TS-1051400title eksik.
TS-1029400title 11 karakterden uzun.
TS-1026400text boş veya 2.000 karakterden uzun.
TS-1060400Alıcı sayısı sınırı aşıldı: 500 (zamanlanmış gönderimde 50.000).
TS-1070 / TS-1071 / TS-1072400Zamanlama alanları geçersiz (bkz. Zamanlanmış gönderim).
TS-1031401Anahtar bulunamadı veya aktif değil.
TS-1061403«POST isteklerine izin ver» izni kapalı.
TS-1062403«SMS gönderimi» izni kapalı.
TS-1030403Hesap aktif değil.
TS-1028400Başlık hesabınızda bulunamadı veya onaylı değil.
TS-1027403Bakiye yetersiz.
TS-1060429Dakikalık gönderim sınırı aşıldı.
SRV-ERR500Beklenmeyen sunucu hatası.

Notlar

  • Webhook tanımladıysanız bu gönderim için sms.sent, sms.delivered ve sms.failed olayları gönderilir. Olayın hangi webhook'a gideceği için bkz. Webhook → Yönlendirme.
  • Bir isteği zaman aşımı nedeniyle yeniden göndermeden önce ilk isteğin işlenip işlenmediğini kontrol edin; aksi halde mesaj iki kez gönderilebilir.

Zamanlanmış gönderim

/sms/send isteğine scheduled_date ve scheduled_time eklendiğinde mesajlar hemen gönderilmez, belirtilen zamanda gönderilmek üzere sıraya alınır.

POST https://api.turkeysms.com.tr/sms/send

Gerekli izinler: «POST isteklerine izin ver» ve «SMS gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Ek parametreler

ParametreTürDurumAçıklama
scheduled_datestringZorunluGönderim tarihi, YYYY-AA-GG (ör. 2026-10-15).
scheduled_timestringZorunluGönderim saati, SS:DD veya SS:DD:ss (ör. 09:30).

Diğer parametreler SMS gönderimi ile aynıdır.

Kurallar

  • Belirtilen zaman gelecekte olmalıdır. Tarih ve saat Türkiye saatine (Europe/Istanbul) göre değerlendirilir.
  • Bir istekte en fazla 50.000 farklı numara gönderilebilir.
  • Bakiye kontrolü ve dakikalık gönderim sınırı istek anında uygulanır.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/sms/send \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "title": "BASLIGINIZ",
  "sentto": "905XXXXXXXXX",
  "text": "Kampanyamız yarın başlıyor.",
  "sms_lang": 1,
  "scheduled_date": "2026-10-15",
  "scheduled_time": "09:30"
}'
$payload = [
    'api_key'        => 'API_ANAHTARINIZ',
    'title'          => 'BASLIGINIZ',
    'sentto'         => '905XXXXXXXXX',
    'text'           => 'Kampanyamız yarın başlıyor.',
    'sms_lang'       => 1,
    'scheduled_date' => '2026-10-15',
    'scheduled_time' => '09:30',
];

$ch = curl_init('https://api.turkeysms.com.tr/sms/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":        "API_ANAHTARINIZ",
    "title":          "BASLIGINIZ",
    "sentto":         "905XXXXXXXXX",
    "text":           "Kampanyamız yarın başlıyor.",
    "sms_lang":       1,
    "scheduled_date": "2026-10-15",
    "scheduled_time": "09:30",
}

r = requests.post("https://api.turkeysms.com.tr/sms/send", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:        'API_ANAHTARINIZ',
  title:          'BASLIGINIZ',
  sentto:         '905XXXXXXXXX',
  text:           'Kampanyamız yarın başlıyor.',
  sms_lang:       1,
  scheduled_date: '2026-10-15',
  scheduled_time: '09:30',
};

const r = await fetch('https://api.turkeysms.com.tr/sms/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1024",
  "result_message": "SMS dispatched successfully.",
  "sms_id": 734129955,
  "number_of_sms": 1,
  "total_recipients": 1,
  "success_count": 1,
  "sms_lang": "Turkish",
  "content_type": "Transactional",
  "country": "Turkey-TR"
}

Zamanlanmış gönderimde sms_id, gönderimin rapor kimliğidir. Bu değeri Raporlar uç noktalarında raporid olarak kullanın; SMS durumu sorgu bu kimliği tanımaz.

Hata yanıtı

JSON — 400
{
  "result": false,
  "result_code": "TS-1072",
  "result_message": "Scheduled time must not be in the past."
}
KodHTTPAnlamı
TS-1070400scheduled_date YYYY-AA-GG biçiminde değil veya scheduled_time eksik.
TS-1071400scheduled_time SS:DD veya SS:DD:ss biçiminde değil.
TS-1072400Belirtilen zaman geçmişte veya geçersiz (ör. 25:99).
TS-106040050.000 numara sınırı aşıldı.

Diğer kodlar SMS gönderimi ile aynıdır.

Grup gönderimi

Çok sayıda numaraya tek istekle gönderim yapar. İki uç nokta vardır:

  • /group/send: tüm numaralara aynı metin.
  • /group/sendMixed: her numaraya kendi metni. text bir dizi olur ve sırası numara dizisiyle eşleşir.
POST https://api.turkeysms.com.tr/group/send
POST https://api.turkeysms.com.tr/group/sendMixed

Gerekli izin: «Grup gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
titlestringZorunluHesabınızda onaylı SMS başlığı.
senttoarrayZorunluNumara dizisi (JSON dizisi; virgüllü metin kabul edilmez). En fazla 50.000 öğe. numbers adıyla da gönderilebilir.
textstring / arrayZorunlu/group/send: tek metin. /group/sendMixed: numara sayısıyla aynı uzunlukta metin dizisi; text[i], sentto[i] numarasına gider. Her metin en fazla 2.000 karakter; TS-L satır sonuna çevrilir.
sms_langintİsteğe bağlı0 İngilizce, 1 Türkçe, 2 Arapça/Unicode. Varsayılan 2. Türkçe metinlerde 1 gönderin.
scheduled_smsintİsteğe bağlı1 gönderilirse gönderim zamanlanır.
scheduled_datestringKoşulluscheduled_sms 1 ise zorunlu. YYYY-AA-GG.
scheduled_timestringKoşulluscheduled_sms 1 ise zorunlu. SS:DD veya SS:DD:ss. Tarih ve saat Türkiye saatine (Europe/Istanbul) göre değerlendirilir.

Kurallar

  • Numaralar /sms/send ile aynı kurallarla dönüştürülür: boşluklar, +, - ve parantezler kaldırılır; 00 ile başlayan numaralarda 00 silinir; 05… ve 10 haneli 5… numaralar 905… biçimine çevrilir. Numaralar tek tek doğrulanmaz.
  • /group/send isteğinde tekrarlanan numara bir kez sıraya alınır. /group/sendMixed isteğinde aynı numara ve aynı metin çifti bir kez sıraya alınır; aynı numaraya farklı metinler ayrı ayrı gönderilir.
  • Bakiyeniz toplam SMS sayısını karşılamalıdır (TS-1027).
  • Tarih ve saat alanlarını yalnızca scheduled_sms: 1 ile birlikte gönderin.
  • Numara engelleme listeniz bu uç noktalarda uygulanmaz (bkz. Numara engelleme).
  • Başarılı yanıt, gönderimin sıraya alındığını gösterir; mesajlar ardından gönderilir.

İstek örneği (/group/send)

curl -X POST https://api.turkeysms.com.tr/group/send \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "title": "BASLIGINIZ",
  "sentto": [
    "905XXXXXXXXX",
    "905YYYYYYYYY"
  ],
  "text": "Mağazamız bugün 21:00'\''e kadar açıktır.",
  "sms_lang": 1
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'title'    => 'BASLIGINIZ',
    'sentto'   => ['905XXXXXXXXX', '905YYYYYYYYY'],
    'text'     => 'Mağazamız bugün 21:00\'e kadar açıktır.',
    'sms_lang' => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/group/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "title":    "BASLIGINIZ",
    "sentto":   ["905XXXXXXXXX", "905YYYYYYYYY"],
    "text":     "Mağazamız bugün 21:00'e kadar açıktır.",
    "sms_lang": 1,
}

r = requests.post("https://api.turkeysms.com.tr/group/send", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  title:    'BASLIGINIZ',
  sentto:   ['905XXXXXXXXX', '905YYYYYYYYY'],
  text:     'Mağazamız bugün 21:00\'e kadar açıktır.',
  sms_lang: 1,
};

const r = await fetch('https://api.turkeysms.com.tr/group/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

İstek örneği (/group/sendMixed)

curl -X POST https://api.turkeysms.com.tr/group/sendMixed \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "title": "BASLIGINIZ",
  "sentto": [
    "905XXXXXXXXX",
    "905YYYYYYYYY"
  ],
  "text": [
    "Sayın Ayşe Hanım, siparişiniz hazır.",
    "Sayın Mehmet Bey, siparişiniz hazır."
  ],
  "sms_lang": 1
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'title'    => 'BASLIGINIZ',
    'sentto'   => ['905XXXXXXXXX', '905YYYYYYYYY'],
    'text'     => ['Sayın Ayşe Hanım, siparişiniz hazır.', 'Sayın Mehmet Bey, siparişiniz hazır.'],
    'sms_lang' => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/group/sendMixed');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "title":    "BASLIGINIZ",
    "sentto":   ["905XXXXXXXXX", "905YYYYYYYYY"],
    "text":     ["Sayın Ayşe Hanım, siparişiniz hazır.", "Sayın Mehmet Bey, siparişiniz hazır."],
    "sms_lang": 1,
}

r = requests.post("https://api.turkeysms.com.tr/group/sendMixed", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  title:    'BASLIGINIZ',
  sentto:   ['905XXXXXXXXX', '905YYYYYYYYY'],
  text:     ['Sayın Ayşe Hanım, siparişiniz hazır.', 'Sayın Mehmet Bey, siparişiniz hazır.'],
  sms_lang: 1,
};

const r = await fetch('https://api.turkeysms.com.tr/group/sendMixed', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1024",
  "result_message": "Bulk SMS dispatched successfully.",
  "rapor_id": 482913377,
  "total_numbers": 2,
  "total_sms_cost": 2,
  "scheduled": false
}
AlanAçıklama
rapor_idGönderimin rapor kimliği. Raporlar uç noktalarında raporid olarak kullanılır.
total_numbersDönüştürme ve tekrar ayıklamadan sonra sıraya alınan numara sayısı.
total_sms_costToplam SMS sayısı.
scheduledGönderim zamanlandıysa true.

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1028",
  "result_message": "Sender ID was not found in your account or is not approved."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz, text boş, text türü yanlış veya /group/sendMixed'de metin ve numara sayısı eşit değil.
TS-1025400api_key eksik veya 30 karakterden kısa.
TS-1029400title eksik.
TS-1026400sentto eksik veya dizi değil ya da bir metin 2.000 karakterden uzun.
TS-106040050.000 numara sınırı aşıldı.
TS-1070 / TS-1071 / TS-1072400Zamanlama alanları geçersiz: tarih biçimi, saat biçimi veya geçmiş zaman.
TS-1031403Anahtar bulunamadı veya aktif değil.
TS-1067403«Grup gönderimi» izni kapalı.
TS-1030403Hesap aktif değil.
TS-1028403Başlık hesabınızda bulunamadı veya onaylı değil.
TS-1027403Bakiye yetersiz.
SRV-ERR500Beklenmeyen sunucu hatası.

OTP gönderimi

Tek bir numaraya, TurkeySMS tarafından üretilen bir doğrulama kodu (OTP) gönderir. Metin hazır şablondan oluşur; gönderici adı her zaman OTPSMS olur.

POST https://api.turkeysms.com.tr/otp/send

Gerekli izin: «OTP gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
mobilestringZorunluTek alıcı numarası. 905XXXXXXXXX biçiminde gönderin; 05…, 5… ve 00… biçimleri de dönüştürülür.
digitsintİsteğe bağlıKod uzunluğu: 4, 5 veya 6. Varsayılan 4; başka değerlerde 4 kullanılır.
sms_langintİsteğe bağlıŞablon dili: 0 İngilizce, 1 Türkçe, 2 Arapça. Varsayılan 2. lang adıyla da gönderilebilir; ikisi birlikte gelirse sms_lang kullanılır.

Şablonlar

MARKA, hesabınıza tanımlı OTP marka adıdır. Örnekte kod 4821'dir.

sms_lang: 1 (Türkçe)
4821
Aktivasyon kodunuz OTP
MARKA
sms_lang: 0 (İngilizce)
Your activation code is:4821
MARKA
sms_lang: 2 (Arapça)
4821
هو رمز التفعيل الخاص بك
MARKA

İstek örneği

curl -X POST https://api.turkeysms.com.tr/otp/send \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "mobile": "905XXXXXXXXX",
  "digits": 6,
  "sms_lang": 1
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'mobile'   => '905XXXXXXXXX',
    'digits'   => 6,
    'sms_lang' => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/otp/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "mobile":   "905XXXXXXXXX",
    "digits":   6,
    "sms_lang": 1,
}

r = requests.post("https://api.turkeysms.com.tr/otp/send", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  mobile:   '905XXXXXXXXX',
  digits:   6,
  sms_lang: 1,
};

const r = await fetch('https://api.turkeysms.com.tr/otp/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1024",
  "result_message": "OTP dispatched successfully.",
  "sms_id": 48213390,
  "otp_code": 482193,
  "sandbox": false
}
AlanAçıklama
sms_idMesaj kimliği; SMS durumu sorgu ile kullanılabilir.
otp_codeGönderilen kod. Tam sayı olarak döner ve 0 ile başlamaz.
sandboxCanlı isteklerde false.
Kodu doğrulamak sizin sisteminizin görevidir. API'de doğrulama uç noktası yoktur. otp_code değerini sunucunuzda kısa bir geçerlilik süresiyle (ör. 3–5 dakika) saklayın, kullanıcının girdiği kodla karşılaştırın ve kullanıldıktan sonra silin. Kodu istemciye (tarayıcı, mobil uygulama) göndermeyin. Aynı numaraya kısa sürede çok sayıda istek gelmesini kendi tarafınızda sınırlayın.

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1036",
  "result_message": "OTP sending privilege is disabled for this API key."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz.
TS-1050401api_key eksik veya 30 karakterden kısa.
TS-1025400mobile eksik veya 7 karakterden kısa.
TS-1034403Numara biçimi geçersiz (temizlendikten sonra 11–15 hane olmalıdır).
TS-1031403Anahtar bulunamadı veya aktif değil.
TS-1036403«OTP gönderimi» izni kapalı.
TS-1030403Hesap aktif değil.
TS-1027403Bakiye yetersiz.
TS-5000403Mesaj kaydedilemedi; isteği yeniden deneyin.
SRV-ERR500Beklenmeyen sunucu hatası.

Gelişmiş OTP

Kendi başlığınız ve kendi metninizle OTP gönderir. Kodu TurkeySMS üretir ve metindeki TS-CODE ifadesinin yerine koyar.

POST https://api.turkeysms.com.tr/otp/detailed

Gerekli izinler: «POST isteklerine izin ver» ve «Gelişmiş OTP» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
mobilestringZorunluTek alıcı numarası, 905XXXXXXXXX.
titlestringZorunluHesabınızdaki SMS başlığı. En fazla 11 karakter; Türkçe karakterler iki karakter sayılır. Başlığın onaylı olması, belgesinin onaylanmış olması ve operatör onayının tamamlanmış olması gerekir.
textstringZorunluMesaj metni; TS-CODE ifadesini içermelidir (büyük harfle). En fazla 2.000 karakter. TS-L satır sonuna çevrilir.
langintİsteğe bağlı0 İngilizce, 1 Türkçe, 2 Arapça/Unicode. Varsayılan 2. Bu uç noktada sms_lang okunmaz; lang kullanın.
digitsintİsteğe bağlıKod uzunluğu: 4, 5 veya 6. Varsayılan 4.

Kurallar

  • Şu başlıklar kabul edilmez (büyük/küçük harf fark etmez): test, api, apikey, api_key, test123, 123, 0000, 123456789, senderid, sender, title, text, content.
  • Bakiyeniz, metnin SMS sayısını karşılamalıdır. SMS sayısı Mesaj dili ve SMS sayısı tablolarıyla hesaplanır.
  • Doğrulama hataları HTTP 400, hesap ve izin hataları HTTP 403 ile döner.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/otp/detailed \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "mobile": "905XXXXXXXXX",
  "title": "BASLIGINIZ",
  "text": "Giriş kodunuz: TS-CODE. Kodu kimseyle paylaşmayın.",
  "lang": 1,
  "digits": 6
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'mobile'  => '905XXXXXXXXX',
    'title'   => 'BASLIGINIZ',
    'text'    => 'Giriş kodunuz: TS-CODE. Kodu kimseyle paylaşmayın.',
    'lang'    => 1,
    'digits'  => 6,
];

$ch = curl_init('https://api.turkeysms.com.tr/otp/detailed');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "mobile":  "905XXXXXXXXX",
    "title":   "BASLIGINIZ",
    "text":    "Giriş kodunuz: TS-CODE. Kodu kimseyle paylaşmayın.",
    "lang":    1,
    "digits":  6,
}

r = requests.post("https://api.turkeysms.com.tr/otp/detailed", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  mobile:  '905XXXXXXXXX',
  title:   'BASLIGINIZ',
  text:    'Giriş kodunuz: TS-CODE. Kodu kimseyle paylaşmayın.',
  lang:    1,
  digits:  6,
};

const r = await fetch('https://api.turkeysms.com.tr/otp/detailed', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1024",
  "result_message": "OTP dispatched successfully.",
  "sms_id": 48213391,
  "otp_code": 482193,
  "number_of_sms": 1,
  "sms_lang": "Turkish",
  "sandbox": false
}
AlanAçıklama
sms_idMesaj kimliği.
otp_codeGönderilen kod. Tam sayı olarak döner ve 0 ile başlamaz.
number_of_smsMesajın SMS sayısı.
sms_langlang değerinin etiketi.
sandboxCanlı isteklerde false.
Operatöre iletim sırasında bir hata olursa yanıt yine TS-1024 döner. Mesajın durumunu SMS durumu sorgu ile kontrol edebilirsiniz; iletim hatasında TS-1022 ve details alanında hata açıklaması döner. Kodun doğrulanması için OTP gönderimi bölümündeki uyarı burada da geçerlidir.

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1028",
  "result_message": "Sender ID is not approved for OTP (approval, document and network approval are required)."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz, bir alan metin değil veya başlık kabul edilmeyenler listesinde.
TS-1050400api_key eksik.
TS-1025400mobile eksik.
TS-1051400title eksik.
TS-1026400text boş, TS-CODE içermiyor veya 2.000 karakterden uzun.
TS-1031400 403400: anahtar 30 karakterden kısa. 403: anahtar bulunamadı veya aktif değil.
TS-1034400Numara biçimi geçersiz.
TS-1029400 403400: başlık 11 karakterden uzun. 403: başlık hesabınızda bulunamadı.
TS-1061403«POST isteklerine izin ver» izni kapalı.
TS-1037403«Gelişmiş OTP» izni kapalı.
TS-1030403Hesap aktif değil.
TS-1028403Başlık OTP için onaylı değil (onay, belge veya operatör onayı eksik).
TS-1027403Bakiye yetersiz.
TS-5000403Mesaj kaydedilemedi; isteği yeniden deneyin.
SRV-ERR500Beklenmeyen sunucu hatası.

Mesaj dili ve SMS sayısı

sms_lang (Gelişmiş OTP'de lang) mesajın karakter setini ve kaç SMS sayılacağını belirler. Yanlış değer, metnin daha fazla SMS'e bölünmesine yol açabilir.

DeğerKullanım
0İngilizce; yalnızca Latin harfleri ve standart işaretler (Türkçe karakter yok).
1Türkçe; ç, ğ, ı, İ, ö, ş, ü içeren metinler.
2Arapça ve diğer Unicode metinler. Varsayılan değerdir.

SMS sayısı

Tablodaki sayılar, belirtilen SMS sayısına sığan en fazla karakter sayısıdır. Karakter sayısı, TS-L satır sonuna çevrildikten sonra hesaplanır.

Metin uzunluğu en fazla1234567
Türkiye numaraları, sms_lang 01603054556107609101070
Türkiye numaraları, sms_lang 11552454455957408901040
Türkiye numaraları, sms_lang 265127190250315380445
Yurt dışı numaralar (tüm değerler)70130195260325390450
  • Son sütunu aşan metinler 8 SMS olarak hesaplanır.
  • /sms/send ve /otp/detailed, 905 ile başlamayan numaraları yurt dışı numara sayar. /group/send ve /group/sendMixed tüm numaralar için Türkiye tablosunu kullanır.

İçerik etiketi

/sms/send isteğindeki content_type (0 Transactional, 1 High Quality, 2 Advertising) yalnızca yanıtta etiket olarak döner; gönderim yolunu veya fiyatı değiştirmez.

Gruplar

Rehberinizdeki grupları oluşturur, yeniden adlandırır, siler ve listeler. Her işlemin ayrı bir izni vardır.

Bu uç noktalarda bazı başarısız sonuçlar HTTP 200 ile döner (ör. TS-1082, TS-1086). Sonucu her zaman result ve result_code ile değerlendirin.

Grup oluşturma

POST https://api.turkeysms.com.tr/groups/create

Gerekli izin: «Grup oluştur» (API Merkezi → Anahtarlarım → anahtar → İzinler)

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
group_namestringZorunluGrup adı. 2–50 karakter; Türkçe karakterler iki karakter sayılır. Aktif gruplarınız arasında benzersiz olmalıdır.
curl -X POST https://api.turkeysms.com.tr/groups/create \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "group_name": "Müşteriler"
}'
$payload = [
    'api_key'    => 'API_ANAHTARINIZ',
    'group_name' => 'Müşteriler',
];

$ch = curl_init('https://api.turkeysms.com.tr/groups/create');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":    "API_ANAHTARINIZ",
    "group_name": "Müşteriler",
}

r = requests.post("https://api.turkeysms.com.tr/groups/create", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:    'API_ANAHTARINIZ',
  group_name: 'Müşteriler',
};

const r = await fetch('https://api.turkeysms.com.tr/groups/create', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1080",
  "result_message": "Group created successfully.",
  "group": {
    "id": 5412,
    "name": "Müşteriler",
    "created_at": "2026-10-01"
  }
}

group.id değerini numara eklerken group_id olarak kullanın.

Grup adını değiştirme

POST https://api.turkeysms.com.tr/groups/edit

Gerekli izin: «Grup düzenle» (API Merkezi → Anahtarlarım → anahtar → İzinler)

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
group_idintZorunluGrup kimliği.
new_namestringZorunluYeni ad. Bu uç noktada uzunluk ve benzersizlik kontrol edilmez; adı 2–50 karakter ve benzersiz tutmanızı öneririz.
curl -X POST https://api.turkeysms.com.tr/groups/edit \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "group_id": 5412,
  "new_name": "VIP Müşteriler"
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'group_id' => 5412,
    'new_name' => 'VIP Müşteriler',
];

$ch = curl_init('https://api.turkeysms.com.tr/groups/edit');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "group_id": 5412,
    "new_name": "VIP Müşteriler",
}

r = requests.post("https://api.turkeysms.com.tr/groups/edit", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  group_id: 5412,
  new_name: 'VIP Müşteriler',
};

const r = await fetch('https://api.turkeysms.com.tr/groups/edit', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1087",
  "result_message": "Group name updated successfully.",
  "new_name": "VIP Müşteriler"
}

Grup silme

POST https://api.turkeysms.com.tr/groups/delete

Gerekli izin: «Grup sil» (API Merkezi → Anahtarlarım → anahtar → İzinler)

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
group_idintZorunluGrup kimliği.

Silinen grup listelerden kaldırılır ve yeniden kullanılamaz. Gruba eklenmiş numaralar silinmez.

curl -X POST https://api.turkeysms.com.tr/groups/delete \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "group_id": 5412
}'
$payload = [
    'api_key'  => 'API_ANAHTARINIZ',
    'group_id' => 5412,
];

$ch = curl_init('https://api.turkeysms.com.tr/groups/delete');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":  "API_ANAHTARINIZ",
    "group_id": 5412,
}

r = requests.post("https://api.turkeysms.com.tr/groups/delete", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:  'API_ANAHTARINIZ',
  group_id: 5412,
};

const r = await fetch('https://api.turkeysms.com.tr/groups/delete', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1088",
  "result_message": "Group deleted successfully."
}

Grupları listeleme

POST https://api.turkeysms.com.tr/groups/list

Gerekli izin: «Grup listele» (API Merkezi → Anahtarlarım → anahtar → İzinler)

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
searchstringİsteğe bağlıAd içinde arama. Boşsa tüm gruplar döner.
curl -X POST https://api.turkeysms.com.tr/groups/list \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "search": "Müşteri"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'search'  => 'Müşteri',
];

$ch = curl_init('https://api.turkeysms.com.tr/groups/list');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "search":  "Müşteri",
}

r = requests.post("https://api.turkeysms.com.tr/groups/list", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  search:  'Müşteri',
};

const r = await fetch('https://api.turkeysms.com.tr/groups/list', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1090",
  "result_message": "Group list retrieved successfully.",
  "groups_count": 2,
  "groups": [
    {
      "id": 5413,
      "name": "VIP Müşteriler",
      "date": "2026-10-01"
    },
    {
      "id": 5398,
      "name": "Müşteriler 2025",
      "date": "2026-04-02"
    }
  ]
}

Yalnızca silinmemiş gruplar, en yeniden eskiye doğru döner. Sayfalama yoktur.

Yanıt kodları

JSON — 200 (başarısız sonuç)
{
  "result": false,
  "result_code": "TS-1082",
  "result_message": "Group name already exists."
}
KodHTTPAnlamı
TS-1080 / TS-1087 / TS-1088 / TS-1090200Oluşturuldu / güncellendi / silindi / listelendi.
TS-1033400Gövde geçersiz.
TS-1050400api_key eksik.
TS-1031400Anahtar 30 karakterden kısa, bulunamadı veya aktif değil.
TS-1081 / TS-1084 / TS-1085 / TS-1089400İlgili izin kapalı: oluştur / düzenle / sil / listele.
TS-1030400Hesap aktif değil.
TS-1082200Bu adda aktif bir grup zaten var.
TS-1083400 200Grup adı boş veya 2–50 karakter dışında. Düzenlemede geçersiz group_id için de 200 ile döner.
TS-1086400 200400: group_id eksik. 200: grup bulunamadı, size ait değil veya silinmiş.
SRV-ERR500Beklenmeyen sunucu hatası.

Numaralar

Bir gruba numara ekler. Numara, ad ve üç ek alanla birlikte rehberinize kaydedilir.

POST https://api.turkeysms.com.tr/contacts/add

Gerekli izin: «Numara ekle» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
group_idintZorunluNumaranın ekleneceği grubun kimliği (bkz. Gruplar).
gsm_numberstringZorunluTürkiye cep telefonu numarası. 905XXXXXXXXX, 05XXXXXXXXX, 5XXXXXXXXX, +905… ve 00905… kabul edilir; 905XXXXXXXXX olarak kaydedilir.
namestringİsteğe bağlıKişinin adı.
f_01, f_02, f_03stringİsteğe bağlıEk alanlar; kişiselleştirme için serbest metin.

Kurallar

  • Yalnızca Türkiye cep telefonu numaraları eklenebilir.
  • Aynı numaranın gruba daha önce eklenip eklenmediği kontrol edilmez; tekrarları kendi tarafınızda önleyin.
  • Numara engelleme listeniz bu uç noktada kontrol edilmez.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/contacts/add \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "group_id": 5412,
  "gsm_number": "905XXXXXXXXX",
  "name": "Ayşe Yılmaz",
  "f_01": "İstanbul"
}'
$payload = [
    'api_key'    => 'API_ANAHTARINIZ',
    'group_id'   => 5412,
    'gsm_number' => '905XXXXXXXXX',
    'name'       => 'Ayşe Yılmaz',
    'f_01'       => 'İstanbul',
];

$ch = curl_init('https://api.turkeysms.com.tr/contacts/add');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key":    "API_ANAHTARINIZ",
    "group_id":   5412,
    "gsm_number": "905XXXXXXXXX",
    "name":       "Ayşe Yılmaz",
    "f_01":       "İstanbul",
}

r = requests.post("https://api.turkeysms.com.tr/contacts/add", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key:    'API_ANAHTARINIZ',
  group_id:   5412,
  gsm_number: '905XXXXXXXXX',
  name:       'Ayşe Yılmaz',
  f_01:       'İstanbul',
};

const r = await fetch('https://api.turkeysms.com.tr/contacts/add', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1100",
  "result_message": "Contact added successfully.",
  "group_id": 5412,
  "total_sent": 1,
  "total_added": 1,
  "total_failed": 0,
  "mobile": "905XXXXXXXXX"
}

mobile, kaydedilen numaradır. total_sent, total_added ve total_failed tek numaralık bu işlemin özetidir.

Hata yanıtı

JSON — 200 (başarısız sonuç)
{
  "result": false,
  "result_code": "TS-1101",
  "result_message": "Failed to add contact."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz.
TS-1050400api_key eksik.
TS-1025400gsm_number eksik.
TS-1086400 200400: group_id eksik ya da grup bulunamadı veya size ait değil. 200: group_id sayı değil veya sıfırdan büyük değil.
TS-1031400Anahtar bulunamadı veya aktif değil.
TS-1065400«Numara ekle» izni kapalı.
TS-1030400Hesap aktif değil.
TS-1101200Numara geçerli bir Türkiye cep telefonu numarası değil.
SRV-ERR500Beklenmeyen sunucu hatası.

Numara engelleme

Numara engelleme listenize numara ekler ve bir numaranın listede olup olmadığını sorgular. Liste hesap bazındadır.

Kapsam: Numara engelleme listesi şu an yalnızca panelden yapılan gönderimlerde uygulanır. /sms/send, /otp/* ve /group/* ile yapılan API gönderimlerinde uygulanmaz; API ile gönderim yapıyorsanız engelli numaraları kendi tarafınızda ayıklayın.
POST https://api.turkeysms.com.tr/blacklist/post/add
POST https://api.turkeysms.com.tr/blacklist/post/status

Gerekli izin: «Numara engelle» (API Merkezi → Anahtarlarım → anahtar → İzinler)

İzin her iki uç nokta için de gereklidir. Eski /blacklist/add ve /blacklist/status adresleri kullanılmaz (404).

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
numberstringZorunluTürkiye cep numarası. 905XXXXXXXXX, +90 5XX…, 0090 5XX…, 05XX… ve 5XX… biçimleri kabul edilir ve 905XXXXXXXXX biçimine çevrilir.
Numara panelle aynı kuralla 905XXXXXXXXX biçiminde kaydedilir. Ekleme ve sorgulamada numaranın son 10 hanesi karşılaştırılır; bu nedenle 05321234567 ile 905321234567 aynı numara sayılır. Sabit hatlar ve yurt dışı numaralar kabul edilmez (TS-1144).

Yanıt biçimi farkı: bu uç noktalar result yerine status alanını kullanır ("success" veya "error").

Numara ekleme

curl -X POST https://api.turkeysms.com.tr/blacklist/post/add \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "number": "905XXXXXXXXX"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'number'  => '905XXXXXXXXX',
];

$ch = curl_init('https://api.turkeysms.com.tr/blacklist/post/add');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['status'] ?? '') === 'success') {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "number":  "905XXXXXXXXX",
}

r = requests.post("https://api.turkeysms.com.tr/blacklist/post/add", json=payload, timeout=30)
data = r.json()
if data.get("status") == "success":
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  number:  '905XXXXXXXXX',
};

const r = await fetch('https://api.turkeysms.com.tr/blacklist/post/add', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.status === 'success') {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "status": "success",
  "result_code": "TS-1141",
  "result_message": "Number added to blacklist successfully"
}

Numara sorgulama

curl -X POST https://api.turkeysms.com.tr/blacklist/post/status \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "number": "905XXXXXXXXX"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'number'  => '905XXXXXXXXX',
];

$ch = curl_init('https://api.turkeysms.com.tr/blacklist/post/status');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['status'] ?? '') === 'success') {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "number":  "905XXXXXXXXX",
}

r = requests.post("https://api.turkeysms.com.tr/blacklist/post/status", json=payload, timeout=30)
data = r.json()
if data.get("status") == "success":
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  number:  '905XXXXXXXXX',
};

const r = await fetch('https://api.turkeysms.com.tr/blacklist/post/status', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.status === 'success') {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK (listede)
{
  "status": "success",
  "result_code": "TS-1143",
  "result_message": "The phone number is currently in the blacklist.",
  "is_blocked": true,
  "block_date": "2026-10-01",
  "block_time": "14:30"
}
JSON — 200 OK (listede değil)
{
  "status": "success",
  "result_code": "TS-1142",
  "result_message": "The phone number is NOT in the blacklist.",
  "is_blocked": false
}

block_date ve block_time, numaranın listeye eklendiği tarih ve saattir. Listeyi görüntülemek ve numara çıkarmak için paneldeki Numara Engelleme sayfasını kullanın; API'de çıkarma uç noktası yoktur.

Hata yanıtı

JSON — 403
{
  "status": "error",
  "result_code": "TS-1065",
  "result_message": "Number blocking privilege is disabled for this API key."
}
KodHTTPAnlamı
TS-1141200Numara listeye eklendi.
TS-1143 / TS-1142200Numara listede / listede değil.
TS-1050403api_key eksik veya gövde geçersiz.
TS-1031401Anahtar 20 karakterden kısa, bulunamadı veya aktif değil ya da hesap aktif değil.
TS-1025400number eksik.
TS-1144400Numara geçerli bir Türkiye cep numarası değil.
TS-1065403«Numara engelle» izni kapalı.
TS-1140400Numara listenizde zaten var.
TS-1033400Kayıt sırasında hata oluştu; yeniden deneyin.
TS-404404Yol hatalı.

Bakiye sorgu

Hesabınızdaki SMS kredisini döndürür.

POST https://api.turkeysms.com.tr/balance/

Gerekli izin: «Bakiye sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Adres sondaki eğik çizgiyle yazılır: /balance/. Eğik çizgisiz adres yönlendirme (301) döndürür; bazı HTTP istemcileri yönlendirmede POST isteğini GET'e çevirir ve istek başarısız olur.

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/balance/ \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
];

$ch = curl_init('https://api.turkeysms.com.tr/balance/');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
}

r = requests.post("https://api.turkeysms.com.tr/balance/", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
};

const r = await fetch('https://api.turkeysms.com.tr/balance/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1040",
  "result_message": "Balance retrieved successfully.",
  "balance_main": 1500
}

balance_main: SMS kredisi (tam sayı).

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1065",
  "result_message": "Balance inquiry privilege is disabled for this key."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz.
TS-1050400api_key eksik.
TS-1025400api_key 30 karakterden kısa.
TS-1031403Anahtar bulunamadı veya aktif değil.
TS-1065403«Bakiye sorgu» izni kapalı.
TS-1030403Hesap aktif değil.
SRV-ERR403 500Beklenmeyen sunucu hatası.

Başlık sorgu

Hesabınızda onaylı SMS başlıklarını listeler. Gönderimlerde title alanına bu listedeki bir başlığı yazın.

POST https://api.turkeysms.com.tr/senderid/check

Gerekli izin: «Başlık sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/senderid/check \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ"
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
];

$ch = curl_init('https://api.turkeysms.com.tr/senderid/check');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
}

r = requests.post("https://api.turkeysms.com.tr/senderid/check", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
};

const r = await fetch('https://api.turkeysms.com.tr/senderid/check', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1040",
  "result_message": "Operation success.",
  "sender_ids_count": 2,
  "sender_ids": [
    {
      "id": 1288,
      "title": "BASLIGINIZ",
      "status": 1,
      "network_stat": 1
    },
    {
      "id": 1102,
      "title": "MAGAZA",
      "status": 1,
      "network_stat": 1
    }
  ]
}
AlanAçıklama
sender_ids_countListedeki başlık sayısı.
sender_ids[].idBaşlık kimliği.
sender_ids[].titleSMS başlığı; gönderimde title olarak kullanılır.
sender_ids[].statusOnaylı başlıklar listelendiği için her zaman 1.
sender_ids[].network_statDeğerleri henüz tanımlanmamıştır; entegrasyonunuzda kullanmayın.

Liste en yeni başlıktan başlar. Onay bekleyen veya reddedilen başlıklar listelenmez; onaylı başlık yoksa sender_ids boş dizi olur.

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1038",
  "result_message": "Sender ID inquiry privilege is disabled for this key."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz.
TS-1050400api_key eksik.
TS-1031400 403400: anahtar 30 karakterden kısa. 403: anahtar bulunamadı veya aktif değil.
TS-1038403«Başlık sorgu» izni kapalı.
TS-1030403Hesap aktif değil.
SRV-ERR403 500Beklenmeyen sunucu hatası.

SMS durumu sorgu

Tek bir mesajın teslim durumunu döndürür. Yalnızca kendi hesabınızdan gönderilen mesajlar sorgulanabilir.

POST https://api.turkeysms.com.tr/sms/status

Gerekli izinler: «POST isteklerine izin ver» ve «SMS durumu sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
sms_idintZorunluMesaj kimliği: anında /sms/send (tek alıcı), /otp/send veya /otp/detailed yanıtındaki sms_id.
Zamanlanmış gönderimlerin ve grup gönderimlerinin kimlikleri rapor kimliğidir; bunlar için Raporlar uç noktalarını kullanın. Çok alıcılı anında gönderimde sms_id yalnızca son alıcıya aittir. Teslim durumunu sürekli sorgulamak yerine Webhook kullanmanızı öneririz.

İstek örneği

curl -X POST https://api.turkeysms.com.tr/sms/status \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "sms_id": 48213377
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'sms_id'  => 48213377,
];

$ch = curl_init('https://api.turkeysms.com.tr/sms/status');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['result'] ?? false) === true) {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "sms_id":  48213377,
}

r = requests.post("https://api.turkeysms.com.tr/sms/status", json=payload, timeout=30)
data = r.json()
if data.get("result") is True:
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  sms_id:  48213377,
};

const r = await fetch('https://api.turkeysms.com.tr/sms/status', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.result === true) {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();

Başarılı yanıt

JSON — 200 OK
{
  "result": true,
  "result_code": "TS-1064",
  "result_message": "Number received the message.",
  "sender_id": "BASLIGINIZ",
  "date_of_sending": "2026-10-01",
  "time_of_sending": "14:27:12",
  "sms_status": "Number received the message",
  "sms_balance": "1 SMS",
  "details": "OK",
  "operator": "Turkcell"
}
AlanAçıklama
result_codeTS-1064: mesaj teslim edildi. TS-1022: teslim onayı yok (mesaj teslim edilemedi veya teslim raporu henüz gelmedi). İkisi de result: true ve HTTP 200 ile döner.
sms_statusNumber received the message veya The number did not receive the message.
sender_idMesajın gönderildiği SMS başlığı.
date_of_sending, time_of_sendingMesajın kaydedildiği tarih ve saat.
sms_balanceBu mesajın SMS sayısı (hesap bakiyesi değildir).
detailsİşlem sonucu; iletim hatasında hata açıklaması.
operatorAlıcının operatörü; bilgi yoksa boş olabilir.

Hata yanıtı

JSON — 403
{
  "result": false,
  "result_code": "TS-1020",
  "result_message": "The data sent is incorrect."
}
KodHTTPAnlamı
TS-1033400Gövde geçersiz.
TS-1050403api_key eksik.
TS-1052403sms_id eksik, sayı değil veya sıfırdan büyük değil.
TS-1031403Anahtar bulunamadı veya aktif değil.
TS-1061403«POST isteklerine izin ver» izni kapalı.
TS-1063403«SMS durumu sorgu» izni kapalı.
TS-1030403Hesap aktif değil.
TS-1020403Bu kimlikle size ait bir mesaj bulunamadı.
SRV-ERR500Beklenmeyen sunucu hatası.

Raporlar

Grup ve zamanlanmış gönderimlerin raporlarını döndürür. İki uç nokta vardır: Özet rapor gönderimin sayaçlarını, Detaylı rapor numara bazında teslim durumlarını verir.

POST https://api.turkeysms.com.tr/reports/basic
POST https://api.turkeysms.com.tr/reports/detailed

Gerekli izinler: «POST isteklerine izin ver» ve «SMS durumu sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)

raporid değeri /group/send ve /group/sendMixed yanıtındaki rapor_id ya da zamanlanmış /sms/send yanıtındaki sms_id'dir. Bu uç noktalar result yerine status alanını kullanır; başarılı yanıtta result_message yoktur.

Parametreler

ParametreTürDurumAçıklama
api_keystringZorunluAPI anahtarınız.
raporidintZorunluRapor kimliği.
pageintİsteğe bağlıYalnızca Detaylı rapor: sayfa numarası, 1 veya daha büyük. Varsayılan 1. Her sayfada en fazla 500 kayıt döner.

Özet rapor

curl -X POST https://api.turkeysms.com.tr/reports/basic \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "raporid": 482913377
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'raporid' => 482913377,
];

$ch = curl_init('https://api.turkeysms.com.tr/reports/basic');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['status'] ?? '') === 'success') {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "raporid": 482913377,
}

r = requests.post("https://api.turkeysms.com.tr/reports/basic", json=payload, timeout=30)
data = r.json()
if data.get("status") == "success":
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  raporid: 482913377,
};

const r = await fetch('https://api.turkeysms.com.tr/reports/basic', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.status === 'success') {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "status": "success",
  "result_code": "TS-1064",
  "rapor_id": 482913377,
  "total_numbers": 100,
  "success_count": 90,
  "failed_count": 5,
  "pending_count": 5,
  "details": {
    "sending_date": "2026-10-01",
    "sending_time": "14:22:10",
    "report_status": "Currently in the process of being sent.",
    "sms_sender_id": "BASLIGINIZ",
    "invalid_numbers": 2,
    "blocked_numbers": 1,
    "last_update": "2026-10-01 14:30:00"
  }
}
AlanAçıklama
total_numbersGönderimdeki numara sayısı.
success_countBaşarılı mesaj sayısı.
failed_countBaşarısız mesajlar; geçersiz ve engelli numaralar dahil.
pending_countSonucu henüz belli olmayan mesajlar.
details.sending_date, details.sending_timeRaporun oluşturulduğu tarih ve saat (zamanlanmış gönderimde gönderim zamanı değildir).
details.report_statusRaporun işlenme durumunu belirten metin.
details.sms_sender_idGönderimde kullanılan SMS başlığı.
details.invalid_numbers, details.blocked_numbersGeçersiz numara sayısı ve engelli numara sayısı.
details.last_updateSayaçların son güncellendiği zaman.

Sayaçlar, gönderim ve teslim raporu süreçleri ilerledikçe değişir.

Detaylı rapor

curl -X POST https://api.turkeysms.com.tr/reports/detailed \
  -H "Content-Type: application/json" \
  -d '{
  "api_key": "API_ANAHTARINIZ",
  "raporid": 482913377,
  "page": 1
}'
$payload = [
    'api_key' => 'API_ANAHTARINIZ',
    'raporid' => 482913377,
    'page'    => 1,
];

$ch = curl_init('https://api.turkeysms.com.tr/reports/detailed');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT        => 30,
]);
$body = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$res = $body !== false ? json_decode($body, true) : null;
if (($res['status'] ?? '') === 'success') {
    // İşlem başarılı
} else {
    error_log('TurkeySMS: ' . $http . ' ' . ($res['result_code'] ?? 'yanıt yok'));
}
import requests

payload = {
    "api_key": "API_ANAHTARINIZ",
    "raporid": 482913377,
    "page":    1,
}

r = requests.post("https://api.turkeysms.com.tr/reports/detailed", json=payload, timeout=30)
data = r.json()
if data.get("status") == "success":
    print("Başarılı", data)
else:
    print("Hata", r.status_code, data.get("result_code"))
// Node.js 18+ (yerleşik fetch)
(async () => {
const payload = {
  api_key: 'API_ANAHTARINIZ',
  raporid: 482913377,
  page:    1,
};

const r = await fetch('https://api.turkeysms.com.tr/reports/detailed', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(payload),
});
const data = await r.json();
if (data.status === 'success') {
  console.log('Başarılı', data);
} else {
  console.error('Hata', r.status, data.result_code);
}
})();
JSON — 200 OK
{
  "status": "success",
  "result_code": "TS-1064",
  "data": [
    {
      "phone_number": "905XXXXXXXXX",
      "sent_at": "2026-10-01 14:22:10",
      "sms_status": "Number received the message",
      "details": {
        "done_at": "2026-10-01 14:22:15",
        "status_code": 1,
        "operator": "TURKCELL"
      }
    }
  ],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_records": 1203,
    "records_per_page": 500
  }
}
details.status_codesms_statusAnlamı
1Number received the messageTeslim edildi.
2Expiration timeGeçerlilik süresi doldu; teslim edilemedi.
0Number didn't receive the messageTeslim edilmedi veya teslim raporu henüz gelmedi.

details.operator değerleri: TURKCELL, VODAFONE, TURKTELEKOM, KKTCELL, TELSIM, UNKNOWN. Henüz kayıt yoksa (ör. zamanlanmış gönderim başlamadıysa) data boş dizi olur. Son sayfadan sonraki sayfalar için de boş dizi döner.

Hata yanıtı

JSON — 200 (rapor bulunamadı)
{
  "status": "error",
  "result_code": "TS-1029",
  "result_message": "The Report ID is invalid or missing."
}
KodHTTPAnlamı
TS-1064200Rapor döndü.
TS-1029400 200400: raporid eksik veya sayı değil. 200: rapor bulunamadı veya size ait değil.
TS-1033400 404400: gövde veya page geçersiz. 404: yol hatalı.
TS-1050400api_key eksik.
TS-1031400Anahtar 30 karakterden kısa, bulunamadı veya aktif değil.
TS-1061400«POST isteklerine izin ver» izni kapalı.
TS-1063400«SMS durumu sorgu» izni kapalı.
TS-1030400Hesap aktif değil.
SRV-ERR500Beklenmeyen sunucu hatası.
🔗

Webhook'lar

Webhook ile TurkeySMS, hesabınızda gerçekleşen olayları (mesajın operatöre iletilmesi, teslim raporu, gelen SMS vb.) sizin belirlediğiniz bir adrese HTTP POST isteğiyle bildirir. Böylece mesaj durumunu öğrenmek için API'yi sürekli sorgulamanız (polling) gerekmez.

Bu bölümdeki istek ve gövde örnekleri, canlı sistemin gönderdiği biçimle birebir aynıdır; içlerindeki değerler (numaralar, kimlikler, zamanlar) örnektir.

📢
Önceki sürümden geçiş: Bu sayfanın eski sürümünde anlatılan alanlar kullanılmamaktadır. Alıcınızı aşağıdaki eşleşmeye göre güncelleyin:
EskiYeni
X-TurkeySMS-Webhook-Id / event_idX-TurkeySMS-Delivery / id
X-TurkeySMS-Webhook-Version / versionKaldırıldı
X-TurkeySms-Signature (yalnızca gövde)X-TurkeySMS-Signature-V2 (zaman damgalı); eski başlık uyumluluk için gönderilmeye devam eder
timestamp (ISO metin)timestamp (Unix saniye, sayı) ve created_at (ISO 8601)
generated_atKaldırıldı
data.sms_iddata.message_id
data.mobiledata.to
data.delivered_atdata.done_at
data.failure_reasondata.reason
data.operatorKaldırıldı (operator_status operatörün durum metnidir)

Nasıl çalışır

  1. Hesabınızda bir olay gerçekleşir (ör. mesajınız operatöre iletilir veya teslim raporu gelir).
  2. TurkeySMS olayı, bu olayı seçmiş webhook'larınız için kuyruğa alır ve her olaya benzersiz bir id verir.
  3. İstek gövdesi JSON olarak hazırlanır, secret anahtarınızla HMAC ile imzalanır ve adresinize POST edilir.
  4. Sunucunuz 10 saniye içinde 2xx dönerse olay teslim edilmiş sayılır. Geçici hatalarda (bağlantı hatası, zaman aşımı, 408, 429, 5xx) olay, ayarladığınız sayıda yeniden denenir.

Olayların tipik bildirim süreleri:

OlayNe zaman gönderilirTipik gecikme
sms.sentMesaj operatöre iletildiğindeYaklaşık 1,5–2 dakika (sistem, mesaj kaydının tamamlanması için 90 saniye bekler)
sms.deliveredOperatörden başarılı teslim raporu geldiğindeRapor geldikten sonra 30–60 saniye içinde (rapor çok hızlı gelirse sms.sent ile birlikte, gönderimden 1,5–2 dakika sonra)
sms.failedMesaj operatöre iletilemediğinde veya alıcıya teslim edilemediğindeTeslim hatasında rapor geldikten sonra 30–60 saniye; operatöre iletilemeyen mesajda kayıttan yaklaşık 6–7 dakika sonra
sms.receivedGelen SMS numaranıza (0850) mesaj ulaştığındaGenellikle 30 saniye içinde
inbound.matchedBir otomasyon kuralındaki «Webhook Tetikle» eylemi çalıştığındaGenellikle 30 saniye içinde
key.testPaneldeki Test düğmesine bastığınızdaDüğmeye bastığınız anda (eşzamanlı)
ℹ️
Operatör 72 saat içinde teslim raporu döndürmezse o mesaj için sms.delivered veya sms.failed gönderilmez. Mesajın son durumunu her zaman SMS Durumu uç noktasından sorgulayabilirsiniz. otp.verified olayı panelde «Yakında» olarak görünür ve şu an gönderilmez.

Kurulum

Webhook'lar Hesabım → API Merkezi → Güvenlik & IP → Webhook sekmesinden yönetilir. «Yeni webhook ekle» formundaki alanlar:

AlanAçıklama
AnahtarWebhook'un bağlı olduğu API anahtarı. Her API anahtarının tek bir webhook'u olur; aynı anahtar için yeniden kaydetmek mevcut webhook'u değiştirir.
URLOlayların gönderileceği adres. Herkese açık bir https:// adresi kullanın (bkz. Güvenlik).
Imzalama anahtarı (Secret)İmza için kullanılan gizli değer. Kaydedildikten sonra panelde gösterilmez. Düzenlemede alanı boş bırakmak mevcut secret'ı korur; değiştirmek için yeni değer girin, kaldırmak için «Mevcut secret'ı kaldır» kutusunu işaretleyin. Secret yoksa istekler imzasız gönderilir (önermiyoruz).
Imzalama algoritmasısha256 (varsayılan) veya sha512.
Maksimum tekrar deneme0–10 arası. Varsayılan 3. İlk denemeden sonra en fazla kaç kez yeniden deneneceği.
Tekrar deneme aralığı (saniye)1–3600 arası. Varsayılan 30. Her denemede iki katına çıkar (bkz. Yeniden deneme).
Tetikleyici olaylarAlmak istediğiniz olaylar. Hiçbiri seçilmezse sms.received hariç tüm olaylar gönderilir. sms.received mesaj içeriği taşıdığı için yalnızca açıkça seçilirse gönderilir.
Webhook aktifKapalıyken olaylar kaydedilir ancak gönderilmez; bekleyen yeniden denemeler de iptal edilir. Tekrar açtığınızda kapalı dönemdeki olaylar gönderilmez. Yapılandırma korunur.
💡
Teslim raporları ve gelen SMS'leri farklı adreslere almak istiyorsanız iki ayrı API anahtarı kullanın: birinin webhook'unda sms.sent, sms.delivered, sms.failed; diğerinde yalnızca sms.received seçili olsun.

Hangi olay hangi webhook'a gider?

DurumOlayı alan webhook
API anahtarıyla gönderilen mesajYalnızca o anahtarın webhook'u. Gövdede key_id bu anahtarın numarasıdır.
Panelden veya otomasyonla gönderilen mesajHesabınızdaki, olayı seçmiş tüm etkin webhook'lar. Gövdede key_id = null.
sms.receivedHesabınızdaki, sms.received olayını açıkça seçmiş tüm etkin webhook'lar. Mesajın, hesabınıza tanımlı bir 0850 numarasına gelmesi gerekir.
inbound.matchedHesabınızdaki ilk etkin webhook (anahtar numarası en küçük olan). Olay seçiminden bağımsızdır.
key.testTest düğmesine bastığınız anahtarın webhook'u.

Hesabınızın ana API anahtarıyla gönderilen mesajlar panel gönderimi gibi değerlendirilir (tüm webhook'lar, key_id = null). Hesabınızdaki iki webhook aynı URL'yi kullanıyorsa her olay bu URL'ye yalnızca bir kez gönderilir.

İstek biçimi

Her istek POST yöntemiyle, UTF-8 JSON gövdeyle gönderilir. Başlıklar:

BaşlıkAçıklama
Content-TypeHer zaman application/json.
User-AgentSabit değer: TurkeySMS-Webhook/1.0.
X-TurkeySMS-EventOlay adı; gövdedeki event ile aynıdır.
X-TurkeySMS-DeliveryTeslim kimliği (32 karakter hex). Gövdedeki id ile aynıdır ve yeniden denemelerde değişmez.
X-TurkeySMS-AttemptDeneme numarası: ilk gönderimde 1, her yeniden denemede bir artar.
X-TurkeySMS-TimestampBu denemenin gönderildiği an (Unix saniye). Her denemede yenilenir.
X-TurkeySMS-SignatureEski imza: <algo>=hex(HMAC(secret, gövde)). Zaman damgasını kapsamaz; yalnızca geriye dönük uyumluluk için gönderilir.
X-TurkeySMS-Signature-V2Önerilen imza: t=<zaman>,v1=hex(HMAC(secret, "<zaman>.<gövde>")). Secret tanımlı değilse imza başlıkları gönderilmez.
HTTP — örnek istek başlıkları
POST /turkeysms/webhook HTTP/1.1
Host: ornek.com
Content-Type: application/json
User-Agent: TurkeySMS-Webhook/1.0
X-TurkeySMS-Event: sms.delivered
X-TurkeySMS-Delivery: 27f38025030d060f3e3b760b318b406e
X-TurkeySMS-Attempt: 1
X-TurkeySMS-Timestamp: 1790857803
X-TurkeySMS-Signature: sha256=776ebd61c3789873d7851a30e868ff8e73dbc586bccd67d49e50b3498e827e44
X-TurkeySMS-Signature-V2: t=1790857803,v1=660a71ff372d5921231c4871913b030476acfdad1dafee4eb6f3117126837b11

Gövde her olayda aynı zarfı kullanır:

AlanTürAçıklama
idstringOlayın benzersiz kimliği (32 karakter hex) = X-TurkeySMS-Delivery. Tekrarları bu değerle ayıklayın.
eventstringOlay adı (ör. sms.delivered).
created_atstringOlayın oluşturulduğu zaman, ISO 8601.
timestampintOlayın oluşturulduğu zaman, Unix saniye. Yeniden denemelerde değişmez; imza zaman penceresi için bunu değil, imzadaki t= değerini kullanın.
dataobjectOlaya özgü alanlar (aşağıda).

Olaylar ve alanlar

sms.sent, sms.delivered ve sms.failed olaylarında data şu ortak alanları içerir. Bu olaylarda mesaj metni gönderilmez.

AlanTürAçıklama
message_idintMesaj numarası. /sms/send yanıtındaki sms_id ile aynıdır; SMS Durumu sorgusunda kullanılabilir.
bulk_idstringGönderimin toplu işlem (kampanya) numarası.
tostringAlıcı numarası, uluslararası formatta (905xxxxxxxxx).
sender_idstringMesajın gönderildiği SMS başlığı.
partsintMesajın kaç SMS parçasından oluştuğu.
sourcestringMesajın kaynağı. Örnek: api (API ile), Web (panelden).
key_idint | nullMesajın gönderildiği API anahtarının numarası. Panelden veya otomasyonla gönderilen mesajlarda null.
sent_atstringGönderim zamanı, ISO 8601 (2026-10-01T15:28:31+03:00).

sms.sent — mesaj operatöre iletildi. Yalnızca ortak alanlar gönderilir.

JSON — sms.sent
{
    "id": "353272ae3ae66d3233cd5ebe30faadcf",
    "event": "sms.sent",
    "created_at": "2026-10-01T15:30:02+03:00",
    "timestamp": 1790857802,
    "data": {
        "message_id": 518431556,
        "bulk_id": "1259383818",
        "to": "905xxxxxxxxx",
        "sender_id": "BASLIGIM",
        "parts": 1,
        "source": "api",
        "key_id": 4804,
        "sent_at": "2026-10-01T15:28:31+03:00"
    }
}

sms.delivered — mesaj alıcıya teslim edildi. Ortak alanlara ek olarak:

AlanTürAçıklama
statusstringHer zaman delivered.
done_atstring | nullOperatörün teslim zamanı, ISO 8601. Operatör zaman bildirmediyse null.
operator_statusstringOperatörün döndürdüğü durum metni (ör. Message delivered to handset).
JSON — sms.delivered
{
    "id": "27f38025030d060f3e3b760b318b406e",
    "event": "sms.delivered",
    "created_at": "2026-10-01T15:30:03+03:00",
    "timestamp": 1790857803,
    "data": {
        "message_id": 518431556,
        "bulk_id": "1259383818",
        "to": "905xxxxxxxxx",
        "sender_id": "BASLIGIM",
        "parts": 1,
        "source": "api",
        "key_id": 4804,
        "sent_at": "2026-10-01T15:28:31+03:00",
        "done_at": "2026-10-01T15:28:33+03:00",
        "operator_status": "Message delivered to handset",
        "status": "delivered"
    }
}

sms.failed — mesaj iletilemedi veya teslim edilemedi. Ortak alanlara ek olarak:

AlanTürAçıklama
stagestringsubmit: mesaj, kaydından yaklaşık 6–7 dakika sonra hâlâ operatöre iletilmemiş (bu durumda bulk_id "0" olur ve reason boş olabilir). delivery: operatör teslim edilemedi raporu döndürdü.
statusstringsubmit aşamasında rejected; delivery aşamasında undelivered, expired veya canceled.
reasonstringHata nedeni (en fazla 200 karakter).
done_atstring | nullYalnızca delivery aşamasında: operatörün rapor zamanı.
operator_statusstringYalnızca delivery aşamasında: operatörün durum metni.
JSON — sms.failed (stage: delivery)
{
    "id": "9755ae0b22863732063111ea35e2e1f4",
    "event": "sms.failed",
    "created_at": "2026-10-01T15:35:44+03:00",
    "timestamp": 1790858144,
    "data": {
        "message_id": 518431601,
        "bulk_id": "1259383818",
        "to": "905xxxxxxxxx",
        "sender_id": "BASLIGIM",
        "parts": 1,
        "source": "api",
        "key_id": 4804,
        "sent_at": "2026-10-01T15:28:31+03:00",
        "done_at": "2026-10-01T15:35:40+03:00",
        "operator_status": "Unknown Subscriber",
        "stage": "delivery",
        "status": "undelivered",
        "reason": "Unknown Subscriber"
    }
}
JSON — sms.failed (stage: submit)
{
    "id": "b1c2d3e4f5a60718293a4b5c6d7e8f90",
    "event": "sms.failed",
    "created_at": "2026-10-01T15:40:31+03:00",
    "timestamp": 1790858431,
    "data": {
        "message_id": 518431620,
        "bulk_id": "0",
        "to": "905xxxxxxxxx",
        "sender_id": "BASLIGIM",
        "parts": 1,
        "source": "api",
        "key_id": 4804,
        "sent_at": "2026-10-01T15:28:31+03:00",
        "stage": "submit",
        "status": "rejected",
        "reason": ""
    }
}

sms.received — hesabınıza tanımlı 0850 numarasına SMS geldi. Mesaj metni içerdiği için yalnızca webhook ayarında açıkça seçilirse gönderilir.

AlanTürAçıklama
message_idintGelen mesajın numarası. Gelen mesajlar giden mesajlardan ayrı numaralandırılır.
fromstringGönderen numara.
tostringMesajın geldiği 0850 numaranız (908509xxxxxx).
textstringMesaj metni (UTF-8).
networkstringGönderenin operatörü (ör. TURKCELL-TR).
received_atstringMesajın alındığı zaman, ISO 8601.
JSON — sms.received
{
    "id": "9262804e8760b90e1c0714d0ca78ac02",
    "event": "sms.received",
    "created_at": "2026-10-01T15:49:02+03:00",
    "timestamp": 1790858942,
    "data": {
        "message_id": 436956,
        "from": "905xxxxxxxxx",
        "to": "908509444004",
        "text": "BANK",
        "network": "TURKCELL-TR",
        "received_at": "2026-10-01T15:48:48+03:00"
    }
}

inbound.matched — Gelen SMS → Otomasyon sayfasındaki bir kuralın «Webhook Tetikle» eylemi çalıştı. sms.received ile aynı alanlara ek olarak rule_id (int) ve rule_name (string) içerir.

⚠️
inbound.matched olayında received_at şu an YYYY-MM-DD HH:MM:SS biçiminde (İstanbul saati, saat dilimi bilgisi olmadan) gönderilmektedir. Alıcınızda hem bu biçimi hem de ISO 8601 biçimini kabul edin.
JSON — inbound.matched
{
    "id": "4be0f6d1c2a3958e7f60a1b2c3d4e5f6",
    "event": "inbound.matched",
    "created_at": "2026-10-01T15:52:31+03:00",
    "timestamp": 1790859151,
    "data": {
        "message_id": 436957,
        "from": "905xxxxxxxxx",
        "to": "908509444004",
        "text": "HOOK",
        "network": "TURKCELL-TR",
        "received_at": "2026-10-01 15:52:24",
        "rule_id": 12,
        "rule_name": "Webhook'a ilet"
    }
}

key.test — paneldeki Test düğmesiyle gönderilir; yeniden denenmez. message değeri markanıza göre değişir.

JSON — key.test
{
    "id": "5d0e3c9a7b1f42e68c0d9a1b2c3e4f50",
    "event": "key.test",
    "created_at": "2026-10-01T15:01:06+03:00",
    "timestamp": 1790856066,
    "data": {
        "key_id": 4804,
        "message": "TurkeySMS test fire",
        "test": true
    }
}
🧪
Paneldeki Webhook Simulator ile gönderilen olaylarda data içinde "simulated": true bulunur. Bu olaylardaki message_id ve telefon numaraları gerçek değildir ve key_id alanı bulunmaz; canlı verilerinizle karıştırmamak için bu alanı kontrol edin.

İmza doğrulama

Secret tanımlıysa her istek iki imza başlığıyla gelir. X-TurkeySMS-Signature-V2 başlığını doğrulayın; zaman damgasını da kapsadığı için ele geçirilen bir isteğin tekrar gönderilmesini (replay) engeller.

  1. İstek gövdesini ham hâliyle okuyun (JSON'u ayrıştırıp yeniden oluşturmayın; tek bir boşluk farkı imzayı geçersiz kılar).
  2. X-TurkeySMS-Signature-V2 değerini ayrıştırın: t=<unix>,v1=<hex>. Buradaki v1, imza şemasının sürüm etiketidir.
  3. Algoritmayı hex uzunluğundan belirleyin: 64 karakter = sha256, 128 karakter = sha512 (veya panelde seçtiğinizi kullanın).
  4. HMAC(algoritma, secret, t + "." + ham_gövde) değerini hex olarak hesaplayın.
  5. Sonucu sabit zamanlı karşılaştırma ile (hash_equals, crypto.timingSafeEqual, hmac.compare_digest) imzadaki değerle karşılaştırın.
  6. |şimdi − t| 300 saniyeden büyükse isteği reddedin. Sunucu saatinizin NTP ile senkron olduğundan emin olun.
  7. Doğrulama başarısızsa 401 dönün ve gövdeyi işlemeyin.
⏱️
Zaman penceresini gövdedeki timestamp alanıyla kontrol etmeyin. Bu alan olayın oluşturulma zamanıdır ve yeniden denemelerde değişmez; saatler sonra gelen geçerli bir yeniden denemeyi reddetmenize yol açar. Her deneme yeni bir t= ile yeniden imzalanır.

Eski imza (X-TurkeySMS-Signature): sha256=<hex> biçimindedir ve yalnızca gövdeyi imzalar. Zaman damgası içermediği için tek başına tekrar saldırılarına karşı koruma sağlamaz. Yeni entegrasyonlarda kullanmayın.

Secret değiştirme: Yeni secret panelde kaydedildiği anda sonraki tüm denemeler yeni secret ile imzalanır. Kesinti yaşamamak için önce alıcınızın hem eski hem yeni secret'ı kabul etmesini sağlayın, ardından paneldeki secret'ı değiştirin ve birkaç saat sonra eski secret'ı alıcınızdan kaldırın.

Yanıt, zaman aşımı ve yeniden deneme

Sunucunuzun yanıtıTurkeySMS'in davranışı
2xxOlay teslim edildi; yeniden gönderilmez.
408, 429, 5xxGeçici hata; yeniden denenir.
Bağlantı hatası, DNS hatası, TLS hatası, 10 saniyelik zaman aşımıGeçici hata; yeniden denenir.
3xx (yönlendirme)Yönlendirmeler izlenmez; kalıcı hata, yeniden denenmez. URL'nin son adresini kullanın.
Diğer 4xx (400, 401, 403, 404 …)Kalıcı hata; yeniden denenmez.

Bağlantı kurma süresi en fazla 5 saniye, toplam istek süresi en fazla 10 saniyedir. Bekleme süresi her denemede iki katına çıkar: aralık × 2(deneme − 1), en fazla 6 saat. Varsayılan ayarlarla (3 tekrar, 30 saniye):

DenemeNe zamanNot
1Olay oluştuğunda
21. denemeden yaklaşık 30 sn sonra
32. denemeden yaklaşık 60 sn sonra
43. denemeden yaklaşık 120 sn sonraSon deneme; başarısız olursa olay tükenmiş olarak işaretlenir.

Yeniden denemeler 30 saniyelik işleme döngüsüyle çalışır; gerçek süre tablodakinden en fazla yaklaşık 30 saniye uzun olabilir. Tüm denemeler (istek, yanıt kodu, yanıt gövdesinin ilk 8.000 karakteri, süre) Webhook Merkezi → Teslim Kayıtları sayfasında görünür. Bu nedenle yanıt gövdesinde gizli bilgi döndürmeyin; kısa bir değer (ok) yeterlidir.

⚡
Önce yanıt verin, sonra işleyin: olayı veritabanına veya bir kuyruğa yazıp hemen 200 dönün. Uzun işlemleri (e-posta, harici API çağrısı vb.) yanıttan sonra yapın. 10 saniyeyi aşan bir yanıt, sunucunuz olayı işlemiş olsa bile zaman aşımı sayılır ve olay yeniden gönderilir.

Tekrarlar ve sıralama

  • En az bir kez teslim: Aynı olay birden fazla kez gelebilir (ör. zaman aşımı sonrası yeniden deneme). Gövdedeki id değerini kaydedin ve daha önce işlediğiniz bir id gelirse işlemeden 200 dönün.
  • Sıralama garanti edilmez: Yeniden denemeler nedeniyle sms.delivered, sms.sent'ten önce gelebilir. Mesaj durumunu message_id bazında tutun; delivered ve failed nihai durumlardır, sonradan gelen sms.sent bunları değiştirmemelidir.
  • İşleme hatası: Olayı kaydedemediyseniz id kaydınızı geri alın ve 500 dönün; olay yeniden denenir.
  • Tanımadığınız olaylar: Gelecekte yeni olay türleri eklenebilir. İşlemediğiniz bir olay geldiğinde de 200 dönün; aksi hâlde gereksiz yeniden denemeler oluşur.

Güvenlik

  • HTTPS kullanın. TurkeySMS sertifikayı doğrular; geçersiz, süresi dolmuş veya kendinden imzalı sertifikalarda istek başarısız olur.
  • Herkese açık adres: localhost, özel ağ (10.x, 172.16–31.x, 192.168.x), CGNAT ve ayrılmış adresler kabul edilmez. Özel veya ayrılmış bir IP adresi ya da yerel ad (localhost, .local, .lan, .internal) içeren URL'ler kayıt sırasında reddedilir; özel bir adrese çözümlenen alan adları gönderim anında reddedilir ve bu hata yeniden denenmez. Alan adı her gönderimde çözümlenir ve doğrulanan IP adresine bağlanılır.
  • Yönlendirme yok: http → https veya sonda / eklenmesi gibi yönlendirmeler izlenmez; doğrudan son adresi girin.
  • İmzasız istekleri reddedin: Secret tanımladıysanız imza başlığı olmayan veya doğrulanamayan her isteği 401 ile reddedin.
  • IP'ye güvenmeyin: İsteklerin kaynak IP adresleri değişebilir. Doğrulama için IP listesi yerine imzayı kullanın.
  • Secret'ı koruyun: Kaynak kodunda değil, ortam değişkeninde veya gizli yapılandırma dosyasında saklayın; sızdığından şüphelenirseniz panelden değiştirin.
  • Hata ayrıntısı döndürmeyin: Hata durumunda yalnızca durum kodu dönün; yığın izi veya sistem bilgisi yanıt gövdesine yazılmamalıdır.
  • Kişisel veri: sms.received ve inbound.matched mesaj metni ve telefon numarası içerir; bu verileri KVKK kapsamında saklayın ve erişimi sınırlayın.

Test etme

AraçNeredeNe işe yarar
Test düğmesiGüvenlik & IP → Webhook → Tanımlı webhook'larkey.test olayı gönderir ve sonucu (HTTP kodu, süre) hemen gösterir. Yeniden denenmez.
Webhook SimulatorAynı sayfanın altındaki «Sandbox» kartıSeçtiğiniz olayı (sms.sent, sms.delivered, sms.failed, sms.received, key.test) gerçek imza ve gerçek yeniden deneme ile gönderir; gövdede "simulated": true bulunur. Webhook o olayı seçmemişse veya aktif değilse gönderim yapılmaz. «Dry-run» işaretliyken istek gönderilmez, yalnızca gövde ve imza gösterilir.
Teslim KayıtlarıAPI Merkezi → Webhook MerkeziHer denemenin istek ve yanıtını, deneme sayısını, süreyi ve hata nedenini gösterir; anahtar, olay ve duruma göre süzülebilir, CSV olarak indirilebilir.
Sağlık & UyarılarAPI Merkezi → Webhook MerkeziArdışık hata sayısı, son 24 saatlik başarı oranı, son başarı/hata zamanı, riskli webhook'lar ve yeniden deneme durumu.
🛠️
Yerel geliştirme ortamınız (localhost) doğrudan kullanılamaz. Herkese açık bir test sunucusu veya HTTPS tünel hizmeti üzerinden test edin.

Örnek alıcılar

Üç örnek de aynı işi yapar: V2 imzasını ve zaman penceresini doğrular, tekrarları id ile ayıklar ve hızlıca 200 döner. Örnekler geçerli istek, yeniden deneme, yanlış secret, eski zaman damgası, değiştirilmiş gövde ve sha512 senaryolarıyla test edilmiştir. Tekrar kontrolü için dosya yerine veritabanında benzersiz (UNIQUE) bir sütun da kullanabilirsiniz; kritik işlemlerde id'yi olayla aynı veritabanı işleminde (transaction) kaydedin.

<?php
// TurkeySMS webhook alıcısı (PHP 7.4+)
$secret  = getenv('TURKEYSMS_WEBHOOK_SECRET') ?: '';  // panelde tanımladığınız secret (ortam değişkeninden)
$seenDir = '/var/lib/myapp/webhook-seen';             // web kökü dışında, yazılabilir bir klasör
$body    = file_get_contents('php://input');          // imza HAM gövde üzerinden hesaplanır
if ($secret === '') {                                 // yapılandırma eksik: TurkeySMS yeniden denesin
    http_response_code(500);
    exit;
}

// 1) X-TurkeySMS-Signature-V2 doğrulaması: t=<unix>,v1=<hex HMAC("<t>.<gövde>")>
$sig = $_SERVER['HTTP_X_TURKEYSMS_SIGNATURE_V2'] ?? '';
if (!preg_match('/^t=(\d+),v1=([0-9a-f]{64}|[0-9a-f]{128})$/D', $sig, $m)) {
    http_response_code(401);
    exit;
}
$algo     = strlen($m[2]) === 64 ? 'sha256' : 'sha512';   // panelde seçtiğiniz algoritma
$expected = hash_hmac($algo, $m[1] . '.' . $body, $secret);
// Zaman penceresi imzadaki t= ile ölçülür (her deneme yeniden imzalanır), gövdedeki "timestamp" ile değil.
if (!hash_equals($expected, $m[2]) || abs(time() - (int)$m[1]) > 300) {
    http_response_code(401);
    exit;
}

// 2) Tekrarları ayıklayın: "id" = X-TurkeySMS-Delivery, tüm denemelerde aynıdır.
$evt = json_decode($body, true);
$id  = is_array($evt) && preg_match('/^[0-9a-f]{32}$/D', (string)($evt['id'] ?? '')) ? $evt['id'] : '';
if ($id === '') {
    http_response_code(400);
    exit;
}
if (!is_dir($seenDir)) @mkdir($seenDir, 0750, true);
$marker = @fopen($seenDir . '/' . $id, 'x');              // aynı id daha önce geldiyse başarısız olur
if ($marker === false) {
    http_response_code(is_file($seenDir . '/' . $id) ? 200 : 500);   // 500 → TurkeySMS yeniden dener
    exit;
}
fclose($marker);

// 3) Olayı hızlıca kaydedin veya kuyruğa alın (TurkeySMS en fazla 10 saniye bekler).
//    Kayıt başarısız olursa işaret dosyasını silip 500 dönün; olay yeniden denenir.
$d = $evt['data'];
switch ($evt['event']) {
    case 'sms.sent':        /* $d['message_id'], $d['to'], $d['sender_id'] */ break;
    case 'sms.delivered':   /* $d['message_id'], $d['done_at'] */ break;
    case 'sms.failed':      /* $d['message_id'], $d['stage'], $d['status'], $d['reason'] */ break;
    case 'sms.received':    /* $d['from'], $d['to'], $d['text'] */ break;
    case 'inbound.matched': /* $d['from'], $d['text'], $d['rule_id'] */ break;
    case 'key.test':        break;
}

http_response_code(200);
echo 'ok';
// TurkeySMS webhook alıcısı (Node.js 18+ · Express 4)
const express = require('express');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

const SECRET = process.env.TURKEYSMS_WEBHOOK_SECRET;   // panelde tanımladığınız secret
const SEEN_DIR = '/var/lib/myapp/webhook-seen';        // yazılabilir, kalıcı bir klasör
fs.mkdirSync(SEEN_DIR, { recursive: true });

const app = express();

// İmza HAM gövde üzerinden hesaplanır: bu rotada JSON ayrıştırıcı kullanmayın.
app.post('/turkeysms/webhook', express.raw({ type: '*/*', limit: '256kb' }), (req, res) => {
  if (!SECRET) return res.sendStatus(500);              // yapılandırma eksik: TurkeySMS yeniden denesin
  const body = req.body;                                // Buffer
  const m = /^t=(\d+),v1=([0-9a-f]{64}|[0-9a-f]{128})$/.exec(req.get('X-TurkeySMS-Signature-V2') || '');
  if (!m) return res.sendStatus(401);

  const algo = m[2].length === 64 ? 'sha256' : 'sha512';
  const expected = crypto.createHmac(algo, SECRET).update(m[1] + '.').update(body).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(m[1])) <= 300;
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2])) || !fresh) {
    return res.sendStatus(401);
  }

  let evt;
  try { evt = JSON.parse(body.toString('utf8')); } catch { return res.sendStatus(400); }
  if (!/^[0-9a-f]{32}$/.test(evt.id || '')) return res.sendStatus(400);

  // Tekrarları ayıklayın: "id" tüm denemelerde aynıdır.
  try {
    fs.writeFileSync(path.join(SEEN_DIR, evt.id), '', { flag: 'wx' });
  } catch (e) {
    return res.sendStatus(e.code === 'EEXIST' ? 200 : 500);
  }

  // Olayı hızlıca kaydedin veya kuyruğa alın (en fazla 10 saniye).
  const d = evt.data;
  switch (evt.event) {
    case 'sms.sent':        /* d.message_id, d.to */ break;
    case 'sms.delivered':   /* d.message_id, d.done_at */ break;
    case 'sms.failed':      /* d.stage, d.status, d.reason */ break;
    case 'sms.received':    /* d.from, d.to, d.text */ break;
    case 'inbound.matched': /* d.text, d.rule_id */ break;
    case 'key.test':        break;
  }
  res.status(200).send('ok');
});

app.listen(3000);
# TurkeySMS webhook alıcısı (Python 3.8+ · Flask 2+)
import hashlib, hmac, json, os, re, time
from flask import Flask, request

SECRET = os.environ["TURKEYSMS_WEBHOOK_SECRET"].encode()   # panelde tanımladığınız secret
SEEN_DIR = "/var/lib/myapp/webhook-seen"                     # yazılabilir, kalıcı bir klasör
os.makedirs(SEEN_DIR, exist_ok=True)
SIG_RE = re.compile(r"t=(\d+),v1=([0-9a-f]{64}|[0-9a-f]{128})")

app = Flask(__name__)

@app.post("/turkeysms/webhook")
def turkeysms_webhook():
    body = request.get_data()                               # HAM gövde (bytes)
    m = SIG_RE.fullmatch(request.headers.get("X-TurkeySMS-Signature-V2", ""))
    if not m:
        return "", 401
    ts, sig = m.group(1), m.group(2)
    algo = hashlib.sha256 if len(sig) == 64 else hashlib.sha512
    expected = hmac.new(SECRET, ts.encode() + b"." + body, algo).hexdigest()
    if not hmac.compare_digest(expected, sig) or abs(time.time() - int(ts)) > 300:
        return "", 401

    try:
        evt = json.loads(body)
    except ValueError:
        return "", 400
    eid = evt.get("id", "") if isinstance(evt, dict) else ""
    if not re.fullmatch(r"[0-9a-f]{32}", eid):
        return "", 400

    # Tekrarları ayıklayın: "id" tüm denemelerde aynıdır.
    try:
        os.close(os.open(os.path.join(SEEN_DIR, eid), os.O_CREAT | os.O_EXCL | os.O_WRONLY))
    except FileExistsError:
        return "duplicate", 200
    except OSError:
        return "", 500                                      # TurkeySMS yeniden dener

    # Olayı hızlıca kaydedin veya kuyruğa alın (en fazla 10 saniye).
    d = evt["data"]
    if evt["event"] == "sms.delivered":
        pass  # d["message_id"], d["done_at"]
    elif evt["event"] == "sms.failed":
        pass  # d["stage"], d["status"], d["reason"]
    elif evt["event"] == "sms.received":
        pass  # d["from"], d["to"], d["text"]
    return "ok", 200

Sorun giderme

BelirtiOlası nedenÇözüm
Teslim Kayıtları'nda 401Secret alıcıdakiyle aynı değil; gövde, imza doğrulanmadan önce değiştirildi (JSON ayrıştırılıp yeniden oluşturuldu); sunucu saati kaymış.Secret'ı iki tarafta yeniden girin; imzayı ham gövde üzerinden hesaplayın; NTP ile saati senkronlayın.
«Zaman Aşımı»Alıcı 10 saniyede yanıt vermiyor.Önce 200 dönün, işlemi sonra yapın. Olay yeniden gönderilir; id ile tekrarı ayıklayın.
3xx ve yeniden deneme yokURL yönlendiriyor (ör. http → https, sonda /).Webhook URL'sine yönlendirmesiz son adresi yazın.
Hiç olay gelmiyorWebhook aktif değil; olay seçili değil; mesaj başka bir API anahtarıyla gönderildi; URL özel ağda.Ayarları ve yönlendirme kurallarını kontrol edin; Test düğmesiyle bağlantıyı doğrulayın.
sms.received gelmiyorOlay açıkça seçilmemiş (boş seçim bu olayı kapsamaz) veya mesaj hesabınıza tanımlı olmayan bir numaraya geldi.Webhook'ta sms.received olayını işaretleyin; mesajı Gelen SMS → Numaralarım sayfasındaki bir numaraya gönderin.
inbound.matched beklenmeyen URL'ye geldiBu olay her zaman hesabınızdaki ilk etkin webhook'a gider.İlk webhook'unuzun bu olayı işleyebildiğinden emin olun (işlemiyorsa yine de 200 dönsün).
Aynı olay iki kez geldiEn az bir kez teslim; zaman aşımı sonrası yeniden deneme.Normaldir. id ile tekrarları ayıklayın.
sms.delivered gelmediOlay seçili değil veya operatör 72 saat içinde rapor döndürmedi.Webhook olaylarını kontrol edin; durumu SMS Durumu ile sorgulayın.
Olaylar gecikmeli geliyorUç noktanız bağlantı hatası, 429 veya 5xx döndürdüğünde o webhook'un bekleyen tüm olayları 60 saniye ertelenir; hata sürerse denemeler tükenir.Teslim Kayıtları ve Sağlık & Uyarılar sayfasında hatayı inceleyip uç noktanızı düzeltin.

Canlıya geçiş kontrol listesi

  • ☐ Webhook URL'si herkese açık, geçerli sertifikalı https:// adresi ve yönlendirme yapmıyor.
  • ☐ Secret tanımlı; alıcı X-TurkeySMS-Signature-V2 imzasını ham gövde üzerinden ve sabit zamanlı karşılaştırmayla doğruluyor.
  • ☐ Zaman penceresi imzadaki t= ile kontrol ediliyor (300 sn) ve sunucu saati NTP ile senkron.
  • ☐ Tekrarlar id ile ayıklanıyor; durum message_id bazında ve nihai durumlar korunarak tutuluyor.
  • ☐ Alıcı 10 saniyeden kısa sürede 2xx dönüyor; uzun işler kuyrukta.
  • ☐ Tanınmayan olaylara da 200 dönülüyor.
  • ☐ Doğru olaylar seçili; sms.received gerekiyorsa açıkça işaretli.
  • ☐ Test düğmesi ve Webhook Simulator ile tüm olay türleri denendi; Teslim Kayıtları'nda hata yok.

Sık sorulan sorular

Birden fazla URL'ye olay gönderebilir miyim?
Evet. Her API anahtarının bir webhook'u vardır; farklı URL'ler için farklı anahtarlar kullanın. Panelden gönderilen mesajların olayları tüm etkin webhook'lara gider.

Olaylar hangi saat diliminde?
Tarih alanları ISO 8601 biçiminde ve saat dilimi bilgisiyle (+03:00) gönderilir; inbound.matched içindeki received_at için yukarıdaki nota bakın. timestamp ve X-TurkeySMS-Timestamp Unix saniyedir.

Mesaj metni webhook'ta gelir mi?
Giden mesaj olaylarında (sms.sent, sms.delivered, sms.failed) gelmez. Gelen mesajlarda (sms.received, inbound.matched) gelir.

Webhook kapalıyken oluşan olayları sonradan alabilir miyim?
Hayır. Kapalı dönemdeki olaylar gönderilmez; bu dönemin mesaj durumlarını SMS Raporları ile sorgulayın.

Yeniden deneme sayısı tükenirse ne olur?
Olay tükenmiş olarak işaretlenir ve bir daha gönderilmez. Teslim Kayıtları'nda görebilirsiniz.

İzleme

API kullanımınızı panelden izleyebilirsiniz:

Panelİçerik
API Merkezi → İstatistiklerToplam çağrı, başarı oranı, uç nokta dağılımı ve en çok kullanılan anahtarlar.
API Merkezi → Bağlantı Günlükleriİstek kayıtları; durum, uç nokta, anahtar, IP ve yanıt koduna göre filtrelenebilir.
Webhook / Logs → Teslim KayıtlarıWebhook isteklerinin teslim kayıtları ve yanıtları.

Parametre doğrulamasında reddedilen bazı istekler (ör. eksik alan) bağlantı günlüklerinde görünmeyebilir. Hata ayıklarken kendi tarafınızda da istek ve yanıtları (API anahtarı hariç) kaydetmenizi öneririz.

Yanıt kodları

Kodlar uç noktaya göre farklı HTTP durumlarıyla dönebilir. Ayrıntılı açıklamalar ilgili uç nokta bölümündedir; bu tablo hızlı başvuru içindir.

Ortak

KodHTTPAnlamı
SRV-ERR500Beklenmeyen sunucu hatası. Bakiye ve Başlık sorgu bu kodu 403 ile de döndürebilir.
TS-1033400 404Gövde geçersiz; Gruplar, Numaralar ve Raporlar'da 404 ile hatalı yol.
TS-1030400 403Hesap aktif değil.
TS-1031400 401 403API anahtarı geçersiz, bulunamadı veya aktif değil.
TS-1035403Anahtar duraklatılmış, süresi dolmuş veya iptal edilmiş.
TS-1066403İsteğin IP adresi anahtarın izin listesinde değil.
TS-1068429Anahtarın saatlik istek limiti doldu.
TS-1069429Anahtarın günlük istek limiti doldu.
TS-1073429Anahtarın aylık istek limiti doldu.

Anahtar denetimi

KodHTTPAnlamı
TS-1000200Anahtar geçerli; izinler ve hesap özeti döndü.
TS-5000500Beklenmeyen sunucu hatası.

SMS gönderimi ve zamanlanmış gönderim

KodHTTPAnlamı
TS-1024200Gönderim işleme alındı.
TS-1050401api_key eksik veya kısa.
TS-1025400Alıcı eksik.
TS-1051400Başlık eksik.
TS-1029400Başlık 11 karakterden uzun.
TS-1026400Metin boş veya 2.000 karakterden uzun.
TS-1028400Başlık hesapta yok veya onaylı değil.
TS-1060400 429400: alıcı sayısı sınırı. 429: dakikalık gönderim sınırı.
TS-1061403«POST isteklerine izin ver» kapalı.
TS-1062403«SMS gönderimi» kapalı.
TS-1027403Bakiye yetersiz.
TS-1070 / TS-1071 / TS-1072400Zamanlama tarihi, saati veya geçmiş zaman.

Grup gönderimi

KodHTTPAnlamı
TS-1024200Gönderim sıraya alındı.
TS-1025400api_key eksik veya kısa.
TS-1029400Başlık eksik.
TS-1026400Numara listesi eksik veya metin 2.000 karakterden uzun.
TS-106040050.000 numara sınırı.
TS-1070 / TS-1071 / TS-1072400Zamanlama alanları geçersiz.
TS-1067403«Grup gönderimi» kapalı.
TS-1028403Başlık hesapta yok veya onaylı değil.
TS-1027403Bakiye yetersiz.

OTP gönderimi ve Gelişmiş OTP

KodHTTPAnlamı
TS-1024200OTP gönderildi.
TS-1050400 401api_key eksik.
TS-1025400Numara eksik.
TS-1034400 403Numara biçimi geçersiz.
TS-1051400Başlık eksik (Gelişmiş OTP).
TS-1026400Metin boş, TS-CODE yok veya çok uzun (Gelişmiş OTP).
TS-1029400 403Başlık 11 karakterden uzun veya hesapta yok (Gelişmiş OTP).
TS-1028403Başlık OTP için onaylı değil (Gelişmiş OTP).
TS-1036403«OTP gönderimi» kapalı.
TS-1037403«Gelişmiş OTP» kapalı.
TS-1061403«POST isteklerine izin ver» kapalı (Gelişmiş OTP).
TS-1027403Bakiye yetersiz.
TS-5000403Mesaj kaydedilemedi; yeniden deneyin.

Gruplar

KodHTTPAnlamı
TS-1080 / TS-1087 / TS-1088 / TS-1090200Oluşturuldu / güncellendi / silindi / listelendi.
TS-1050400api_key eksik.
TS-1081 / TS-1084 / TS-1085 / TS-1089400İlgili izin kapalı.
TS-1082200Grup adı zaten var (başarısız sonuç).
TS-1083400 200Grup adı geçersiz.
TS-1086400 200Grup bulunamadı veya group_id eksik.

Numaralar

KodHTTPAnlamı
TS-1100200Numara eklendi.
TS-1101200Numara geçersiz (başarısız sonuç).
TS-1050400api_key eksik.
TS-1025400gsm_number eksik.
TS-1065400«Numara ekle» kapalı.
TS-1086400 200Grup bulunamadı veya group_id geçersiz.

Numara engelleme

KodHTTPAnlamı
TS-1141200Numara listeye eklendi.
TS-1142 / TS-1143200Numara listede değil / listede.
TS-1050403api_key eksik.
TS-1025400number eksik.
TS-1144400Numara geçerli bir Türkiye cep numarası değil.
TS-1140400Numara zaten listede.
TS-1065403«Numara engelle» kapalı.
TS-404404Yol hatalı.

Bakiye sorgu ve Başlık sorgu

KodHTTPAnlamı
TS-1040200Sorgu başarılı.
TS-1050400api_key eksik.
TS-1025400api_key kısa (Bakiye sorgu).
TS-1065403«Bakiye sorgu» kapalı.
TS-1038403«Başlık sorgu» kapalı.

SMS durumu sorgu

KodHTTPAnlamı
TS-1064200Mesaj teslim edildi.
TS-1022200Teslim onayı yok (teslim edilemedi veya rapor henüz gelmedi).
TS-1050403api_key eksik.
TS-1052403sms_id eksik veya geçersiz.
TS-1061403«POST isteklerine izin ver» kapalı.
TS-1063403«SMS durumu sorgu» kapalı.
TS-1020403Mesaj bulunamadı.

Raporlar

KodHTTPAnlamı
TS-1064200Rapor döndü.
TS-1029400 200Rapor kimliği eksik veya rapor bulunamadı.
TS-1050400api_key eksik.
TS-1061400«POST isteklerine izin ver» kapalı.
TS-1063400«SMS durumu sorgu» kapalı.

SDK ve entegrasyonlar

Bu sayfadaki örnekler herhangi bir kütüphane gerektirmez; her dilde standart HTTP istemcisiyle çalışır. Kendi kodunuzda zaman aşımı tanımlayın ve sonucu result (veya status) ile result_code alanlarına göre değerlendirin.

Hazır entegrasyonlar

Etkileşimli dokümantasyon

API'yi tarayıcıdan denemek için etkileşimli dokümantasyonu (Swagger, OpenAPI 3.1) kullanabilirsiniz. Etkileşimli dokümantasyon İngilizcedir.

Etkileşimli dokümantasyondan gönderilen istekler canlı sisteme gider; gönderim uç noktalarında gerçek SMS gönderilir.

Etkileşimli dokümantasyonu aç

Destek