# SMS

https://dev.wisecp.com/tr/mesaj-gonderme

Toplu mesaj gönderimini fiyatlandıran, yapan ve geçmişini veren beş uç.

## Genel Bakış

Müşteri kendi cüzdanından ödeyerek toplu mesaj gönderebilir. Akış üç adımdır: bir **başlık** seçin, fiyat alın, gönderin.

Fiyat hedef ülkeye ve mesajın **parça sayısına** göre değişir. Metin uzadıkça ya da alfabe dışına çıktıkça parça sayısı artar ve tutar onunla birlikte büyür.

Bazı ülkeler başlığın **önceden kayıtlı** olmasını ister. Kaydı olmayan bir ülkeye giden numaralar sessizce düşmez: elenenler listesinde gerekçesiyle görünür.

## Referans

### Başlıkları Listeleme

get/api/v1/client/sms/senders

`Sms/GetSmsSenders` anahtarın sahibi

Gönderimde kullanılabilecek başlıkları ve ülke kayıtlarını döndürür.

Dönen alanlar data[] — 4

idintBaşlığın numarası.

namestringAlıcının göreceği metin. Gönderim ucuna bu değer verilir.

is_defaultboolHesabın varsayılan başlığı mı.

countriesobject[]Ön kayıt gerektiren ülkelerdeki durum. Ülke kodu ve durum taşır; ön kayıt istemeyen ülkeler burada görünmez.

Hatalar 3

sms_disabled422Operatör uluslararası mesaj hizmetini kapatmış.

sms_api_disabled422Operatör mesaj arayüzünü kapatmış. Panel çalışmaya devam eder.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/client/sms/senders' \
  -H "Authorization: Bearer $CLIENT_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/client/sms/senders', {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
const preferred = data.find((s) => s.is_default) ?? data[0];
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/client/sms/senders');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Bos ulke listesi ENGEL DEGILDIR: cogu ulke on kayit istemez ve baslik oralarda dogrudan calisir.
$senders = Kernel::internal('client:Sms/GetSmsSenders', ['owner_id' => $uid])['data'];
$name = $senders[0]['name'] ?? null;
```

### Fiyat Alma

post/api/v1/client/sms/quote

`Sms/QuoteSms` gönderim yok

Gönderimin ne kadar tutacağını ve neyin eleneceğini söyler.

Gövde 3

senderstringreqGönderen başlığı. Hesabın etkin başlıklarından biri olmalıdır.

messagestringreqMesaj metni. Parça tavanını aşan metin kırpılır ve kırpıldığı bildirilir.

numbersarrayreqAlıcı numaralar. Uluslararası biçimde; tek bir metin olarak gönderilirse satır, virgül ve noktalı virgülden bölünür.

Dönen alanlar data — 6

messageobjectMetin çözümlemesi. Kodlama, uzunluk, parça sayısı, kırpılıp kırpılmadığı ve gerçekten gidecek metin.

recipientsintÜcretlendirilip gönderilecek numara sayısı.

total_partsintToplam parça. Faturalama birimi budur.

totalobjectGönderim ucunun keseceği tutar.

countriesobject[]Hedef ülke başına kırılım. Kod, ad, adet, parça, birim fiyat ve toplam.

skippedobjectElenenler. Sayı, çözülemeyen girdiler, fiyatlanmayan ülkeler ve başlığın kaydı olmayan ülkeler.

Hatalar 6

sms_disabled422Operatör uluslararası mesaj hizmetini kapatmış.

sms_api_disabled422Operatör mesaj arayüzünü kapatmış. Panel çalışmaya devam eder.

sender_invalid422Başlık eksik, size ait değil ya da etkin değil.

message_required422Mesaj boş.

numbers_required422Alıcı listesi boş.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/client/sms/quote' \
  -H "Authorization: Bearer $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"sender":"TESTBRAND","message":"Your code is 482913","numbers":["+15551112233"]}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/client/sms/quote', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${clientKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ sender, message, numbers }),
});

const { data } = await res.json();
if (data.skipped.total) reviewSkipped(data.skipped);
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/client/sms/quote');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $clientKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(compact('sender', 'message', 'numbers')),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Elenen hedefler HATA DEGIL: teklif her zaman basarili doner, kaybi skipped blogundan okuyun.
$q = Kernel::internal('client:Sms/QuoteSms',
    ['owner_id' => $uid, 'sender' => $sender, 'message' => $text, 'numbers' => $nums])['data'];

$willCost = $q['total']['amount'];
$willDrop = $q['skipped']['total'];
```

### Toplu Gönderim

post/api/v1/client/sms/send

`Sms/SendSms` cüzdandan keser

Mesajı gönderir ve tutarı cüzdandan keser.

Gövde 3

senderstringreqGönderen başlığı. Hesabın etkin başlıklarından biri olmalıdır.

messagestringreqMesaj metni. Parça tavanını aşan metin kırpılır ve kırpıldığı bildirilir.

numbersarrayreqAlıcı numaralar. Uluslararası biçimde; tek bir metin olarak gönderilirse satır, virgül ve noktalı virgülden bölünür.

Dönen alanlar 201 — data — 9

message_idintGönderimin numarası. Geçmiş ucunda bu numarayla aranır.

senderstringKullanılan başlık.

acceptedintÜcretlendirilip sağlayıcıya verilen alıcı sayısı.

partsintMesaj başına parça.

total_partsintToplam parça.

totalobjectCüzdandan kesilen tutar.

balanceobjectKesim sonrası cüzdan.

report_idstringSağlayıcının parti referansı.

skippedobjectElenenler. Sayı, çözülemeyen girdiler, fiyatlanmayan ülkeler ve başlığın kaydı olmayan ülkeler.

Hatalar 10

sms_disabled422Operatör uluslararası mesaj hizmetini kapatmış.

sms_api_disabled422Operatör mesaj arayüzünü kapatmış. Panel çalışmaya devam eder.

sender_invalid422Başlık eksik, size ait değil ya da etkin değil.

no_recipients422Bütün numaralar elendi. Gerekçe yanıtın ayrıntısında gelir.

price_unavailable422Tutar sıfıra fiyatlandı.

send_rejected422Bir kanca gönderimi reddetti.

sms_module_unavailable422Yapılandırılmış bir gönderim sağlayıcısı yok.

insufficient_balance422Cüzdan tutarı karşılamıyor. Hiçbir şey gönderilmez ve kesilmez.

send_failed500Sağlayıcı gönderimi reddetti. Kesilen tutar tamamen iade edilir.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl -X POST 'https://panel.ornek.com/api/v1/client/sms/send' \
  -H "Authorization: Bearer $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"sender":"TESTBRAND","message":"Your code is 482913","numbers":["+15551112233"]}'
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/client/sms/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${clientKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ sender, message, numbers }),
});

const { data } = await res.json();
console.log(data.accepted, data.total, data.balance);
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/client/sms/send');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $clientKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(compact('sender', 'message', 'numbers')),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Tutari SUNUCU yeniden hesaplar: teklifte gordugunuz rakam bir soz degil, gonderim kendi fiyatini bilir.
$r = Kernel::internal('client:Sms/SendSms',
    ['owner_id' => $uid, 'sender' => $sender, 'message' => $text, 'numbers' => $nums])['data'];

$charged = $r['total']['amount'];
```

### Gönderim Geçmişi

get/api/v1/client/sms/messages

`Sms/GetSmsMessages` anahtarın sahibi

Yapılmış gönderimleri en yeniden başlayarak döndürür.

Sorgu 2

pageintKaçıncı sayfa.

limitintSayfa başına satır. En çok 100.

Dönen alanlar data[] — 9 + meta — 4

message_idintGönderimin numarası.

senderstringKullanılan başlık.

textstringGönderilen metin.

recipientsintÜcretlendirilen alıcı sayısı.

partsintMesaj başına parça.

total_partsintToplam parça.

totalobjectKesilen tutar.

countriesobject[]Hedef ülke kırılımı.

created_atstringGönderim anı.

total_countintToplam gönderim. Meta altında toplam adıyla döner.

pageintBulunulan sayfa.

limitintSayfa boyutu.

next_pageintSonraki sayfa.

Hatalar 3

sms_disabled422Operatör uluslararası mesaj hizmetini kapatmış.

sms_api_disabled422Operatör mesaj arayüzünü kapatmış. Panel çalışmaya devam eder.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/client/sms/messages' \
  -H "Authorization: Bearer $CLIENT_KEY"
```

```javascript
const res = await fetch('https://panel.ornek.com/api/v1/client/sms/messages', {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data, meta } = await res.json();
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/client/sms/messages');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Gecmiste ALICI NUMARALARI yoktur: numaralar yalniz tek gonderim ucunda gelir.
$rows = Kernel::internal('client:Sms/GetSmsMessages', ['owner_id' => $uid])['data'];
$one  = Kernel::internal('client:Sms/GetSmsMessage',
    ['owner_id' => $uid, 'id' => $rows[0]['message_id']])['data'];
```

### Tek Gönderimi Okuma

get/api/v1/client/sms/messages/{id}

`Sms/GetSmsMessage` anahtarın sahibi

Bir gönderimi alıcı numaralarıyla birlikte döndürür.

Dönen alanlar data — 11

dataobjectGeçmiş satırının alanları.

numbersstring[]Ücretlendirilip gönderilen numaralar.

report_idstringSağlayıcının parti referansı.

Hatalar 4

not_found404Böyle bir gönderim yok ya da başka bir müşteriye ait.

sms_disabled422Operatör uluslararası mesaj hizmetini kapatmış.

sms_api_disabled422Operatör mesaj arayüzünü kapatmış. Panel çalışmaya devam eder.

insufficient_scope403Anahtar gerekli kapsamı taşımıyor.

İstek cURL JavaScript PHP (HTTP) PHP (Dahili)

```bash
curl 'https://panel.ornek.com/api/v1/client/sms/messages/4520' \
  -H "Authorization: Bearer $CLIENT_KEY"
```

```javascript
const res = await fetch(`https://panel.ornek.com/api/v1/client/sms/messages/${id}`, {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
console.log(data.numbers.length, data.report_id);
```

```php
$ch = curl_init('https://panel.ornek.com/api/v1/client/sms/messages/' . $id);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Alici bazli TESLIM RAPORU burada YOK: saglayici-canli rapor panel gorunumunde kalir.
$m = Kernel::internal('client:Sms/GetSmsMessage', ['owner_id' => $uid, 'id' => $id])['data'];
$sentTo = $m['numbers'];
```

## Tuzaklar

> **Elenen alıcılar hata döndürmez**
> 
> Fiyat ve gönderim uçları geçersiz numaraları, fiyatlanmamış ülkeleri ve başlığın kaydı olmayan ülkeleri **sessizce elemez**, ama gönderimi de durdurmaz: kalan küme gider ve elenenler yanıtta listelenir. Bu bloğu okumazsanız mesajın bir bölümünün hiç gitmediğini fark etmezsiniz.

> **Teklif bir söz değildir**
> 
> Gönderim ucu tutarı **kendisi yeniden hesaplar** ve istemcinin gönderdiği bir rakama asla güvenmez. Teklif ile gönderim arasında fiyat ya da başlık kaydı değişirse kesilen tutar farklı olabilir. Kesin rakamı gönderim yanıtından okuyun.

> **Kesim atomiktir, iade tam olur**
> 
> Cüzdan **tek bir koşullu güncellemeyle** kesilir: eşzamanlı iki gönderim bakiyeyi eksiye düşüremez. Sağlayıcı gönderimi reddederse kesilen tutar tamamen iade edilir ve hiçbir mesaj gitmez. Yani başarısız bir gönderim para kaybettirmez.

> **Alfabe dışına çıkmak parça sayısını artırır**
> 
> Mesaj temel alfabede yazılmışsa bir parçaya daha çok karakter sığar; alfabe dışı tek bir harf bile metni **diğer kodlamaya** düşürür ve parça başına kapasite yarıdan aza iner. Tutar parça üzerinden hesaplandığı için maliyet birden büyür. Teklif ucundaki kodlama alanını okuyun.

> **Geçmiş numaraları taşımaz**
> 
> Gönderim geçmişi özet satırlar verir; **alıcı numaraları** yalnız tek gönderimi okuduğunuzda gelir. Alıcı bazlı teslim raporu ise API'de hiç yoktur ve panelde kalır, çünkü sağlayıcıdan canlı çekilir.

## İlgili Makaleler

- [Hesap Bakiyesi](https://dev.wisecp.com/tr/hesap-bakiyesi-api)
- [Client API İlk Çağrılar](https://dev.wisecp.com/tr/client-api-ilk-cagrilar)
