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üm | Uç 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 |
| Webhook | Olay bildirimleri sizin sunucunuza gönderilir |
TS-1030).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.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.
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.POST kabul eder.Content-Type: application/json, UTF-8) olarak gönderin. Form verisi de kabul edilir; örnekler JSON kullanır. Sorgu dizesi (query string) okunmaz./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.Her istekte API anahtarınızı gövdedeki api_key alanında gönderin. HTTP başlığıyla (ör. Authorization) gönderilen anahtar okunmaz.
Çoğu uç nokta aşağıdaki zarfı kullanır. Başarılı yanıtlarda uç noktaya özel alanlar aynı nesneye eklenir.
{ "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").
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.
/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.
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ı 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.
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 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 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ç noktalar | Kapalıysa |
|---|---|---|
| POST isteklerine izin ver | /sms/send, /sms/status, /otp/detailed, /reports/basic, /reports/detailed | TS-1061 |
| SMS gönderimi | /sms/send | TS-1062 |
| Grup gönderimi | /group/send, /group/sendMixed | TS-1067 |
| OTP gönderimi | /otp/send | TS-1036 |
| Gelişmiş OTP | /otp/detailed | TS-1037 |
| Grup oluştur | /groups/create | TS-1081 |
| Grup düzenle | /groups/edit | TS-1084 |
| Grup sil | /groups/delete | TS-1085 |
| Grup listele | /groups/list | TS-1089 |
| Numara ekle | /contacts/add | TS-1065 |
| Numara engelle | /blacklist/post/add, /blacklist/post/status | TS-1065 |
| Bakiye sorgu | /balance/ | TS-1065 |
| SMS durumu sorgu | /sms/status, /reports/basic, /reports/detailed | TS-1063 |
| Başlık sorgu | /senderid/check | TS-1038 |
/auth/post/check/ için izin gerekmez. Bir anahtarın izinlerini bu uç noktayla sorgulayabilirsiniz.
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.
| Kural | Ne zaman reddedilir | Kod (HTTP) |
|---|---|---|
| Saatlik limit | Anahtarla o saat içinde (ör. 14:00–14:59) yapılan istek sayısı limite ulaştığında. | TS-1068 (429) |
| Günlük limit | Anahtarla o gün yapılan istek sayısı limite ulaştığında. | TS-1069 (429) |
| Aylık limit | Anahtarla 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 tarihi | Tarih geçtikten sonra. Anahtar, tanımlanan günün sonuna kadar geçerlidir. | TS-1035 (403) |
TS-1060) ayrıdır.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.
Gerekli izin: Yok. Aktif bir API anahtarı yeterlidir.
/auth/post/check/. Eski /auth/check adresi kullanılmaz (404).| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. 20–128 karakter. |
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); } })();
{ "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" } }
| Alan | Açıklama |
|---|---|
key_details.status | Anahtarın durumu. Yalnızca aktif anahtarlar yanıt aldığı için başarılı yanıtta Active olur. |
key_details.permissions | 16 izin alanı (true/false). Karşılıkları aşağıdaki tabloda. |
account_summary.account_status | Hesabın durumu. Başarılı yanıtta Active olur. |
account_summary.balance.main | Hesabınızdaki SMS kredisi (tam sayı). |
account_summary.balance.international, account_summary.global_sending | Ek alanlar. |
audit_info.request_ip | İsteğin geldiği IP adresi. |
audit_info.checked_at | Denetimin yapıldığı tarih ve saat. |
İzin alanlarının panel karşılıkları:
| Alan | Panel izni |
|---|---|
post_request | POST isteklerine izin ver |
send_single_sms | SMS gönderimi |
send_group_sms | Grup gönderimi |
send_otp | OTP gönderimi |
send_otp_advanced | Gelişmiş OTP |
create_group | Grup oluştur |
manage_groups | Grup oluştur (eski ad; create_group ile aynı değeri taşır, geriye dönük uyumluluk için korunur) |
edit_group | Grup düzenle |
delete_group | Grup sil |
list_groups | Grup listele |
add_contact | Numara ekle |
delete_contact | Panelde karşılığı yoktur; bu sayfada belgelenen uç noktalarda kullanılmaz. |
block_number | Numara engelle |
check_balance | Bakiye sorgu |
check_sms_status | SMS durumu sorgu |
check_senderid | Başlık sorgu |
{ "result": false, "result_code": "TS-1031", "result_message": "Invalid API key" }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1031 | 401 | api_key eksik, metin değil veya 20–128 karakter dışında. |
| TS-1031 | 400 | Anahtar bulunamadı ya da «Aktif» durumda değil. |
| TS-1030 | 400 | Hesap aktif değil. |
| TS-5000 | 500 | Beklenmeyen sunucu hatası. |
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.
Gerekli izinler: «POST isteklerine izin ver» ve «SMS gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| sentto | string | Zorunlu | Alı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. |
| title | string | Zorunlu | Hesabınızda onaylı SMS başlığı. En fazla 11 karakter; Türkçe karakterler (ç, ğ, ı, ö, ş, ü) iki karakter sayılır. |
| text | string | Zorunlu | Mesaj metni. En fazla 2.000 karakter. Metindeki TS-L ifadesi satır sonuna çevrilir. |
| sms_lang | int | İ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_type | int | İ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_date | string | İsteğe bağlı | Doluysa gönderim zamanlanır. Bkz. Zamanlanmış gönderim. |
| scheduled_time | string | Koşullu | scheduled_date gönderildiğinde zorunludur. |
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.
TS-1027).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); } })();
{ "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" }
| Alan | Açıklama |
|---|---|
sms_id | Son alıcıya ait mesaj kimliği. Tek alıcılı gönderimlerde SMS durumu sorgu ile kullanılır. |
number_of_sms | Tüm alıcılar için toplam SMS sayısı. |
total_recipients | Tekrarlar çı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_type | Gönderdiğiniz değerlerin etiketi. |
country | İlk alıcının ülke etiketi (ör. Turkey-TR, yurt dışı için GlobalSMS-GL). |
{ "result": false, "result_code": "TS-1027", "result_message": "Insufficient SMS credits. Please top up your account." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçerli JSON veya form verisi değil. |
| TS-1050 | 401 | api_key eksik veya 30 karakterden kısa. |
| TS-1025 | 400 | sentto eksik, 7 karakterden kısa veya içinde numara yok. |
| TS-1051 | 400 | title eksik. |
| TS-1029 | 400 | title 11 karakterden uzun. |
| TS-1026 | 400 | text boş veya 2.000 karakterden uzun. |
| TS-1060 | 400 | Alıcı sayısı sınırı aşıldı: 500 (zamanlanmış gönderimde 50.000). |
| TS-1070 / TS-1071 / TS-1072 | 400 | Zamanlama alanları geçersiz (bkz. Zamanlanmış gönderim). |
| TS-1031 | 401 | Anahtar bulunamadı veya aktif değil. |
| TS-1061 | 403 | «POST isteklerine izin ver» izni kapalı. |
| TS-1062 | 403 | «SMS gönderimi» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| TS-1028 | 400 | Başlık hesabınızda bulunamadı veya onaylı değil. |
| TS-1027 | 403 | Bakiye yetersiz. |
| TS-1060 | 429 | Dakikalık gönderim sınırı aşıldı. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
sms.sent, sms.delivered ve sms.failed olayları gönderilir. Olayın hangi webhook'a gideceği için bkz. Webhook → Yönlendirme./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.
Gerekli izinler: «POST isteklerine izin ver» ve «SMS gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| scheduled_date | string | Zorunlu | Gönderim tarihi, YYYY-AA-GG (ör. 2026-10-15). |
| scheduled_time | string | Zorunlu | Gönderim saati, SS:DD veya SS:DD:ss (ör. 09:30). |
Diğer parametreler SMS gönderimi ile aynıdır.
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); } })();
{ "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.
{ "result": false, "result_code": "TS-1072", "result_message": "Scheduled time must not be in the past." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1070 | 400 | scheduled_date YYYY-AA-GG biçiminde değil veya scheduled_time eksik. |
| TS-1071 | 400 | scheduled_time SS:DD veya SS:DD:ss biçiminde değil. |
| TS-1072 | 400 | Belirtilen zaman geçmişte veya geçersiz (ör. 25:99). |
| TS-1060 | 400 | 50.000 numara sınırı aşıldı. |
Diğer kodlar SMS gönderimi ile aynıdır.
Ç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.Gerekli izin: «Grup gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| title | string | Zorunlu | Hesabınızda onaylı SMS başlığı. |
| sentto | array | Zorunlu | Numara dizisi (JSON dizisi; virgüllü metin kabul edilmez). En fazla 50.000 öğe. numbers adıyla da gönderilebilir. |
| text | string / array | Zorunlu | /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_lang | int | İ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_sms | int | İsteğe bağlı | 1 gönderilirse gönderim zamanlanır. |
| scheduled_date | string | Koşullu | scheduled_sms 1 ise zorunlu. YYYY-AA-GG. |
| scheduled_time | string | Koşullu | scheduled_sms 1 ise zorunlu. SS:DD veya SS:DD:ss. Tarih ve saat Türkiye saatine (Europe/Istanbul) göre değerlendirilir. |
/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.TS-1027).scheduled_sms: 1 ile birlikte gönderin.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); } })();
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); } })();
{ "result": true, "result_code": "TS-1024", "result_message": "Bulk SMS dispatched successfully.", "rapor_id": 482913377, "total_numbers": 2, "total_sms_cost": 2, "scheduled": false }
| Alan | Açıklama |
|---|---|
rapor_id | Gönderimin rapor kimliği. Raporlar uç noktalarında raporid olarak kullanılır. |
total_numbers | Dönüştürme ve tekrar ayıklamadan sonra sıraya alınan numara sayısı. |
total_sms_cost | Toplam SMS sayısı. |
scheduled | Gönderim zamanlandıysa true. |
{ "result": false, "result_code": "TS-1028", "result_message": "Sender ID was not found in your account or is not approved." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz, text boş, text türü yanlış veya /group/sendMixed'de metin ve numara sayısı eşit değil. |
| TS-1025 | 400 | api_key eksik veya 30 karakterden kısa. |
| TS-1029 | 400 | title eksik. |
| TS-1026 | 400 | sentto eksik veya dizi değil ya da bir metin 2.000 karakterden uzun. |
| TS-1060 | 400 | 50.000 numara sınırı aşıldı. |
| TS-1070 / TS-1071 / TS-1072 | 400 | Zamanlama alanları geçersiz: tarih biçimi, saat biçimi veya geçmiş zaman. |
| TS-1031 | 403 | Anahtar bulunamadı veya aktif değil. |
| TS-1067 | 403 | «Grup gönderimi» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| TS-1028 | 403 | Başlık hesabınızda bulunamadı veya onaylı değil. |
| TS-1027 | 403 | Bakiye yetersiz. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
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.
Gerekli izin: «OTP gönderimi» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| mobile | string | Zorunlu | Tek alıcı numarası. 905XXXXXXXXX biçiminde gönderin; 05…, 5… ve 00… biçimleri de dönüştürülür. |
| digits | int | İsteğe bağlı | Kod uzunluğu: 4, 5 veya 6. Varsayılan 4; başka değerlerde 4 kullanılır. |
| sms_lang | int | İ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. |
MARKA, hesabınıza tanımlı OTP marka adıdır. Örnekte kod 4821'dir.
4821 Aktivasyon kodunuz OTP MARKA
Your activation code is:4821 MARKA
4821 هو رمز التفعيل الخاص بك MARKA
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); } })();
{ "result": true, "result_code": "TS-1024", "result_message": "OTP dispatched successfully.", "sms_id": 48213390, "otp_code": 482193, "sandbox": false }
| Alan | Açıklama |
|---|---|
sms_id | Mesaj kimliği; SMS durumu sorgu ile kullanılabilir. |
otp_code | Gönderilen kod. Tam sayı olarak döner ve 0 ile başlamaz. |
sandbox | Canlı isteklerde false. |
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.{ "result": false, "result_code": "TS-1036", "result_message": "OTP sending privilege is disabled for this API key." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 401 | api_key eksik veya 30 karakterden kısa. |
| TS-1025 | 400 | mobile eksik veya 7 karakterden kısa. |
| TS-1034 | 403 | Numara biçimi geçersiz (temizlendikten sonra 11–15 hane olmalıdır). |
| TS-1031 | 403 | Anahtar bulunamadı veya aktif değil. |
| TS-1036 | 403 | «OTP gönderimi» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| TS-1027 | 403 | Bakiye yetersiz. |
| TS-5000 | 403 | Mesaj kaydedilemedi; isteği yeniden deneyin. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
Kendi başlığınız ve kendi metninizle OTP gönderir. Kodu TurkeySMS üretir ve metindeki TS-CODE ifadesinin yerine koyar.
Gerekli izinler: «POST isteklerine izin ver» ve «Gelişmiş OTP» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| mobile | string | Zorunlu | Tek alıcı numarası, 905XXXXXXXXX. |
| title | string | Zorunlu | Hesabı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. |
| text | string | Zorunlu | Mesaj metni; TS-CODE ifadesini içermelidir (büyük harfle). En fazla 2.000 karakter. TS-L satır sonuna çevrilir. |
| lang | int | İ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. |
| digits | int | İsteğe bağlı | Kod uzunluğu: 4, 5 veya 6. Varsayılan 4. |
test, api, apikey, api_key, test123, 123, 0000, 123456789, senderid, sender, title, text, content.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); } })();
{ "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 }
| Alan | Açıklama |
|---|---|
sms_id | Mesaj kimliği. |
otp_code | Gönderilen kod. Tam sayı olarak döner ve 0 ile başlamaz. |
number_of_sms | Mesajın SMS sayısı. |
sms_lang | lang değerinin etiketi. |
sandbox | Canlı isteklerde false. |
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.{ "result": false, "result_code": "TS-1028", "result_message": "Sender ID is not approved for OTP (approval, document and network approval are required)." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz, bir alan metin değil veya başlık kabul edilmeyenler listesinde. |
| TS-1050 | 400 | api_key eksik. |
| TS-1025 | 400 | mobile eksik. |
| TS-1051 | 400 | title eksik. |
| TS-1026 | 400 | text boş, TS-CODE içermiyor veya 2.000 karakterden uzun. |
| TS-1031 | 400 403 | 400: anahtar 30 karakterden kısa. 403: anahtar bulunamadı veya aktif değil. |
| TS-1034 | 400 | Numara biçimi geçersiz. |
| TS-1029 | 400 403 | 400: başlık 11 karakterden uzun. 403: başlık hesabınızda bulunamadı. |
| TS-1061 | 403 | «POST isteklerine izin ver» izni kapalı. |
| TS-1037 | 403 | «Gelişmiş OTP» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| TS-1028 | 403 | Başlık OTP için onaylı değil (onay, belge veya operatör onayı eksik). |
| TS-1027 | 403 | Bakiye yetersiz. |
| TS-5000 | 403 | Mesaj kaydedilemedi; isteği yeniden deneyin. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
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ğer | Kullanım |
|---|---|
0 | İngilizce; yalnızca Latin harfleri ve standart işaretler (Türkçe karakter yok). |
1 | Türkçe; ç, ğ, ı, İ, ö, ş, ü içeren metinler. |
2 | Arapça ve diğer Unicode metinler. Varsayılan değerdir. |
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 fazla | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
Türkiye numaraları, sms_lang 0 | 160 | 305 | 455 | 610 | 760 | 910 | 1070 |
Türkiye numaraları, sms_lang 1 | 155 | 245 | 445 | 595 | 740 | 890 | 1040 |
Türkiye numaraları, sms_lang 2 | 65 | 127 | 190 | 250 | 315 | 380 | 445 |
| Yurt dışı numaralar (tüm değerler) | 70 | 130 | 195 | 260 | 325 | 390 | 450 |
/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./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.
Rehberinizdeki grupları oluşturur, yeniden adlandırır, siler ve listeler. Her işlemin ayrı bir izni vardır.
TS-1082, TS-1086). Sonucu her zaman result ve result_code ile değerlendirin.Gerekli izin: «Grup oluştur» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| group_name | string | Zorunlu | Grup 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); } })();
{ "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.
Gerekli izin: «Grup düzenle» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| group_id | int | Zorunlu | Grup kimliği. |
| new_name | string | Zorunlu | Yeni 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); } })();
{ "result": true, "result_code": "TS-1087", "result_message": "Group name updated successfully.", "new_name": "VIP Müşteriler" }
Gerekli izin: «Grup sil» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| group_id | int | Zorunlu | Grup 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); } })();
{ "result": true, "result_code": "TS-1088", "result_message": "Group deleted successfully." }
Gerekli izin: «Grup listele» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| search | string | İ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); } })();
{ "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.
{ "result": false, "result_code": "TS-1082", "result_message": "Group name already exists." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1080 / TS-1087 / TS-1088 / TS-1090 | 200 | Oluşturuldu / güncellendi / silindi / listelendi. |
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 400 | api_key eksik. |
| TS-1031 | 400 | Anahtar 30 karakterden kısa, bulunamadı veya aktif değil. |
| TS-1081 / TS-1084 / TS-1085 / TS-1089 | 400 | İlgili izin kapalı: oluştur / düzenle / sil / listele. |
| TS-1030 | 400 | Hesap aktif değil. |
| TS-1082 | 200 | Bu adda aktif bir grup zaten var. |
| TS-1083 | 400 200 | Grup adı boş veya 2–50 karakter dışında. Düzenlemede geçersiz group_id için de 200 ile döner. |
| TS-1086 | 400 200 | 400: group_id eksik. 200: grup bulunamadı, size ait değil veya silinmiş. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
Bir gruba numara ekler. Numara, ad ve üç ek alanla birlikte rehberinize kaydedilir.
Gerekli izin: «Numara ekle» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| group_id | int | Zorunlu | Numaranın ekleneceği grubun kimliği (bkz. Gruplar). |
| gsm_number | string | Zorunlu | Türkiye cep telefonu numarası. 905XXXXXXXXX, 05XXXXXXXXX, 5XXXXXXXXX, +905… ve 00905… kabul edilir; 905XXXXXXXXX olarak kaydedilir. |
| name | string | İsteğe bağlı | Kişinin adı. |
| f_01, f_02, f_03 | string | İsteğe bağlı | Ek alanlar; kişiselleştirme için serbest metin. |
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); } })();
{ "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.
{ "result": false, "result_code": "TS-1101", "result_message": "Failed to add contact." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 400 | api_key eksik. |
| TS-1025 | 400 | gsm_number eksik. |
| TS-1086 | 400 200 | 400: 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-1031 | 400 | Anahtar bulunamadı veya aktif değil. |
| TS-1065 | 400 | «Numara ekle» izni kapalı. |
| TS-1030 | 400 | Hesap aktif değil. |
| TS-1101 | 200 | Numara geçerli bir Türkiye cep telefonu numarası değil. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
Numara engelleme listenize numara ekler ve bir numaranın listede olup olmadığını sorgular. Liste hesap bazındadı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.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).
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| number | string | Zorunlu | Türkiye cep numarası. 905XXXXXXXXX, +90 5XX…, 0090 5XX…, 05XX… ve 5XX… biçimleri kabul edilir ve 905XXXXXXXXX biçimine çevrilir. |
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").
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); } })();
{ "status": "success", "result_code": "TS-1141", "result_message": "Number added to blacklist successfully" }
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); } })();
{ "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" }
{ "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.
{ "status": "error", "result_code": "TS-1065", "result_message": "Number blocking privilege is disabled for this API key." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1141 | 200 | Numara listeye eklendi. |
| TS-1143 / TS-1142 | 200 | Numara listede / listede değil. |
| TS-1050 | 403 | api_key eksik veya gövde geçersiz. |
| TS-1031 | 401 | Anahtar 20 karakterden kısa, bulunamadı veya aktif değil ya da hesap aktif değil. |
| TS-1025 | 400 | number eksik. |
| TS-1144 | 400 | Numara geçerli bir Türkiye cep numarası değil. |
| TS-1065 | 403 | «Numara engelle» izni kapalı. |
| TS-1140 | 400 | Numara listenizde zaten var. |
| TS-1033 | 400 | Kayıt sırasında hata oluştu; yeniden deneyin. |
| TS-404 | 404 | Yol hatalı. |
Hesabınızdaki SMS kredisini döndürür.
Gerekli izin: «Bakiye sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)
/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.| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
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); } })();
{ "result": true, "result_code": "TS-1040", "result_message": "Balance retrieved successfully.", "balance_main": 1500 }
balance_main: SMS kredisi (tam sayı).
{ "result": false, "result_code": "TS-1065", "result_message": "Balance inquiry privilege is disabled for this key." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 400 | api_key eksik. |
| TS-1025 | 400 | api_key 30 karakterden kısa. |
| TS-1031 | 403 | Anahtar bulunamadı veya aktif değil. |
| TS-1065 | 403 | «Bakiye sorgu» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| SRV-ERR | 403 500 | Beklenmeyen sunucu hatası. |
Hesabınızda onaylı SMS başlıklarını listeler. Gönderimlerde title alanına bu listedeki bir başlığı yazın.
Gerekli izin: «Başlık sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
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); } })();
{ "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 } ] }
| Alan | Açıklama |
|---|---|
sender_ids_count | Listedeki başlık sayısı. |
sender_ids[].id | Başlık kimliği. |
sender_ids[].title | SMS başlığı; gönderimde title olarak kullanılır. |
sender_ids[].status | Onaylı başlıklar listelendiği için her zaman 1. |
sender_ids[].network_stat | Değ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.
{ "result": false, "result_code": "TS-1038", "result_message": "Sender ID inquiry privilege is disabled for this key." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 400 | api_key eksik. |
| TS-1031 | 400 403 | 400: anahtar 30 karakterden kısa. 403: anahtar bulunamadı veya aktif değil. |
| TS-1038 | 403 | «Başlık sorgu» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| SRV-ERR | 403 500 | Beklenmeyen sunucu hatası. |
Tek bir mesajın teslim durumunu döndürür. Yalnızca kendi hesabınızdan gönderilen mesajlar sorgulanabilir.
Gerekli izinler: «POST isteklerine izin ver» ve «SMS durumu sorgu» (API Merkezi → Anahtarlarım → anahtar → İzinler)
| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| sms_id | int | Zorunlu | Mesaj kimliği: anında /sms/send (tek alıcı), /otp/send veya /otp/detailed yanıtındaki sms_id. |
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); } })();
{ "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" }
| Alan | Açıklama |
|---|---|
result_code | TS-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_status | Number received the message veya The number did not receive the message. |
sender_id | Mesajın gönderildiği SMS başlığı. |
date_of_sending, time_of_sending | Mesajın kaydedildiği tarih ve saat. |
sms_balance | Bu mesajın SMS sayısı (hesap bakiyesi değildir). |
details | İşlem sonucu; iletim hatasında hata açıklaması. |
operator | Alıcının operatörü; bilgi yoksa boş olabilir. |
{ "result": false, "result_code": "TS-1020", "result_message": "The data sent is incorrect." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1033 | 400 | Gövde geçersiz. |
| TS-1050 | 403 | api_key eksik. |
| TS-1052 | 403 | sms_id eksik, sayı değil veya sıfırdan büyük değil. |
| TS-1031 | 403 | Anahtar bulunamadı veya aktif değil. |
| TS-1061 | 403 | «POST isteklerine izin ver» izni kapalı. |
| TS-1063 | 403 | «SMS durumu sorgu» izni kapalı. |
| TS-1030 | 403 | Hesap aktif değil. |
| TS-1020 | 403 | Bu kimlikle size ait bir mesaj bulunamadı. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
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.
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.| Parametre | Tür | Durum | Açıklama |
|---|---|---|---|
| api_key | string | Zorunlu | API anahtarınız. |
| raporid | int | Zorunlu | Rapor kimliği. |
| page | int | İ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. |
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); } })();
{ "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" } }
| Alan | Açıklama |
|---|---|
total_numbers | Gönderimdeki numara sayısı. |
success_count | Başarılı mesaj sayısı. |
failed_count | Başarısız mesajlar; geçersiz ve engelli numaralar dahil. |
pending_count | Sonucu henüz belli olmayan mesajlar. |
details.sending_date, details.sending_time | Raporun oluşturulduğu tarih ve saat (zamanlanmış gönderimde gönderim zamanı değildir). |
details.report_status | Raporun işlenme durumunu belirten metin. |
details.sms_sender_id | Gönderimde kullanılan SMS başlığı. |
details.invalid_numbers, details.blocked_numbers | Geçersiz numara sayısı ve engelli numara sayısı. |
details.last_update | Sayaçların son güncellendiği zaman. |
Sayaçlar, gönderim ve teslim raporu süreçleri ilerledikçe değişir.
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); } })();
{ "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_code | sms_status | Anlamı |
|---|---|---|
1 | Number received the message | Teslim edildi. |
2 | Expiration time | Geçerlilik süresi doldu; teslim edilemedi. |
0 | Number didn't receive the message | Teslim 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.
{ "status": "error", "result_code": "TS-1029", "result_message": "The Report ID is invalid or missing." }
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1064 | 200 | Rapor döndü. |
| TS-1029 | 400 200 | 400: raporid eksik veya sayı değil. 200: rapor bulunamadı veya size ait değil. |
| TS-1033 | 400 404 | 400: gövde veya page geçersiz. 404: yol hatalı. |
| TS-1050 | 400 | api_key eksik. |
| TS-1031 | 400 | Anahtar 30 karakterden kısa, bulunamadı veya aktif değil. |
| TS-1061 | 400 | «POST isteklerine izin ver» izni kapalı. |
| TS-1063 | 400 | «SMS durumu sorgu» izni kapalı. |
| TS-1030 | 400 | Hesap aktif değil. |
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. |
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.
| Eski | Yeni |
|---|---|
| X-TurkeySMS-Webhook-Id / event_id | X-TurkeySMS-Delivery / id |
| X-TurkeySMS-Webhook-Version / version | Kaldı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_at | Kaldırıldı |
| data.sms_id | data.message_id |
| data.mobile | data.to |
| data.delivered_at | data.done_at |
| data.failure_reason | data.reason |
| data.operator | Kaldırıldı (operator_status operatörün durum metnidir) |
id verir.POST edilir.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:
| Olay | Ne zaman gönderilir | Tipik gecikme |
|---|---|---|
| sms.sent | Mesaj operatöre iletildiğinde | Yaklaşık 1,5–2 dakika (sistem, mesaj kaydının tamamlanması için 90 saniye bekler) |
| sms.delivered | Operatörden başarılı teslim raporu geldiğinde | Rapor geldikten sonra 30–60 saniye içinde (rapor çok hızlı gelirse sms.sent ile birlikte, gönderimden 1,5–2 dakika sonra) |
| sms.failed | Mesaj operatöre iletilemediğinde veya alıcıya teslim edilemediğinde | Teslim hatasında rapor geldikten sonra 30–60 saniye; operatöre iletilemeyen mesajda kayıttan yaklaşık 6–7 dakika sonra |
| sms.received | Gelen SMS numaranıza (0850) mesaj ulaştığında | Genellikle 30 saniye içinde |
| inbound.matched | Bir otomasyon kuralındaki «Webhook Tetikle» eylemi çalıştığında | Genellikle 30 saniye içinde |
| key.test | Paneldeki Test düğmesine bastığınızda | Düğmeye bastığınız anda (eşzamanlı) |
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.Webhook'lar Hesabım → API Merkezi → Güvenlik & IP → Webhook sekmesinden yönetilir. «Yeni webhook ekle» formundaki alanlar:
| Alan | Açıklama |
|---|---|
| Anahtar | Webhook'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. |
| URL | Olayları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 deneme | 0–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 olaylar | Almak 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 aktif | Kapalı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. |
sms.sent, sms.delivered, sms.failed; diğerinde yalnızca sms.received seçili olsun.| Durum | Olayı alan webhook |
|---|---|
| API anahtarıyla gönderilen mesaj | Yalnızca o anahtarın webhook'u. Gövdede key_id bu anahtarın numarasıdır. |
| Panelden veya otomasyonla gönderilen mesaj | Hesabınızdaki, olayı seçmiş tüm etkin webhook'lar. Gövdede key_id = null. |
sms.received | Hesabı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.matched | Hesabınızdaki ilk etkin webhook (anahtar numarası en küçük olan). Olay seçiminden bağımsızdır. |
key.test | Test 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.
Her istek POST yöntemiyle, UTF-8 JSON gövdeyle gönderilir. Başlıklar:
| Başlık | Açıklama |
|---|---|
| Content-Type | Her zaman application/json. |
| User-Agent | Sabit değer: TurkeySMS-Webhook/1.0. |
| X-TurkeySMS-Event | Olay adı; gövdedeki event ile aynıdır. |
| X-TurkeySMS-Delivery | Teslim kimliği (32 karakter hex). Gövdedeki id ile aynıdır ve yeniden denemelerde değişmez. |
| X-TurkeySMS-Attempt | Deneme numarası: ilk gönderimde 1, her yeniden denemede bir artar. |
| X-TurkeySMS-Timestamp | Bu denemenin gönderildiği an (Unix saniye). Her denemede yenilenir. |
| X-TurkeySMS-Signature | Eski 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. |
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:
| Alan | Tür | Açıklama |
|---|---|---|
| id | string | Olayın benzersiz kimliği (32 karakter hex) = X-TurkeySMS-Delivery. Tekrarları bu değerle ayıklayın. |
| event | string | Olay adı (ör. sms.delivered). |
| created_at | string | Olayın oluşturulduğu zaman, ISO 8601. |
| timestamp | int | Olayı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. |
| data | object | Olaya özgü alanlar (aşağıda). |
sms.sent, sms.delivered ve sms.failed olaylarında data şu ortak alanları içerir. Bu olaylarda mesaj metni gönderilmez.
| Alan | Tür | Açıklama |
|---|---|---|
| message_id | int | Mesaj numarası. /sms/send yanıtındaki sms_id ile aynıdır; SMS Durumu sorgusunda kullanılabilir. |
| bulk_id | string | Gönderimin toplu işlem (kampanya) numarası. |
| to | string | Alıcı numarası, uluslararası formatta (905xxxxxxxxx). |
| sender_id | string | Mesajın gönderildiği SMS başlığı. |
| parts | int | Mesajın kaç SMS parçasından oluştuğu. |
| source | string | Mesajın kaynağı. Örnek: api (API ile), Web (panelden). |
| key_id | int | null | Mesajın gönderildiği API anahtarının numarası. Panelden veya otomasyonla gönderilen mesajlarda null. |
| sent_at | string | Gönderim zamanı, ISO 8601 (2026-10-01T15:28:31+03:00). |
sms.sent — mesaj operatöre iletildi. Yalnızca ortak alanlar gönderilir.
{ "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:
| Alan | Tür | Açıklama |
|---|---|---|
| status | string | Her zaman delivered. |
| done_at | string | null | Operatörün teslim zamanı, ISO 8601. Operatör zaman bildirmediyse null. |
| operator_status | string | Operatörün döndürdüğü durum metni (ör. Message delivered to handset). |
{ "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:
| Alan | Tür | Açıklama |
|---|---|---|
| stage | string | submit: 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ü. |
| status | string | submit aşamasında rejected; delivery aşamasında undelivered, expired veya canceled. |
| reason | string | Hata nedeni (en fazla 200 karakter). |
| done_at | string | null | Yalnızca delivery aşamasında: operatörün rapor zamanı. |
| operator_status | string | Yalnızca delivery aşamasında: operatörün durum metni. |
{ "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" } }
{ "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.
| Alan | Tür | Açıklama |
|---|---|---|
| message_id | int | Gelen mesajın numarası. Gelen mesajlar giden mesajlardan ayrı numaralandırılır. |
| from | string | Gönderen numara. |
| to | string | Mesajın geldiği 0850 numaranız (908509xxxxxx). |
| text | string | Mesaj metni (UTF-8). |
| network | string | Gönderenin operatörü (ör. TURKCELL-TR). |
| received_at | string | Mesajın alındığı zaman, ISO 8601. |
{ "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.{ "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.
{ "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 } }
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.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.
X-TurkeySMS-Signature-V2 değerini ayrıştırın: t=<unix>,v1=<hex>. Buradaki v1, imza şemasının sürüm etiketidir.sha256, 128 karakter = sha512 (veya panelde seçtiğinizi kullanın).HMAC(algoritma, secret, t + "." + ham_gövde) değerini hex olarak hesaplayın.hash_equals, crypto.timingSafeEqual, hmac.compare_digest) imzadaki değerle karşılaştırın.|şimdi − t| 300 saniyeden büyükse isteği reddedin. Sunucu saatinizin NTP ile senkron olduğundan emin olun.401 dönün ve gövdeyi işlemeyin.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.
| Sunucunuzun yanıtı | TurkeySMS'in davranışı |
|---|---|
| 2xx | Olay teslim edildi; yeniden gönderilmez. |
| 408, 429, 5xx | Geç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):
| Deneme | Ne zaman | Not |
|---|---|---|
| 1 | Olay oluştuğunda | |
| 2 | 1. denemeden yaklaşık 30 sn sonra | |
| 3 | 2. denemeden yaklaşık 60 sn sonra | |
| 4 | 3. denemeden yaklaşık 120 sn sonra | Son 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.
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.id değerini kaydedin ve daha önce işlediğiniz bir id gelirse işlemeden 200 dönün.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.id kaydınızı geri alın ve 500 dönün; olay yeniden denenir.200 dönün; aksi hâlde gereksiz yeniden denemeler oluşur.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.http → https veya sonda / eklenmesi gibi yönlendirmeler izlenmez; doğrudan son adresi girin.401 ile reddedin.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.| Araç | Nerede | Ne işe yarar |
|---|---|---|
| Test düğmesi | Güvenlik & IP → Webhook → Tanımlı webhook'lar | key.test olayı gönderir ve sonucu (HTTP kodu, süre) hemen gösterir. Yeniden denenmez. |
| Webhook Simulator | Aynı 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 Merkezi | Her 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ılar | API Merkezi → Webhook Merkezi | Ardışık hata sayısı, son 24 saatlik başarı oranı, son başarı/hata zamanı, riskli webhook'lar ve yeniden deneme durumu. |
localhost) doğrudan kullanılamaz. Herkese açık bir test sunucusu veya HTTPS tünel hizmeti üzerinden test edin.Üç ö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| Belirti | Olası neden | Çözüm |
|---|---|---|
| Teslim Kayıtları'nda 401 | Secret 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 yok | URL yönlendiriyor (ör. http → https, sonda /). | Webhook URL'sine yönlendirmesiz son adresi yazın. |
| Hiç olay gelmiyor | Webhook 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 gelmiyor | Olay 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 geldi | Bu 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 geldi | En az bir kez teslim; zaman aşımı sonrası yeniden deneme. | Normaldir. id ile tekrarları ayıklayın. |
sms.delivered gelmedi | Olay 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 geliyor | Uç 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. |
https:// adresi ve yönlendirme yapmıyor.X-TurkeySMS-Signature-V2 imzasını ham gövde üzerinden ve sabit zamanlı karşılaştırmayla doğruluyor.t= ile kontrol ediliyor (300 sn) ve sunucu saati NTP ile senkron.id ile ayıklanıyor; durum message_id bazında ve nihai durumlar korunarak tutuluyor.2xx dönüyor; uzun işler kuyrukta.200 dönülüyor.sms.received gerekiyorsa açıkça işaretli.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.
API kullanımınızı panelden izleyebilirsiniz:
| Panel | İçerik |
|---|---|
| API Merkezi → İstatistikler | Toplam ç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.
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.
| Kod | HTTP | Anlamı |
|---|---|---|
| SRV-ERR | 500 | Beklenmeyen sunucu hatası. Bakiye ve Başlık sorgu bu kodu 403 ile de döndürebilir. |
| TS-1033 | 400 404 | Gövde geçersiz; Gruplar, Numaralar ve Raporlar'da 404 ile hatalı yol. |
| TS-1030 | 400 403 | Hesap aktif değil. |
| TS-1031 | 400 401 403 | API anahtarı geçersiz, bulunamadı veya aktif değil. |
| TS-1035 | 403 | Anahtar duraklatılmış, süresi dolmuş veya iptal edilmiş. |
| TS-1066 | 403 | İsteğin IP adresi anahtarın izin listesinde değil. |
| TS-1068 | 429 | Anahtarın saatlik istek limiti doldu. |
| TS-1069 | 429 | Anahtarın günlük istek limiti doldu. |
| TS-1073 | 429 | Anahtarın aylık istek limiti doldu. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1000 | 200 | Anahtar geçerli; izinler ve hesap özeti döndü. |
| TS-5000 | 500 | Beklenmeyen sunucu hatası. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1024 | 200 | Gönderim işleme alındı. |
| TS-1050 | 401 | api_key eksik veya kısa. |
| TS-1025 | 400 | Alıcı eksik. |
| TS-1051 | 400 | Başlık eksik. |
| TS-1029 | 400 | Başlık 11 karakterden uzun. |
| TS-1026 | 400 | Metin boş veya 2.000 karakterden uzun. |
| TS-1028 | 400 | Başlık hesapta yok veya onaylı değil. |
| TS-1060 | 400 429 | 400: alıcı sayısı sınırı. 429: dakikalık gönderim sınırı. |
| TS-1061 | 403 | «POST isteklerine izin ver» kapalı. |
| TS-1062 | 403 | «SMS gönderimi» kapalı. |
| TS-1027 | 403 | Bakiye yetersiz. |
| TS-1070 / TS-1071 / TS-1072 | 400 | Zamanlama tarihi, saati veya geçmiş zaman. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1024 | 200 | Gönderim sıraya alındı. |
| TS-1025 | 400 | api_key eksik veya kısa. |
| TS-1029 | 400 | Başlık eksik. |
| TS-1026 | 400 | Numara listesi eksik veya metin 2.000 karakterden uzun. |
| TS-1060 | 400 | 50.000 numara sınırı. |
| TS-1070 / TS-1071 / TS-1072 | 400 | Zamanlama alanları geçersiz. |
| TS-1067 | 403 | «Grup gönderimi» kapalı. |
| TS-1028 | 403 | Başlık hesapta yok veya onaylı değil. |
| TS-1027 | 403 | Bakiye yetersiz. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1024 | 200 | OTP gönderildi. |
| TS-1050 | 400 401 | api_key eksik. |
| TS-1025 | 400 | Numara eksik. |
| TS-1034 | 400 403 | Numara biçimi geçersiz. |
| TS-1051 | 400 | Başlık eksik (Gelişmiş OTP). |
| TS-1026 | 400 | Metin boş, TS-CODE yok veya çok uzun (Gelişmiş OTP). |
| TS-1029 | 400 403 | Başlık 11 karakterden uzun veya hesapta yok (Gelişmiş OTP). |
| TS-1028 | 403 | Başlık OTP için onaylı değil (Gelişmiş OTP). |
| TS-1036 | 403 | «OTP gönderimi» kapalı. |
| TS-1037 | 403 | «Gelişmiş OTP» kapalı. |
| TS-1061 | 403 | «POST isteklerine izin ver» kapalı (Gelişmiş OTP). |
| TS-1027 | 403 | Bakiye yetersiz. |
| TS-5000 | 403 | Mesaj kaydedilemedi; yeniden deneyin. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1080 / TS-1087 / TS-1088 / TS-1090 | 200 | Oluşturuldu / güncellendi / silindi / listelendi. |
| TS-1050 | 400 | api_key eksik. |
| TS-1081 / TS-1084 / TS-1085 / TS-1089 | 400 | İlgili izin kapalı. |
| TS-1082 | 200 | Grup adı zaten var (başarısız sonuç). |
| TS-1083 | 400 200 | Grup adı geçersiz. |
| TS-1086 | 400 200 | Grup bulunamadı veya group_id eksik. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1100 | 200 | Numara eklendi. |
| TS-1101 | 200 | Numara geçersiz (başarısız sonuç). |
| TS-1050 | 400 | api_key eksik. |
| TS-1025 | 400 | gsm_number eksik. |
| TS-1065 | 400 | «Numara ekle» kapalı. |
| TS-1086 | 400 200 | Grup bulunamadı veya group_id geçersiz. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1141 | 200 | Numara listeye eklendi. |
| TS-1142 / TS-1143 | 200 | Numara listede değil / listede. |
| TS-1050 | 403 | api_key eksik. |
| TS-1025 | 400 | number eksik. |
| TS-1144 | 400 | Numara geçerli bir Türkiye cep numarası değil. |
| TS-1140 | 400 | Numara zaten listede. |
| TS-1065 | 403 | «Numara engelle» kapalı. |
| TS-404 | 404 | Yol hatalı. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1040 | 200 | Sorgu başarılı. |
| TS-1050 | 400 | api_key eksik. |
| TS-1025 | 400 | api_key kısa (Bakiye sorgu). |
| TS-1065 | 403 | «Bakiye sorgu» kapalı. |
| TS-1038 | 403 | «Başlık sorgu» kapalı. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1064 | 200 | Mesaj teslim edildi. |
| TS-1022 | 200 | Teslim onayı yok (teslim edilemedi veya rapor henüz gelmedi). |
| TS-1050 | 403 | api_key eksik. |
| TS-1052 | 403 | sms_id eksik veya geçersiz. |
| TS-1061 | 403 | «POST isteklerine izin ver» kapalı. |
| TS-1063 | 403 | «SMS durumu sorgu» kapalı. |
| TS-1020 | 403 | Mesaj bulunamadı. |
| Kod | HTTP | Anlamı |
|---|---|---|
| TS-1064 | 200 | Rapor döndü. |
| TS-1029 | 400 200 | Rapor kimliği eksik veya rapor bulunamadı. |
| TS-1050 | 400 | api_key eksik. |
| TS-1061 | 400 | «POST isteklerine izin ver» kapalı. |
| TS-1063 | 400 | «SMS durumu sorgu» kapalı. |
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.
API'yi tarayıcıdan denemek için etkileşimli dokümantasyonu (Swagger, OpenAPI 3.1) kullanabilirsiniz. Etkileşimli dokümantasyon İngilizcedir.
result_code, isteğin tarih ve saatini yazın; API anahtarınızı paylaşmayın.