ssmsyaz

smsyaz API v1

Taban adres: https://api.smsyaz.com. Tüm istek ve yanıtlar JSON (UTF-8). Tarih/saatler UTC (ISO 8601).

Kimlik doğrulama (HMAC imza)

API anahtarınızı panelde Geliştirici sayfasında (yalnızca bir kez) görürsünüz. Her istekte şu başlıklar zorunludur:

BaşlıkAçıklama
x-api-keyAPI anahtarınız (sy_live_...)
x-timestampUnix zamanı, milisaniye (saniye de kabul edilir). Sunucu saatinden en fazla ±5 dakika.
x-nonceHer istekte yeni, 16-64 karakter rastgele değer (ör. 32 hex). Aynı nonce 10 dakika içinde ikinci kez kabul edilmez.
x-signaturehex(HMAC_SHA256(apiKey, timestamp + "." + nonce + "." + METHOD + "." + path + "." + body)) - küçük harf hex. GET isteklerinde body boş dizedir; path sorgu dizesini de içerir.

C# örneği

var body = JsonSerializer.Serialize(new { message = "Merhaba", recipients = new[] { "05xxxxxxxxx" } });
var ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
var nonce = Convert.ToHexStringLower(RandomNumberGenerator.GetBytes(16));
var sig = Convert.ToHexStringLower(HMACSHA256.HashData(Encoding.UTF8.GetBytes(apiKey),
    Encoding.UTF8.GetBytes($"{ts}.{nonce}.POST./v1/sms/send.{body}")));
var req = new HttpRequestMessage(HttpMethod.Post, "https://api.smsyaz.com/v1/sms/send") { Content = new StringContent(body, Encoding.UTF8, "application/json") };
req.Headers.Add("x-api-key", apiKey); req.Headers.Add("x-timestamp", ts);
req.Headers.Add("x-nonce", nonce); req.Headers.Add("x-signature", sig);

Node.js örneği

const crypto = require("crypto");
const body = JSON.stringify({ message: "Merhaba", recipients: ["05xxxxxxxxx"] });
const ts = Date.now().toString(), nonce = crypto.randomBytes(16).toString("hex");
const signature = crypto.createHmac("sha256", apiKey).update(`${ts}.${nonce}.POST./v1/sms/send.${body}`).digest("hex");
await fetch("https://api.smsyaz.com/v1/sms/send", { method: "POST", body,
  headers: { "content-type": "application/json", "x-api-key": apiKey, "x-timestamp": ts, "x-nonce": nonce, "x-signature": signature } });

İmza, gönderdiğiniz gövdenin birebir aynısı üzerinden hesaplanmalıdır (JSON'u imzaladıktan sonra yeniden biçimlendirmeyin).

SMS gönder - POST /v1/sms/send

AlanAçıklama
messageMetin, en fazla 1600 karakter. (text da kabul edilir.)
recipientsNumara dizisi, tek istekte en fazla 100.000 (limit numara sayısıdır, mesajın kaç boy olduğu etkilemez; istek gövdesi en fazla 4 MB). Panelden tek gönderim en fazla 10.000. 05xx..., 5xx..., +905xx... biçimleri kabul edilir; tekrarlar ayıklanır. Tek numara için to.
typeinformational (varsayılan) ya da commercial (İYS marka kodu tanımlı olmalı).
senderNameİsteğe bağlı başlık; operatör hesaplarınızdan birinde tanımlı olmalı. Boşsa öncelik sırasındaki operatörün başlığı.
clientReferenceİsteğe bağlı, en fazla 100 karakter. Aynı referansla gelen ikinci istek yeni gönderim yapmaz; ilk sonucu duplicate: true ile döner (güvenle tekrar deneyebilirsiniz). Aynı referans farklı metin/alıcı ile gelirse 409 REFERENCE_CONFLICT.

Yanıt 202 (tümü kuyrukta) ya da 207 (bazı numaralar geçersiz). SMS'ler hemen kuyruğa alınır, operatöre gönderim arka planda yapılır:

{ "queued": true, "message": "2 SMS kuyruğa alındı.", "duplicate": false, "batchId": "0199...", "count": 2, "segments": 1, "encoding": "turkish",
  "cost": 2.00, "balance": 998.00,
  "messages": [ { "id": "0199...", "recipient": "+905xxxxxxxxx" } ],
  "sent": ["+905xxxxxxxxx"], "failedCount": 1, "failed": [ { "recipient": "123", "reason": "INVALID_NUMBER" } ] }

messages ve sent yalnızca 1.000 ve altı alıcıda döner; failed en fazla ilk 1.000 geçersiz numarayı içerir (toplamı failedCount). Büyük gönderimi batchId ile takip edin (aşağıda).

Ücret kabul anında bakiyeden düşülür; hiçbir operatörün kabul etmediği mesajın ücreti otomatik iade edilir.

Bakiye yetmezse hiçbir SMS kuyruğa alınmaz (kısmi gönderim yok), 402 döner; yanıtta bakiyenizin kaç alıcıya yettiği de bulunur:

{ "error": { "code": "INSUFFICIENT_BALANCE", "message": "Bakiye yetersiz: bu gönderim 1.200,00 TL, bakiyeniz 700,00 TL. Bakiyeniz en fazla 7.000 alıcıya yetiyor.",
  "required": 1200.00, "balance": 700.00, "maxRecipients": 7000 } }

Durum sorgula

GET /v1/sms/{messageId} - tek mesaj. GET /v1/sms/batches/{batchId} - gönderimin duruma göre sayıları (örn. { "status": { "queued": 40000, "submitted": 60000 } }; büyük gönderimde birkaç saniyede bir sorgulayabilirsiniz). Mesaj bazında bildirim için webhook kullanın.

DurumAnlamı
queued / sendingKuyrukta / operatöre gönderiliyor.
submittedOperatör kabul etti (ücret kesinleşti).
failedHiçbir operatör kabul etmedi; ücret iade edildi.
unknownOperatör zaman aşımına uğradı - gitmiş olabilir. Çift SMS olmaması için yedeğe geçilmez.

Bakiye - GET /v1/balance

{ "balance": 998.00, "currency": "TRY", "pricePerSegment": 1.00 }

OTP (doğrulama kodu)

POST /v1/otp/send - { "recipient": "05xx...", "length": 6, "ttlSeconds": 180, "text": "Kodunuz: {code}" } (length 4-8, ttl 60-900 sn, text isteğe bağlı ve {code} içermeli). Yanıt: { "otpId", "expiresAt", "messageId" }. Aynı numaraya 10 dakikada en fazla 3 kod.

POST /v1/otp/verify - { "otpId": "...", "code": "123456" } → { "valid": true }. Kod tek kullanımlıktır, en fazla 5 deneme.

Webhook

Panelde https adresinizi ekleyin; imza sırrı bir kez gösterilir. Olaylar: message.status, balance.low, apikey.rotated. Başlıklar: x-smsyaz-event, x-smsyaz-delivery, x-smsyaz-timestamp, x-smsyaz-signature = hex(HMAC_SHA256(sır, timestamp + "." + body)). 2xx dışındaki yanıtlarda 1 dk, 5 dk, 30 dk, 2 sa, 6 sa, 12 sa aralıklarla yeniden denenir.

{ "event": "message.status", "messageId": "0199...", "batchId": "0199...", "recipient": "+905xxxxxxxxx",
  "status": "submitted", "error": null, "occurredAt": "2026-09-25T10:00:00Z" }

Hatalar

{ "error": { "code": "INSUFFICIENT_BALANCE", "message": "Bakiye yetersiz (gerekli: 12.00 TL)." } }
HTTPKodlar
401UNAUTHORIZED, BAD_SIGNATURE, BAD_TIMESTAMP, REPLAYED, KEY_INACTIVE
402INSUFFICIENT_BALANCE
403CUSTOMER_PASSIVE
409REFERENCE_CONFLICT
422EMPTY_MESSAGE, MESSAGE_TOO_LONG, NO_RECIPIENTS, NO_VALID_RECIPIENTS, TOO_MANY_RECIPIENTS, NO_PROVIDER, UNKNOWN_HEADER, IYS_REQUIRED, VALIDATION
429RATE_LIMITED, OTP_RATE_LIMIT

Kurallar