# SMS uzunluğunu hesaplama

> Bir metnin kaç parça tuttuğu ve sınıra ne kadar uzak olduğu; send uç noktasının saydığı şekilde birebir sayılır.

- **İstek:** `POST https://ext-api.netgsm.com.tr/sms/v3/length`
- **Canlı ortam:** `https://ext-api.netgsm.com.tr/sms/v3`
- **Kimlik doğrulama:** `Authorization: Bearer <token>`
- **HTML sayfası:** https://api-docs.netgsm.com.tr/measure-length/
- **OpenAPI tanımı:** https://api-docs.netgsm.com.tr/openapi/sms-v3.yaml (operationId: `measureLength`)

## Açıklama

Bir metnin kaç parça tuttuğu ve sınıra ne kadar uzak olduğu; send uç noktasının saydığı
şekilde birebir sayılır. Yalnızca bir hesaplamadır: hiçbir şey gönderilmez ya da saklanmaz.
Fazla uzun bir metin `fits` false ve negatif `remaining` ile 200 döner.

## İstek

### Gövde (`application/json`, zorunlu)

- `text` (string, zorunlu, en fazla uzunluk 10000): Mesaj metni. Boş olabilir.
- `encoding` (string, isteğe bağlı): Değerler: `DEFAULT`, `TURKISH`, `UNICODE`. Varsayılan: `DEFAULT`.
- `alphanumericSender` (boolean, isteğe bağlı): NETGSM gibi bir metin başlığından gönderilip gönderilmeyeceği; bu beş karakter tutar. Gönderici bir metin başlığı olduğunda her zaman true olmalıdır; false bırakılırsa yanıt, send'in böyle bir başlıktan kabul ettiğinden beş karakter fazlasına izin verir. Varsayılan: `false`.

Örnek gövde:

```json
{
  "text": "Merhaba, şifreniz 123456",
  "encoding": "TURKISH",
  "alphanumericSender": true
}
```

## Örnek istek

```bash
curl -X POST 'https://ext-api.netgsm.com.tr/sms/v3/length' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "text": "Merhaba, şifreniz 123456",
  "encoding": "TURKISH",
  "alphanumericSender": true
}'
```

## Yanıtlar

### 200 — Ölçüm.

Gövde (`application/json`):

- `encoding` (string, zorunlu): Değerler: `DEFAULT`, `TURKISH`, `UNICODE`.
- `length` (integer, zorunlu): Send uç noktasının saydığı şekilde - TURKISH altında kaçışlı her Türkçe harf için iki, alfanümerik gönderici için artı beş.
- `parts` (integer, zorunlu): Metnin kapladığı SMS sayısı. Boş metin için sıfır.
- `limit` (integer, zorunlu): Gönderici maliyeti dahil `length` değerinin alabileceği en büyük değer. En uzun metin değildir - metin başlığı için beş eksiğidir. Ne kadar daha metin sığacağını `remaining` gösterir.
- `fits` (boolean, zorunlu): Send'in bu uzunlukta bir metni kabul edip etmeyeceği.
- `remaining` (integer, zorunlu): Sınıra kadar kalan karakter. Metin sınırı aşıyorsa aştığı kadar negatif.
- `remainingUntilNextPart` (integer, zorunlu): Bir SMS daha gerekmeden önce kalan karakter. Metin sığmıyorsa sıfır.

Örnek:

```json
{
  "encoding": "TURKISH",
  "length": 30,
  "parts": 1,
  "limit": 888,
  "fits": true,
  "remaining": 858,
  "remainingUntilNextPart": 125
}
```

### 400 — INVALID_REQUEST. `text` yok ya da 10000 karakterden uzun, `encoding` bilinmiyor veya gövde JSON değil.

Gövde (`application/json`):

- `code` (string, zorunlu): Değerler: `INVALID_REQUEST`.
- `message` (string, zorunlu): Okunabilir ayrıntı. `UNAUTHENTICATED` için `no bearer token` ya da `invalid or expired token`. `REJECTED_HEADER` için ret adıdır; yalnızca rakamlardan oluşan bir göndericide ` (subscriber number headers were not offered)` ekini taşıyabilir. `RATE_LIMITED` için sınırı belirtir; `FORBIDDEN` ve `REJECTED_IYS` için sabit bir cümledir. `SERVICE_UNAVAILABLE` ve `INTERNAL_ERROR` genel bir cümle taşır; bildirirken `requestId` değerini paylaşmanız gerekir.
- `requestId` (string, zorunlu): İsteğe özgü kimlik, 32 onaltılık karakter. Bir sorun bildirirken bu değeri paylaşmanız, isteğin kayıtlarda bulunmasını sağlar.
- `timestamp` (string, date-time, zorunlu)
- `violations` (array<object>, null olabilir, zorunlu): Yalnızca gövde doğrulamasından gelen INVALID_REQUEST için dolu, aksi halde `null`.
- `violations[].field` (string, isteğe bağlı)
- `violations[].message` (string, isteğe bağlı)
- `rejectedItems` (array<object>, isteğe bağlı, en fazla kayıt 100): Yalnızca `NO_DELIVERABLE_MESSAGES` yanıtında bulunur; diğer hatalarda alan hiç yer almaz. Reddedilen kayıtlar, `index` sırasıyla ilk 100 tanesi; 202 yanıtındaki `rejectedItems` ile aynıdır.
- `rejectedItems[].index` (integer, zorunlu): Kaydın istekteki `messages` dizisindeki sırası, sıfırdan başlar.
- `rejectedItems[].recipient` (string, null olabilir, zorunlu): Kayıttaki alıcı. Kayıt `null` ise ya da alıcısı yoksa `null`.
- `rejectedItems[].reason` (string, zorunlu): Değerler: `INVALID_RECIPIENT`, `INVALID_MESSAGE`, `MESSAGE_TOO_LONG`, `MALFORMED_ENTRY`, `DUPLICATE_RECIPIENT`, `NO_INTERNATIONAL_PERMISSION`.

  | Değer | Ne zaman |
  |---|---|
  | `INVALID_RECIPIENT` | Numara eksik ya da biçimi yanlış; bkz. `recipient`. |
  | `INVALID_MESSAGE` | Metin eksik ya da boş. |
  | `MESSAGE_TOO_LONG` | Metin, `encoding` ve gönderici türüne göre sınırı aşıyor; bkz. `encoding`. |
  | `MALFORMED_ENTRY` | Kayıt `null`. |
  | `DUPLICATE_RECIPIENT` | Aynı alıcı istekte daha sonra yeniden geçiyor. Yalnızca son geçen kayıt gönderilir, öncekiler bu nedenle reddedilir; son kayıt başka bir nedenle reddedilse bile. Numaralar yazıldığı gibi karşılaştırılır. Mükerrer gönderime izin verilen hesaplarda uygulanmaz. |
  | `NO_INTERNATIONAL_PERMISSION` | Numara yurt dışı (`-` ile başlıyor) ve hesabın yurt dışı gönderim izni yok. İzin için destek ekibiyle iletişime geçmelisiniz. Yalnızca başka bir hatası olmayan kayıtlarda bildirilir. |

  Bir kayıt birden fazla nedenle hatalıysa tek neden bildirilir; öncelik: `DUPLICATE_RECIPIENT`,
  `MALFORMED_ENTRY`, `MESSAGE_TOO_LONG`, `INVALID_RECIPIENT`, `INVALID_MESSAGE`,
  `NO_INTERNATIONAL_PERMISSION`.

- `rejectedItemsTruncated` (boolean, isteğe bağlı): Yalnızca `rejectedItems` ile birlikte bulunur. 100'den fazla kayıt reddedildiğinde true.

Örnek (şemadan üretildi):

```json
{
  "code": "INVALID_REQUEST",
  "message": "string",
  "requestId": "string",
  "timestamp": "2026-01-01T10:00:00+03:00",
  "violations": [
    {
      "field": "string",
      "message": "string"
    }
  ],
  "rejectedItems": [
    {
      "index": 0,
      "recipient": "string",
      "reason": "INVALID_RECIPIENT"
    }
  ],
  "rejectedItemsTruncated": true
}
```

### 401 — UNAUTHENTICATED. Bearer token yok ya da token geçersiz veya süresi dolmuş; `message` `no bearer token` ya da `invalid or expired token`.

Gövde (`application/json`): alanlar 400 yanıtıyla aynı; farklı olanlar:

- `code` (string, zorunlu): Değerler: `UNAUTHENTICATED`.

Örnek (şemadan üretildi):

```json
{
  "code": "UNAUTHENTICATED",
  "message": "string",
  "requestId": "string",
  "timestamp": "2026-01-01T10:00:00+03:00",
  "violations": [
    {
      "field": "string",
      "message": "string"
    }
  ],
  "rejectedItems": [
    {
      "index": 0,
      "recipient": "string",
      "reason": "INVALID_RECIPIENT"
    }
  ],
  "rejectedItemsTruncated": true
}
```

### 500 — INTERNAL_ERROR, `message` `internal error`. Beklenmeyen hata; bildirirken `requestId` değerini paylaşmanız gerekir.

Gövde (`application/json`): alanlar 400 yanıtıyla aynı; farklı olanlar:

- `code` (string, zorunlu): Değerler: `INTERNAL_ERROR`.

Örnek (şemadan üretildi):

```json
{
  "code": "INTERNAL_ERROR",
  "message": "string",
  "requestId": "string",
  "timestamp": "2026-01-01T10:00:00+03:00",
  "violations": [
    {
      "field": "string",
      "message": "string"
    }
  ],
  "rejectedItems": [
    {
      "index": 0,
      "recipient": "string",
      "reason": "INVALID_RECIPIENT"
    }
  ],
  "rejectedItemsTruncated": true
}
```

### 503 — SERVICE_UNAVAILABLE. Hiçbir şey yapılmadı; yeniden denemek güvenlidir.

Gövde (`application/json`): alanlar 400 yanıtıyla aynı; farklı olanlar:

- `code` (string, zorunlu): Değerler: `SERVICE_UNAVAILABLE`.

Örnek (şemadan üretildi):

```json
{
  "code": "SERVICE_UNAVAILABLE",
  "message": "string",
  "requestId": "string",
  "timestamp": "2026-01-01T10:00:00+03:00",
  "violations": [
    {
      "field": "string",
      "message": "string"
    }
  ],
  "rejectedItems": [
    {
      "index": 0,
      "recipient": "string",
      "reason": "INVALID_RECIPIENT"
    }
  ],
  "rejectedItemsTruncated": true
}
```
