sunucu.com.tr

API belgeleri

sunucu.com.tr API'si ile hizmetlerinizi listeleyebilir, sunucularınızın durumunu görebilir, başlatıp kapatabilir, faturalarınızı okuyabilir, Object Storage bucket ve erişim anahtarlarınızı yönetebilirsiniz; SMTP hizmetinizle doğrulanmış alan adlarınızdan e-posta gönderebilirsiniz. Anahtarı Panel > API sayfasından oluşturursunuz.

İçindekiler

Başlarken

Temel adres: https://sunucu.com.tr/api/v1. Her istekte anahtarı Authorization başlığında gönderin.

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services
{ "data": [ { "code": "482913-639201", "name": "Bulut Sunucu", "status": "active", ... } ],
  "meta": { "page": 1, "per_page": 50, "total": 1 } }

Anahtarlar ve yetkiler

YetkiAdKapsam
services:readHizmetleri okumaHizmet listesi ve ayrıntısı, sunucu durumu ve işlem günlüğü.
servers:powerSunucu güç işlemleriSunucuları başlatma, kapatma ve yeniden başlatma. Hizmetleri okumayı da içerir.
invoices:readFaturaları okumaFatura listesi, tutarlar ve fatura kalemleri.
emails:sendE-posta göndermeDoğrulanmış gönderim alan adlarınızdan e-posta gönderme. Kota ve hız sınırları SMTP ile ortaktır.
emails:readE-posta durumunu okumaGönderilen e-postaların durumu ve teslim olayları (alıcılar maskeli).
domains:readGönderim alan adlarını okumaGönderim alan adlarınız ve doğrulama durumları.
storage:readObject Storage okumaBucket listesi, erişim anahtarları (gizli anahtar hariç) ve kullanım.
storage:writeObject Storage yönetimiBucket ve erişim anahtarı oluşturma, silme, yenileme ve IP listesi. Okumayı da içerir.
  • Anahtar yalnız oluşturulduğu hesapta geçerlidir.
  • Anahtar yalnız oluşturulurken bir kez gösterilir; biz de göremeyiz.
  • IP kısıtı eklerseniz anahtar yalnız o adreslerden çalışır.
  • Süresi dolan ya da iptal edilen anahtar hemen reddedilir.
  • Anahtarı yalnız hesap sahibi oluşturur ve iptal eder.

Güvenlik önerileri

  • Anahtarı kod deposuna koymayın; ortam değişkeninde ya da gizli bilgi kasasında tutun.
  • Yalnız gereken yetkiyi verin; okuma yeten işe güç yetkisi vermeyin.
  • Sabit IP'li bir sunucudan kullanıyorsanız IP kısıtı ekleyin.
  • Sızdığını düşündüğünüz anahtarı hemen iptal edin ve yenisini oluşturun.
  • Anahtarı adres satırında (sorgu dizesinde) göndermeyin; böyle gelen istek reddedilir.

Yanıt biçimi

  • Gövde ve yanıt JSON, UTF-8.
  • Başarılı yanıt { "data": ... }, liste { "data": [...], "meta": { "page", "per_page", "total" } }.
  • Zaman damgaları ISO 8601 UTC (2026-10-10T09:30:00Z); yalnız tarih alanları (due_date, next_due_date, date) Türkiye günüyle YYYY-MM-DD.
  • Tutarlar iki ondalıklı metin ("504.00").
  • Yeni alanlar duyurusuz eklenebilir; yazılımınız bilinmeyen alanları yok saymalı.

Hatalar

{ "error": { "code": "not_found", "message": "Kayıt bulunamadı.", "request_id": "3f9a1c2b7d10" } }

Başka bir hesaba ait kayıt için de 404 döner. Destek talebinde request_id değerini paylaşın.

KodHTTPAçıklama
unauthorized401Geçerli bir API anahtarı gönderin.
key_expired401Bu API anahtarının süresi dolmuş.
key_revoked401Bu API anahtarı iptal edilmiş.
key_in_url400API anahtarı adres satırında gönderilemez; Authorization başlığını kullanın.
ip_not_allowed403Bu anahtar bu IP adresinden kullanılamaz.
account_locked403Hesap geçici olarak kullanıma kapatıldı. Destek ekibiyle iletişime geçin.
insufficient_scope403Bu işlem için anahtarda "yetki adı" yetkisi gerekiyor.
not_found404Kayıt bulunamadı.
method_not_allowed405Bu adres bu yöntemi desteklemiyor.
invalid_request400İstek geçersiz.
payload_too_large413İstek gövdesi çok büyük.
unsupported_media_type415Content-Type application/json olmalı.
invalid_action422Geçersiz işlem. Kullanılabilir: start, shutdown, reboot, stop, reset.
confirm_required422Zorla kapatma ve zorla yeniden başlatma için "confirm": true gönderin.
power_not_supported422Bu hizmette güç işlemi yapılamaz.
guest_tools_unavailable422Güvenli işlem için işletim sisteminin yanıt vermesi gerekiyor, şu an yanıt alınamıyor. stop ya da reset kullanabilirsiniz.
service_not_active409Bu hizmet şu an işleme açık değil.
monitoring_unavailable404Bu hizmet için izleme verisi yok.
service_provisioning409Sunucu hâlâ kuruluyor, lütfen bekleyin.
already_in_state409Sunucu zaten bu durumda.
operation_in_progress409Bu sunucuda süren bir işlem var. Bitmesini bekleyip tekrar deneyin.
idempotency_key_reused409Bu Idempotency-Key başka bir istekte kullanıldı.
rate_limited429Çok fazla istek. Retry-After başlığındaki süre kadar bekleyin.
too_many_failed_attempts429Bu adresten çok fazla başarısız deneme yapıldı. 10 dakika sonra tekrar deneyin.
api_disabled503API şu an geçici olarak kapalı.
infrastructure_error503İşlem şu an tamamlanamadı. Birkaç dakika sonra tekrar deneyin; sorun sürerse destek talebi açın.
internal_error500Beklenmeyen bir hata oluştu. Sorun sürerse request_id ile destek talebi açın.
name_taken409Bu bucket adı kullanımda. Başka bir ad seçin.
limit_reached409Bu hizmette izin verilen en yüksek sayıya ulaşıldı.
storage_unavailable404Bu hizmette Object Storage hesabı yok.

Oran sınırları

Anahtar başına dakikada 120 istek. Güç işlemleri anahtar başına dakikada 10, aynı sunucuda dakikada 6. Canlı durum anahtar başına dakikada 30, ölçümler dakikada 20 (aynı sunucuda 10). Bir hesabın tüm anahtarları toplamda dakikada 600 istek. E-posta gönderimi ayrı sayılır: anahtar başına saniyede 5 istek.

Her yanıtta RateLimit-Limit, RateLimit-Remaining ve RateLimit-Reset başlıkları bulunur; 429 yanıtında Retry-After başlığı kaç saniye beklemeniz gerektiğini söyler. Aynı adresten 10 dakikada 30 başarısız kimlik denemesinden sonra o adres 10 dakika engellenir.

Sürümleme

Sürüm adreste yer alır (/v1). Yeni alan eklemek gibi geriye uyumlu değişiklikler v1 içinde duyurusuz yapılabilir; yazılımınız bilinmeyen alanları yok saymalı. Geriye uyumsuz değişiklikler yeni sürümle gelir; v1 en az 12 ay desteklenir ve kaldırılmadan en az 90 gün önce e-posta ve Duyurular ile bildirilir.

Uçlar

GET/accountherhangi

Anahtarın bağlı olduğu hesap ve anahtarın kendisi.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/account

Örnek yanıt

{ "data": { "account": { "customer_no": 482913, "name": "Örnek Yazılım Ltd.", "currency": "TRY" },
  "key": { "name": "Yedekleme betiği", "prefix": "snc_k3m9q2xa", "scopes": ["services:read"],
           "expires_at": "2027-01-08T09:00:00Z", "ip_restricted": true } } }

GET/servicesservices:read

Hizmet listesi (oluşturulma sırasına göre).

ParametreAçıklama
statecurrent (varsayılan, süren hizmetler), ended (biten) ya da all.
categoryserver, hosting, domain, email, storage, app ya da other.
page, per_pageSayfa (1'den) ve sayfa boyu (1-100, varsayılan 50).

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" "https://sunucu.com.tr/api/v1/services?state=current"

Örnek yanıt

{ "data": [ {
    "code": "482913-639201",
    "name": "Bulut Sunucu",
    "category": "server",
    "status": "active",
    "hostname": "web01.ornek.com",
    "domain": null,
    "ipv4": "203.0.113.10",
    "additional_ips": ["203.0.113.11"],
    "location": "Türkiye",
    "os": "Ubuntu 24.04",
    "specs": { "vcpu": 2, "ram_gb": 4, "disk_gb": 80 },
    "power_state": "running",
    "power_actions": true,
    "billing": { "cycle": "monthly", "amount": "420.00", "currency": "TRY", "vat_included": true, "next_due_date": "2026-11-01" },
    "created_at": "2026-03-14T08:12:00Z"
  } ],
  "meta": { "page": 1, "per_page": 50, "total": 1 } }

GET/services/{code}services:read

Tek hizmet. {code}, paneldeki hizmet kodudur (müşteri no ve hizmet no, ör. 482913-639201).

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201

Örnek yanıt

{ "data": {
    "code": "482913-639201",
    "name": "Bulut Sunucu",
    "category": "server",
    "status": "active",
    "hostname": "web01.ornek.com",
    "domain": null,
    "ipv4": "203.0.113.10",
    "additional_ips": ["203.0.113.11"],
    "location": "Türkiye",
    "os": "Ubuntu 24.04",
    "specs": { "vcpu": 2, "ram_gb": 4, "disk_gb": 80 },
    "power_state": "running",
    "power_actions": true,
    "billing": { "cycle": "monthly", "amount": "420.00", "currency": "TRY", "vat_included": true, "next_due_date": "2026-11-01" },
    "created_at": "2026-03-14T08:12:00Z"
  } }

GET/services/{code}/statusservices:read

Sunucunun canlı durumu. Güç işlemi desteklenmeyen hizmette 422 power_not_supported.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/status

Örnek yanıt

{ "data": { "power": "running", "uptime_seconds": 273600, "guest_tools": true,
  "operation_in_progress": null, "checked_at": "2026-10-10T09:30:12Z" } }

POST/services/{code}/powerservers:power

Sunucuyu başlatır, kapatır ya da yeniden başlatır.

ParametreAçıklama
actionstart, shutdown, reboot, stop ya da reset (gövdede).
confirmstop ve reset için true olmalı (gövdede).
Idempotency-Keyİsteğe bağlı başlık, 8-48 karakter harf, rakam ve tire.
actionİşlem
startBaşlat
shutdownGüvenli kapat (işletim sistemine kapanma sinyali)
rebootGüvenli yeniden başlat
stopZorla kapat ("confirm": true gerekir)
resetZorla yeniden başlat ("confirm": true gerekir)

Güvenli işlemler sunucudaki işletim sisteminin yanıt vermesini gerektirir. Aynı isteği güvenle tekrarlamak için Idempotency-Key başlığı gönderin; aynı anahtarla gelen tekrar duplicate: true döner. Yeniden kurulum, iptal ve silme gibi geri alınamaz işlemler API'de yoktur; panelden yapılır.

Örnek istek

curl -X POST -H "Authorization: Bearer $SNC_API_KEY" \
  -H "Content-Type: application/json" -H "Idempotency-Key: yeniden-baslat-0001" \
  -d '{"action":"reboot"}' https://sunucu.com.tr/api/v1/services/482913-639201/power

Örnek yanıt

{ "data": { "operation": { "id": 9812, "action": "reboot", "status": "completed",
  "expected_power": "running", "created_at": "2026-10-10T09:31:02Z", "finished_at": "2026-10-10T09:31:05Z" },
  "duplicate": false } }

GET/services/{code}/operationsservices:read

Sunucunun işlem günlüğü (yeniden eskiye).

ParametreAçıklama
limit1-100, varsayılan 50.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" "https://sunucu.com.tr/api/v1/services/482913-639201/operations?limit=20"

Örnek yanıt

{ "data": [ { "id": 9812, "action": "reboot", "label": "Yeniden başlatıldı", "status": "completed",
  "actor": "api_key", "actor_name": "Yedekleme betiği",
  "created_at": "2026-10-10T09:31:02Z", "finished_at": "2026-10-10T09:31:05Z" } ] }

GET/services/{code}/metricsservices:read

Sunucunun işlemci, bellek, disk ve ağ ölçümleri ile bu ayın trafiği. range: 24h (5 dakikalık), 7d ve 30d (saatlik), 1y (günlük). Dakikada en çok 20 istek; veri beş dakikada bir güncellenir.

ParametreAçıklama
range24h (varsayılan), 7d, 30d ya da 1y.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" "https://sunucu.com.tr/api/v1/services/482913-639201/metrics?range=7d"

Örnek yanıt

{ "data": { "range": "7d", "step_seconds": 3600,
  "from": "2026-10-03T11:00:00Z", "to": "2026-10-10T11:00:00Z",
  "current": { "collected_at": "2026-10-10T10:55:00Z", "power": "running", "cpu_percent": 12.5,
    "memory_percent": 40.1, "disk_used_percent": 63.2, "network_in_bps": 1200000,
    "network_out_bps": 300000, "uptime_seconds": 190400 },
  "filesystems": [ { "path": "/", "size_bytes": 42949672960, "free_bytes": 21474836480, "used_percent": 50 } ],
  "traffic": { "month": "2026-10", "in_bytes": 123456789, "out_bytes": 98765432 },
  "points": [ { "t": "2026-10-03T11:00:00Z", "cpu_percent": 12.1, "cpu_percent_max": 30.2,
    "memory_percent": 40, "disk_used_percent": 63, "disk_read_bps": 1048576, "disk_write_bps": 524288,
    "disk_read_iops": 12, "disk_write_iops": 4, "disk_latency_ms": 1.2, "network_in_bps": 1200000,
    "network_out_bps": 300000, "network_in_bytes": 540000000, "network_out_bytes": 135000000,
    "powered_on_seconds": 3600 } ] } }

GET/invoicesinvoices:read

Fatura listesi (yeniden eskiye); panelde gördüğünüz faturalar.

ParametreAçıklama
statusunpaid, paid, cancelled, refunded ya da all (varsayılan).
page, per_pageSayfa ve sayfa boyu (1-100, varsayılan 50).

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" "https://sunucu.com.tr/api/v1/invoices?status=unpaid"

Örnek yanıt

{ "data": [ {
    "id": 1234, "number": "S-1234", "status": "unpaid", "type": "standard",
    "date": "2026-10-01", "due_date": "2026-10-08", "paid_date": null,
    "currency": "TRY", "total": "504.00", "amount_paid": "0.00", "balance_due": "504.00",
    "vat_included": true, "items_count": 3,
    "url": "https://sunucu.com.tr/panel/faturalar/1234"
  } ],
  "meta": { "page": 1, "per_page": 50, "total": 1 } }

GET/invoices/{id}invoices:read

Tek fatura ve kalemleri.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/invoices/1234

Örnek yanıt

{ "data": { "id": 1234, "number": "S-1234", "status": "unpaid", "total": "504.00",
  "subtotal": "420.00", "vat": "84.00",
  "items": [ { "description": "Bulut Sunucu (01.10.2026 - 31.10.2026)", "amount": "420.00", "group": null } ] } }

Object Storage

Object Storage hizmetinizin bucket'larını ve erişim anahtarlarını yönetin, kullanımı okuyun. Bu uçlar yönetim içindir; dosya yükleme ve indirme S3 API'si üzerinden https://s3.tr.sunucu.com.tr adresine yapılır (bkz. Araçlar ve SDK'lar).

  • Anahtarda storage:read (okuma) ya da storage:write (yönetim, okumayı da içerir) yetkisi gerekir. {code} Object Storage hizmetinizin kodudur.
  • Yeni ya da yenilenen erişim anahtarının secret_access_key alanı yalnız o yanıtta bir kez döner; biz saklamayız. Yanıt Cache-Control: no-store ile gelir; değeri loglara yazmayın.
  • Gövdeli isteklerde Content-Type: application/json zorunludur (yoksa 415), gövde en çok 8 KB. Bilinmeyen alanlar sessizce yok sayılmaz, 400 invalid_request döner.
  • Başka hesabın bucket ya da anahtarı, hiç yokmuş gibi 404 not_found döner.
  • Her değişiklik, API anahtarınızın adıyla hesap hareketlerine kaydedilir.

Oran sınırları (genel sınırlara ek olarak, hizmet başına 10 dakikalık pencere):

İşlemSınır
Okuma uçları (GET)Anahtar başına dakikada 120
Yazma uçları (POST, PATCH, PUT, DELETE)Anahtar başına dakikada 10
Bucket oluşturma ve ayar değişikliğiHizmet başına 10 dakikada 30
Bucket silmeHizmet başına 10 dakikada 10
Anahtar oluşturma ve yenilemeHizmet başına 10 dakikada 20
Anahtar pasife alma, silme, IP listesiHizmet başına 10 dakikada 60

Depolama uçları

GET/services/{code}/bucketsstorage:read

Hizmetteki bucket'lar; kullanım rakamları son ölçümden.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/buckets

Örnek yanıt

{ "data": [ {
    "name": "sirket-yedekleri",
    "status": "active",
    "versioning": "enabled",
    "object_lock": { "enabled": true, "mode": "GOVERNANCE", "default_retention_days": 30 },
    "quota_gb": null,
    "used_bytes": 1073741824,
    "object_count": 1520,
    "measured_at": "2026-10-14T09:00:00Z",
    "created_at": "2026-10-01T08:12:00Z",
    "key_count": 1
  } ] }

POST/services/{code}/bucketsstorage:write

Yeni bucket. Ad küme genelinde eşsizdir (alınmışsa 409 name_taken); hesap başına en çok 100 bucket (aşılırsa 409 limit_reached). Yanıt 201.

AlanAçıklama
nameZorunlu. 3-63 karakter; küçük harf, rakam ve tire; nokta yok.
versioningİsteğe bağlı, true/false (varsayılan false).
object_lockİsteğe bağlı, true/false. Yalnız oluştururken açılır, versioning'i de açar. Kip her zaman GOVERNANCE.
lock_daysobject_lock true ise varsayılan saklama süresi, 1-3650 gün. object_lock kapalıyken gönderilmez.

Örnek istek

curl -X POST -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"sirket-yedekleri","object_lock":true,"lock_days":30}' \
  https://sunucu.com.tr/api/v1/services/482913-639201/buckets

Örnek yanıt

{ "data": {
    "name": "sirket-yedekleri",
    "status": "active",
    "versioning": "enabled",
    "object_lock": { "enabled": true, "mode": "GOVERNANCE", "default_retention_days": 30 },
    "quota_gb": null,
    "used_bytes": 1073741824,
    "object_count": 1520,
    "measured_at": "2026-10-14T09:00:00Z",
    "created_at": "2026-10-01T08:12:00Z",
    "key_count": 0
  } }

GET/services/{code}/buckets/{ad}storage:read

Tek bucket.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/buckets/sirket-yedekleri

Örnek yanıt

{ "data": {
    "name": "sirket-yedekleri",
    "status": "active",
    "versioning": "enabled",
    "object_lock": { "enabled": true, "mode": "GOVERNANCE", "default_retention_days": 30 },
    "quota_gb": null,
    "used_bytes": 1073741824,
    "object_count": 1520,
    "measured_at": "2026-10-14T09:00:00Z",
    "created_at": "2026-10-01T08:12:00Z",
    "key_count": 1
  } }

PATCH/services/{code}/buckets/{ad}storage:write

Versioning ya da bucket kotası. En az bir alan gerekir; yanıt güncel bucket.

AlanAçıklama
versioning"enabled" ya da "suspended". Object lock açık bucket'ta askıya alınamaz.
quota_gbBucket kotası (GB, tam sayı, en az 1, en çok paket kotası) ya da kaldırmak için null.

Örnek istek

curl -X PATCH -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"quota_gb":50}' https://sunucu.com.tr/api/v1/services/482913-639201/buckets/sirket-yedekleri

Örnek yanıt

{ "data": { "name": "sirket-yedekleri", "quota_gb": 50, ... } }

DELETE/services/{code}/buckets/{ad}storage:write

Bucket'ı siler. Gövdesiz istek yalnız boş bucket'ı siler (doluysa 400 invalid_request). İçeriğiyle silmek geri alınamaz: purge_objects ile birlikte confirm alanına bucket adını yazın (eşleşmezse 422 confirm_required).

AlanAçıklama
purge_objectsİsteğe bağlı, true: bütün nesneler ve sürümleriyle sil.
confirmpurge_objects true ise zorunlu; bucket adının aynısı.

Örnek istek

curl -X DELETE -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"purge_objects":true,"confirm":"eski-arsiv"}' https://sunucu.com.tr/api/v1/services/482913-639201/buckets/eski-arsiv

Örnek yanıt

{ "data": { "name": "eski-arsiv", "deleted": true } }

GET/services/{code}/keysstorage:read

Hizmetteki bütün erişim anahtarları (hesap geneli ve bucket'a özel). Gizli anahtar hiçbir listede yoktur.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/keys

Örnek yanıt

{ "data": [ {
    "id": 41,
    "label": "yedek-sunucusu",
    "bucket": "sirket-yedekleri",
    "scope": "bucket",
    "access_key_id": "<ERISIM_ANAHTARI>",
    "allowed_ips": ["203.0.113.10/32"],
    "status": "active",
    "last_used_at": "2026-10-14T03:15:12Z",
    "created_at": "2026-10-01T08:13:00Z"
  } ] }

GET/services/{code}/buckets/{ad}/keysstorage:read

Yalnız bu bucket'a özel anahtarlar.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/buckets/sirket-yedekleri/keys

Örnek yanıt

{ "data": [ {
    "id": 41,
    "label": "yedek-sunucusu",
    "bucket": "sirket-yedekleri",
    "scope": "bucket",
    "access_key_id": "<ERISIM_ANAHTARI>",
    "allowed_ips": ["203.0.113.10/32"],
    "status": "active",
    "last_used_at": "2026-10-14T03:15:12Z",
    "created_at": "2026-10-01T08:13:00Z"
  } ] }

POST/services/{code}/keysstorage:write

Yeni erişim anahtarı. bucket null ya da yoksa hesap geneli (en çok 4); bucket adı verilirse yalnız o bucket (bucket başına en çok 2). secret_access_key YALNIZ bu yanıtta döner. Yanıt 201.

AlanAçıklama
bucketBucket adı ya da null (hesap geneli). Bucket hazır (active) olmalı.
labelİsteğe bağlı ad, en çok 64 karakter.
allowed_ipsİsteğe bağlı izinli adresler dizisi (IPv4/IPv6, CIDR), en çok 20; özel ağ adresi kabul edilmez. Boş dizi: kısıt yok.

Örnek istek

curl -X POST -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"bucket":"sirket-yedekleri","label":"yedek-sunucusu","allowed_ips":["203.0.113.10"]}' \
  https://sunucu.com.tr/api/v1/services/482913-639201/keys

Örnek yanıt

{ "data": { "id": 41, "label": "yedek-sunucusu", "bucket": "sirket-yedekleri", "scope": "bucket",
  "access_key_id": "<ERISIM_ANAHTARI>", "allowed_ips": ["203.0.113.10/32"], "status": "active",
  "last_used_at": null, "created_at": "2026-10-14T09:20:00Z",
  "secret_access_key": "<GIZLI_ANAHTAR>",
  "endpoint": "https://s3.tr.sunucu.com.tr", "region": "tr-ist-1" } }

POST/services/{code}/buckets/{ad}/keysstorage:write

Bucket'a özel anahtar için kısa yol; gövdede bucket alanı gönderilmez (label, allowed_ips). Yanıt POST /keys ile aynı.

Örnek istek

curl -X POST -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"label":"web-uygulamasi"}' https://sunucu.com.tr/api/v1/services/482913-639201/buckets/sirket-yedekleri/keys

Örnek yanıt

{ "data": { "id": 42, ..., "secret_access_key": "<GIZLI_ANAHTAR>", "endpoint": "https://s3.tr.sunucu.com.tr", "region": "tr-ist-1" } }

GET/services/{code}/keys/{no}storage:read

Tek anahtar. {no}, listedeki id alanıdır.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/keys/41

Örnek yanıt

{ "data": {
    "id": 41,
    "label": "yedek-sunucusu",
    "bucket": "sirket-yedekleri",
    "scope": "bucket",
    "access_key_id": "<ERISIM_ANAHTARI>",
    "allowed_ips": ["203.0.113.10/32"],
    "status": "active",
    "last_used_at": "2026-10-14T03:15:12Z",
    "created_at": "2026-10-01T08:13:00Z"
  } }

PATCH/services/{code}/keys/{no}storage:write

Anahtarı pasife alır ya da yeniden etkinleştirir. Pasif anahtar silinmez, istekleri reddedilir. Pasife alma hizmet askıdayken de yapılabilir.

AlanAçıklama
activeZorunlu, true ya da false.

Örnek istek

curl -X PATCH -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" -d '{"active":false}' https://sunucu.com.tr/api/v1/services/482913-639201/keys/41

Örnek yanıt

{ "data": { "id": 41, ..., "status": "inactive" } }

DELETE/services/{code}/keys/{no}storage:write

Anahtarı kalıcı olarak siler; hemen geçersiz olur. Bucket'taki veriler etkilenmez. Hizmet askıdayken de yapılabilir.

Örnek istek

curl -X DELETE -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/keys/41

Örnek yanıt

{ "data": { "id": 41, "deleted": true } }

POST/services/{code}/keys/{no}/rotatestorage:write

Yeni erişim anahtarı ve gizli anahtar üretir; eskisi hemen geçersiz olur. Kapsam ve IP listesi korunur. secret_access_key YALNIZ bu yanıtta döner.

Örnek istek

curl -X POST -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/keys/41/rotate

Örnek yanıt

{ "data": { "id": 41, ..., "access_key_id": "<YENI_ERISIM_ANAHTARI>",
  "secret_access_key": "<YENI_GIZLI_ANAHTAR>", "endpoint": "https://s3.tr.sunucu.com.tr", "region": "tr-ist-1" } }

PUT/services/{code}/keys/{no}/ipstorage:write

İzinli adres listesini baştan yazar. Boş dizi kısıtı kaldırır. Yanıt güncel anahtar.

AlanAçıklama
allowed_ipsZorunlu dizi, en çok 20 adres ya da aralık; tek adres /32 (IPv6 /128) olarak kaydedilir.

Örnek istek

curl -X PUT -H "Authorization: Bearer $SNC_API_KEY" -H "Content-Type: application/json" \
  -d '{"allowed_ips":["203.0.113.10","198.51.100.0/24"]}' https://sunucu.com.tr/api/v1/services/482913-639201/keys/41/ip

Örnek yanıt

{ "data": { "id": 41, ..., "allowed_ips": ["203.0.113.10/32", "198.51.100.0/24"] } }

GET/services/{code}/usagestorage:read

Paket, kota, kullanım, bu ayki dışa trafik ve aşım tahmini, son 30 günün günlük kırılımı. status: active, suspended, provisioning ya da unavailable.

Örnek istek

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/services/482913-639201/usage

Örnek yanıt

{ "data": { "package": "s3-tr-100", "status": "active",
  "endpoint": "https://s3.tr.sunucu.com.tr", "region": "tr-ist-1",
  "quota_bytes": 107374182400, "used_bytes": 1073741824, "object_count": 1520,
  "measured_at": "2026-10-14T09:00:00Z",
  "egress": { "period": "2026-10", "bytes": 5368709120, "included_bytes": 214748364800,
    "overage_gb": 0, "overage_usd": 0 },
  "daily": [ { "day": "2026-10-13", "used_bytes": 1073741824, "object_count": 1518,
    "egress_bytes": 104857600, "ingress_bytes": 52428800, "requests": 3120 } ] } }

Depolama hataları

Hata gövdesi diğer uçlarla aynıdır: { "error": { "code", "message", "request_id" } }. Doğrulama hatalarında (400 invalid_request) message alanı neyin yanlış olduğunu Türkçe söyler.

KodHTTPNe zaman
storage_unavailable404Hizmet kodu doğru ama bu hizmette Object Storage hesabı yok (başka ürün ya da henüz açılmamış).
name_taken409Bucket adı başka bir hesapta ya da sizde kullanımda.
limit_reached409Bucket ya da anahtar sayısı sınırı doldu.
service_not_active409Hizmet askıda, hazırlanıyor ya da kapanmış; message alanında nedeni yazar. Anahtar silme ve pasife alma yine çalışır.
confirm_required422İçerikle silmede confirm alanı bucket adıyla eşleşmiyor.
operation_in_progress409Aynı bucket ya da anahtarda süren bir işlem var; birkaç saniye sonra tekrar deneyin.
infrastructure_error503Depolama tarafında geçici sorun; işlem uygulanmadı, tekrar deneyebilirsiniz.

Geçici hatalarda (409 operation_in_progress, 429 rate_limited, 503 infrastructure_error) isteği artan aralıklarla yeniden deneyin; 429'da Retry-After başlığındaki süre kadar bekleyin.

E-posta gönderimi

SMTP hizmetinizde doğruladığınız alan adlarından tek bir istekle e-posta gönderin. SMTP ile aynı aylık kota, hız sınırları ve koruma kuralları geçerlidir; gönderim günlüğü panelde de görünür.

  • Gönderim alan adınızı hizmet sayfasından ekleyip doğrulayın (DNS kayıtları orada).
  • Panel > API sayfasında "E-posta gönderme" (emails:send) yetkili bir anahtar oluşturun. Birden çok SMTP hizmetiniz varsa anahtarı tek hizmete bağlayabilirsiniz.
  • Eski anahtarlar e-posta yetkisi taşımaz; yeni anahtar oluşturun.

Hızlı başlangıç

curl

curl -X POST https://sunucu.com.tr/api/v1/emails \
  -H "Authorization: Bearer $SNC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: siparis-48213-onay" \
  -d '{
    "from": "Örnek Mağaza <bilgi@alanadiniz.com>",
    "to": ["musteri@ornek.com"],
    "subject": "Siparişiniz alındı",
    "html": "<p>Teşekkürler, siparişiniz hazırlanıyor.</p>",
    "text": "Teşekkürler, siparişiniz hazırlanıyor."
  }'

Node.js (fetch)

const res = await fetch("https://sunucu.com.tr/api/v1/emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SNC_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "siparis-48213-onay",
  },
  body: JSON.stringify({
    from: "Örnek Mağaza <bilgi@alanadiniz.com>",
    to: ["musteri@ornek.com"],
    subject: "Siparişiniz alındı",
    html: "<p>Teşekkürler, siparişiniz hazırlanıyor.</p>",
    tags: [{ name: "tur", value: "siparis" }],
  }),
});
const out = await res.json();
if (!res.ok) throw new Error(`${out.error.code}: ${out.error.message}`);
console.log(out.id); // em_...

PHP

<?php
$ch = curl_init("https://sunucu.com.tr/api/v1/emails");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("SNC_API_KEY"),
    "Content-Type: application/json",
    "Idempotency-Key: siparis-48213-onay",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "from" => "Örnek Mağaza <bilgi@alanadiniz.com>",
    "to" => ["musteri@ornek.com"],
    "subject" => "Siparişiniz alındı",
    "text" => "Teşekkürler, siparişiniz hazırlanıyor.",
    "attachments" => [[
      "filename" => "fatura.pdf",
      "content" => base64_encode(file_get_contents("fatura.pdf")),
    ]],
  ]),
]);
$out = json_decode(curl_exec($ch), true);
echo $out["id"] ?? $out["error"]["code"];

Python (requests)

import os, requests

r = requests.post(
    "https://sunucu.com.tr/api/v1/emails",
    headers={
        "Authorization": f"Bearer {os.environ['SNC_API_KEY']}",
        "Idempotency-Key": "siparis-48213-onay",
    },
    json={
        "from": "Örnek Mağaza <bilgi@alanadiniz.com>",
        "to": ["musteri@ornek.com"],
        "subject": "Siparişiniz alındı",
        "text": "Teşekkürler, siparişiniz hazırlanıyor.",
    },
    timeout=30,
)
out = r.json()
print(out["id"] if r.ok else out["error"])

Başarılı yanıt. Engel listesindeki (önceden geri dönen ya da şikâyet eden) alıcılar atlanır ve suppressed içinde maskeli döner:

HTTP/1.1 201 Created
{ "id": "em_k3m9q2xa7d5b4c6e8f2g3h4j5k", "status": "accepted", "accepted": 1, "suppressed": [] }

İstek alanları

AlanAçıklama
fromZorunlu. "Ad <adres>" ya da yalın adres. Alan adı, anahtarın SMTP hizmetinde doğrulanmış olmalı (alt alan adı ayrıca eklenir).
toZorunlu. Metin ya da metin dizisi. to, cc ve bcc toplamı en çok 50 farklı alıcı.
cc, bccİsteğe bağlı, metin ya da dizi. bcc alıcıları iletinin başlığında görünmez.
subjectZorunlu. Tek satır, en çok 998 karakter.
html, textEn az biri zorunlu. Her biri en çok 5 MB.
reply_toİsteğe bağlı, en çok 5 adres.
headersİsteğe bağlı nesne. Yalnız şu başlıklar: List-Unsubscribe, List-Unsubscribe-Post, X-Entity-Ref-ID, In-Reply-To, References. Değer tek satır.
tagsİsteğe bağlı, en çok 10: [{ "name": "...", "value": "..." }], harf, rakam, alt çizgi, tire (1-64). Durum sorgusunda ve webhook'ta geri döner.
attachmentsİsteğe bağlı, en çok 10: [{ "filename": "fatura.pdf", "content": "<base64>", "content_type": "application/pdf" }]. Toplam en çok 7 MB. Adresten (URL) ek desteklenmez; çalıştırılabilir dosya türleri reddedilir.

Gövde JSON, en çok 10 MB. Tanımsız alan gönderirseniz istek reddedilir (yazım hatası sessizce yok sayılmaz).

Idempotency (güvenli tekrar)

Ağ hatasında aynı e-postayı iki kez göndermemek için Idempotency-Key başlığı gönderin (8-48 karakter; harf, rakam, tire). Anahtar 24 saat saklanır:

  • Anahtar hesap genelindedir: aynı hesabın farklı API anahtarlarıyla aynı Idempotency-Key tek ileti sayılır.
  • Aynı anahtar ve aynı gövde: ilk yanıt aynen döner, ileti yeniden gönderilmez (Idempotent-Replayed: true).
  • Aynı anahtar, farklı gövde: 409 idempotency_conflict.
  • İlk istek hâlâ işleniyorsa: 409 idempotency_in_progress; birkaç saniye sonra yeniden deneyin.
  • Başarısız istekler (ör. 429 kota ya da hız) saklanmaz; aynı anahtarla yeniden deneyebilirsiniz. Yalnız 504 send_uncertain saklanır: ileti gitmiş olabilir, önce durumu sorgulayın.

Sınırlar

  • Anahtar başına saniyede 5 gönderim isteği; hizmet başına saniyede 5 ileti; hesap toplamı dakikada 600.
  • Aylık kota alıcı sayısıyla düşer (to + cc + bcc). Kota dolunca 429 quota_exceeded; üst pakete geçerek hemen devam edebilirsiniz.
  • Yeni hesaplarda ilk 14 gün günlük gönderim sınırı uygulanır (429 daily_limit_exceeded).
  • İleti başına en çok 50 alıcı, ileti boyutu en çok 10 MB. Toplu (çok iletili) gönderim ucu yoktur.

E-posta hataları

KodHTTPAçıklama
feature_disabled503E-posta API'si bu hesapta şu an kullanılamıyor.
domain_not_verified403Gönderen alan adı doğrulanmış değil ya da bu anahtarın hizmetinde değil.
sender_not_allowed403Gönderen adresi kabul edilmedi.
sending_paused403Gönderim durduruldu. Nedeni hizmet sayfanızda yazıyor.
account_review403Hesabınız ekip incelemesinde; gönderim inceleme bitince açılır.
sending_unavailable503Gönderim geçici olarak kapalı. Daha sonra yeniden deneyin.
invalid_message422İleti oluşturulamadı ya da biçimi geçersiz.
too_many_recipients422İleti başına en çok 50 alıcı olabilir (to, cc ve bcc toplamı).
invalid_recipient422Alıcı adresi geçersiz.
all_recipients_suppressed422Tüm alıcılar gönderim engel listesinde (önceki geri dönme ya da şikâyet).
attachment_not_allowed422Bu ek türü ya da boyutu kabul edilmiyor.
payload_too_large413İstek gövdesi çok büyük.
daily_limit_exceeded429Yeni hesap günlük gönderim sınırına ulaşıldı. Yarın yeniden deneyin.
quota_exceeded429Aylık gönderim kotanız doldu. Üst pakete geçerek hemen devam edebilirsiniz.
message_rejected422İleti gönderim altyapısı tarafından reddedildi.
send_uncertain504Gönderim sonucu doğrulanamadı. Aynı Idempotency-Key ile yeniden denemeden önce iletinin durumunu sorgulayın.
idempotency_conflict409Bu Idempotency-Key farklı bir istek gövdesiyle kullanıldı.
idempotency_in_progress409Bu Idempotency-Key ile gönderilen istek hâlâ işleniyor.

4xx hataların çoğu kalıcıdır, isteği düzeltmeden tekrarlamayın. 429 ve 503 geçicidir: Retry-After kadar bekleyip yeniden deneyin.

Durum ve alan adları

GET /emails/{id} (emails:read): iletinin durumu ve teslim olayları. Alıcılar maskeli; konu ve içerik saklanmaz. GET /emails: son 30 günün iletileri (page, per_page, status: queued, sent, delivered, partially_delivered, bounced, complained, failed, unknown).

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/emails/em_k3m9q2xa7d5b4c6e8f2g3h4j5k

{ "data": {
  "object": "email", "id": "em_k3m9q2xa7d5b4c6e8f2g3h4j5k", "source": "api",
  "service": "482913-000412", "from_domain": "alanadiniz.com",
  "to": ["m***@o***.com"], "recipient_count": 1, "status": "delivered",
  "tags": { "tur": "siparis" },
  "created_at": "2026-10-20T09:30:00Z", "last_event_at": "2026-10-20T09:30:04Z",
  "events": [
    { "type": "email.sent", "recipient": null, "occurred_at": "2026-10-20T09:30:01Z", "bounce": null, "diagnostic": null },
    { "type": "email.delivered", "recipient": "m***@o***.com", "occurred_at": "2026-10-20T09:30:04Z", "bounce": null, "diagnostic": null }
  ] } }

GET /domains (domains:read): gönderim alan adlarınız ve durumları (verified, pending_ownership, pending_verification, failed, paused, conflict). Yalnız can_send: true olan alan adından gönderebilirsiniz.

curl -H "Authorization: Bearer $SNC_API_KEY" https://sunucu.com.tr/api/v1/domains

{ "data": [
  { "domain": "alanadiniz.com", "service": "482913-000412", "status": "verified", "can_send": true,
    "created_at": "2026-10-18T07:12:00Z" },
  { "domain": "kampanya.alanadiniz.com", "service": "482913-000412", "status": "pending_verification",
    "can_send": false, "created_at": "2026-10-20T08:00:00Z" } ],
  "meta": { "total": 2 } }

Webhook'lar

Panel > API sayfasından en çok 5 https adresi ekleyin. Seçtiğiniz olaylarda adresinize imzalı JSON bildirimi göndeririz. Konu ve içerik bildirimde yer almaz.

OlayAnlamı
email.sentGönderildi (alıcı sunucusuna yola çıktı)
email.deliveredTeslim edildi
email.delivery_delayedTeslim gecikiyor
email.bouncedGeri döndü
email.complainedŞikâyet edildi (istenmeyen olarak işaretlendi)
email.rejectedReddedildi (gönderilmedi)
POST /webhook/eposta HTTP/1.1
Content-Type: application/json; charset=utf-8
User-Agent: sunucu.com.tr-webhook/1
X-Snc-Event-Id: evt_q2xa7d5b4c6e8f2g3h4j5k3m9a
X-Snc-Timestamp: 1760952604
X-Snc-Signature: v1=5d41402abc4b2a76b9719d911017c592...

{"id":"evt_q2xa7d5b4c6e8f2g3h4j5k3m9a","type":"email.bounced","created_at":"2026-10-20T09:30:04Z",
 "data":{"email_id":"em_k3m9q2xa7d5b4c6e8f2g3h4j5k","from_domain":"alanadiniz.com",
  "to":"musteri@ornek.com","occurred_at":"2026-10-20T09:30:03Z",
  "bounce":{"type":"Permanent","subtype":"General"},
  "diagnostic":"smtp; 550 5.1.1 kullanıcı bulunamadı","tags":{"tur":"siparis"}}}
  • Adres 5 saniye içinde 2xx yanıt vermeli. Yönlendirme (3xx) izlenmez, başarısız sayılır.
  • Başarısız bildirim 1 dk, 5 dk, 30 dk, 2 sa, 6 sa, 12 sa ve 24 sa sonra yeniden denenir. Adres 3 gün boyunca hiç yanıt vermezse kapatılır ve size e-posta gönderilir; düzelttikten sonra panelden yeniden açın.
  • Aynı olay birden çok kez gelebilir; X-Snc-Event-Id (gövdede id) ile tekrarları süzün. Sıra garanti değildir.
  • Adres yalnız https ve 443 portu olabilir; iç ağ ya da özel IP adresine çıkan adresler kabul edilmez.
  • Panelde "Deneme gönder" ile webhook.test türünde bir bildirim gönderebilirsiniz.

İmza doğrulama

Her bildirimde X-Snc-Signature: v1=<hex> başlığı bulunur. Değer, imza sırrınızla (whsec_ ile başlayan metnin tamamı) X-Snc-Timestamp + "." + ham gövde üzerinden hesaplanan HMAC-SHA256'dır. Gövdeyi JSON'a çevirmeden, ham haliyle doğrulayın; 5 dakikadan eski zaman damgasını reddedin; karşılaştırmayı sabit sürede yapın. Sır yalnız eklerken ve yenilerken bir kez gösterilir.

Node.js

import { createHmac, timingSafeEqual } from "node:crypto";

// Express örneği: gövdeyi HAM olarak alın (JSON'a çevirmeden önce imzayı doğrulayın).
app.post("/webhook/eposta", express.raw({ type: "application/json" }), (req, res) => {
  const ts = req.get("X-Snc-Timestamp") ?? "";
  const sig = req.get("X-Snc-Signature") ?? "";
  const body = req.body.toString("utf8");
  if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(400);
  const expected = "v1=" + createHmac("sha256", process.env.SNC_WEBHOOK_SECRET).update(`${ts}.${body}`).digest("hex");
  const exp = Buffer.from(expected);
  const ok = sig.split(" ").some((s) => {
    const got = Buffer.from(s);
    return got.length === exp.length && timingSafeEqual(got, exp); // bayt uzunluğu, karakter değil
  });
  if (!ok) return res.sendStatus(401);
  const event = JSON.parse(body);
  // event.id ile tekrarları süzün (aynı olay yeniden gönderilebilir).
  res.sendStatus(204);
});

PHP

<?php
$body = file_get_contents("php://input");
$ts = $_SERVER["HTTP_X_SNC_TIMESTAMP"] ?? "";
$sig = $_SERVER["HTTP_X_SNC_SIGNATURE"] ?? "";
if (!ctype_digit($ts) || abs(time() - (int)$ts) > 300) { http_response_code(400); exit; }
$expected = "v1=" . hash_hmac("sha256", $ts . "." . $body, getenv("SNC_WEBHOOK_SECRET"));
$ok = false;
foreach (explode(" ", $sig) as $s) { if (hash_equals($expected, $s)) { $ok = true; } }
if (!$ok) { http_response_code(401); exit; }
$event = json_decode($body, true);
http_response_code(204);

Python

import hmac, hashlib, os, time
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/webhook/eposta")
def eposta():
    body = request.get_data(as_text=True)
    ts = request.headers.get("X-Snc-Timestamp", "")
    sig = request.headers.get("X-Snc-Signature", "")
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        abort(400)
    expected = "v1=" + hmac.new(os.environ["SNC_WEBHOOK_SECRET"].encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
    if not any(hmac.compare_digest(expected, s) for s in sig.split(" ")):
        abort(401)
    event = request.get_json()
    return "", 204

Değişiklik günlüğü

  • 14 Ekim 2026 · Object Storage uçları eklendi: bucket, erişim anahtarı, IP listesi ve kullanım.
  • E-posta gönderimi, durum sorgusu, alan adları ve webhook'lar eklendi.
  • 10 Ekim 2026 · v1 yayında.

Sorularınız için panelden destek talebi açın.