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
| Yetki | Ad | Kapsam |
|---|---|---|
| services:read | Hizmetleri okuma | Hizmet listesi ve ayrıntısı, sunucu durumu ve işlem günlüğü. |
| servers:power | Sunucu güç işlemleri | Sunucuları başlatma, kapatma ve yeniden başlatma. Hizmetleri okumayı da içerir. |
| invoices:read | Faturaları okuma | Fatura listesi, tutarlar ve fatura kalemleri. |
| emails:send | E-posta gönderme | Doğrulanmış gönderim alan adlarınızdan e-posta gönderme. Kota ve hız sınırları SMTP ile ortaktır. |
| emails:read | E-posta durumunu okuma | Gönderilen e-postaların durumu ve teslim olayları (alıcılar maskeli). |
| domains:read | Gönderim alan adlarını okuma | Gönderim alan adlarınız ve doğrulama durumları. |
| storage:read | Object Storage okuma | Bucket listesi, erişim anahtarları (gizli anahtar hariç) ve kullanım. |
| storage:write | Object Storage yönetimi | Bucket 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.
| Kod | HTTP | Açıklama |
|---|---|---|
| unauthorized | 401 | Geçerli bir API anahtarı gönderin. |
| key_expired | 401 | Bu API anahtarının süresi dolmuş. |
| key_revoked | 401 | Bu API anahtarı iptal edilmiş. |
| key_in_url | 400 | API anahtarı adres satırında gönderilemez; Authorization başlığını kullanın. |
| ip_not_allowed | 403 | Bu anahtar bu IP adresinden kullanılamaz. |
| account_locked | 403 | Hesap geçici olarak kullanıma kapatıldı. Destek ekibiyle iletişime geçin. |
| insufficient_scope | 403 | Bu işlem için anahtarda "yetki adı" yetkisi gerekiyor. |
| not_found | 404 | Kayıt bulunamadı. |
| method_not_allowed | 405 | Bu adres bu yöntemi desteklemiyor. |
| invalid_request | 400 | İstek geçersiz. |
| payload_too_large | 413 | İstek gövdesi çok büyük. |
| unsupported_media_type | 415 | Content-Type application/json olmalı. |
| invalid_action | 422 | Geçersiz işlem. Kullanılabilir: start, shutdown, reboot, stop, reset. |
| confirm_required | 422 | Zorla kapatma ve zorla yeniden başlatma için "confirm": true gönderin. |
| power_not_supported | 422 | Bu hizmette güç işlemi yapılamaz. |
| guest_tools_unavailable | 422 | Gü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_active | 409 | Bu hizmet şu an işleme açık değil. |
| monitoring_unavailable | 404 | Bu hizmet için izleme verisi yok. |
| service_provisioning | 409 | Sunucu hâlâ kuruluyor, lütfen bekleyin. |
| already_in_state | 409 | Sunucu zaten bu durumda. |
| operation_in_progress | 409 | Bu sunucuda süren bir işlem var. Bitmesini bekleyip tekrar deneyin. |
| idempotency_key_reused | 409 | Bu Idempotency-Key başka bir istekte kullanıldı. |
| rate_limited | 429 | Çok fazla istek. Retry-After başlığındaki süre kadar bekleyin. |
| too_many_failed_attempts | 429 | Bu adresten çok fazla başarısız deneme yapıldı. 10 dakika sonra tekrar deneyin. |
| api_disabled | 503 | API şu an geçici olarak kapalı. |
| infrastructure_error | 503 | İşlem şu an tamamlanamadı. Birkaç dakika sonra tekrar deneyin; sorun sürerse destek talebi açın. |
| internal_error | 500 | Beklenmeyen bir hata oluştu. Sorun sürerse request_id ile destek talebi açın. |
| name_taken | 409 | Bu bucket adı kullanımda. Başka bir ad seçin. |
| limit_reached | 409 | Bu hizmette izin verilen en yüksek sayıya ulaşıldı. |
| storage_unavailable | 404 | Bu 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).
| Parametre | Açıklama |
|---|---|
| state | current (varsayılan, süren hizmetler), ended (biten) ya da all. |
| category | server, hosting, domain, email, storage, app ya da other. |
| page, per_page | Sayfa (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.
| Parametre | Açıklama |
|---|---|
| action | start, shutdown, reboot, stop ya da reset (gövdede). |
| confirm | stop 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 |
|---|---|
| start | Başlat |
| shutdown | Güvenli kapat (işletim sistemine kapanma sinyali) |
| reboot | Güvenli yeniden başlat |
| stop | Zorla kapat ("confirm": true gerekir) |
| reset | Zorla 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).
| Parametre | Açıklama |
|---|---|
| limit | 1-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.
| Parametre | Açıklama |
|---|---|
| range | 24h (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.
| Parametre | Açıklama |
|---|---|
| status | unpaid, paid, cancelled, refunded ya da all (varsayılan). |
| page, per_page | Sayfa 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 dastorage: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_keyalanı yalnız o yanıtta bir kez döner; biz saklamayız. YanıtCache-Control: no-storeile gelir; değeri loglara yazmayın. - Gövdeli isteklerde
Content-Type: application/jsonzorunludur (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):
| İşlem | Sı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ği | Hizmet başına 10 dakikada 30 |
| Bucket silme | Hizmet başına 10 dakikada 10 |
| Anahtar oluşturma ve yenileme | Hizmet başına 10 dakikada 20 |
| Anahtar pasife alma, silme, IP listesi | Hizmet 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.
| Alan | Açıklama |
|---|---|
| name | Zorunlu. 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_days | object_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.
| Alan | Açıklama |
|---|---|
| versioning | "enabled" ya da "suspended". Object lock açık bucket'ta askıya alınamaz. |
| quota_gb | Bucket 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).
| Alan | Açıklama |
|---|---|
| purge_objects | İsteğe bağlı, true: bütün nesneler ve sürümleriyle sil. |
| confirm | purge_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.
| Alan | Açıklama |
|---|---|
| bucket | Bucket 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.
| Alan | Açıklama |
|---|---|
| active | Zorunlu, 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.
| Alan | Açıklama |
|---|---|
| allowed_ips | Zorunlu 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.
| Kod | HTTP | Ne zaman |
|---|---|---|
| storage_unavailable | 404 | Hizmet kodu doğru ama bu hizmette Object Storage hesabı yok (başka ürün ya da henüz açılmamış). |
| name_taken | 409 | Bucket adı başka bir hesapta ya da sizde kullanımda. |
| limit_reached | 409 | Bucket ya da anahtar sayısı sınırı doldu. |
| service_not_active | 409 | Hizmet askıda, hazırlanıyor ya da kapanmış; message alanında nedeni yazar. Anahtar silme ve pasife alma yine çalışır. |
| confirm_required | 422 | İçerikle silmede confirm alanı bucket adıyla eşleşmiyor. |
| operation_in_progress | 409 | Aynı bucket ya da anahtarda süren bir işlem var; birkaç saniye sonra tekrar deneyin. |
| infrastructure_error | 503 | Depolama 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ı
| Alan | Açıklama |
|---|---|
| from | Zorunlu. "Ad <adres>" ya da yalın adres. Alan adı, anahtarın SMTP hizmetinde doğrulanmış olmalı (alt alan adı ayrıca eklenir). |
| to | Zorunlu. 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. |
| subject | Zorunlu. Tek satır, en çok 998 karakter. |
| html, text | En 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ı
| Kod | HTTP | Açıklama |
|---|---|---|
| feature_disabled | 503 | E-posta API'si bu hesapta şu an kullanılamıyor. |
| domain_not_verified | 403 | Gönderen alan adı doğrulanmış değil ya da bu anahtarın hizmetinde değil. |
| sender_not_allowed | 403 | Gönderen adresi kabul edilmedi. |
| sending_paused | 403 | Gönderim durduruldu. Nedeni hizmet sayfanızda yazıyor. |
| account_review | 403 | Hesabınız ekip incelemesinde; gönderim inceleme bitince açılır. |
| sending_unavailable | 503 | Gönderim geçici olarak kapalı. Daha sonra yeniden deneyin. |
| invalid_message | 422 | İleti oluşturulamadı ya da biçimi geçersiz. |
| too_many_recipients | 422 | İleti başına en çok 50 alıcı olabilir (to, cc ve bcc toplamı). |
| invalid_recipient | 422 | Alıcı adresi geçersiz. |
| all_recipients_suppressed | 422 | Tüm alıcılar gönderim engel listesinde (önceki geri dönme ya da şikâyet). |
| attachment_not_allowed | 422 | Bu ek türü ya da boyutu kabul edilmiyor. |
| payload_too_large | 413 | İstek gövdesi çok büyük. |
| daily_limit_exceeded | 429 | Yeni hesap günlük gönderim sınırına ulaşıldı. Yarın yeniden deneyin. |
| quota_exceeded | 429 | Aylık gönderim kotanız doldu. Üst pakete geçerek hemen devam edebilirsiniz. |
| message_rejected | 422 | İleti gönderim altyapısı tarafından reddedildi. |
| send_uncertain | 504 | Gönderim sonucu doğrulanamadı. Aynı Idempotency-Key ile yeniden denemeden önce iletinin durumunu sorgulayın. |
| idempotency_conflict | 409 | Bu Idempotency-Key farklı bir istek gövdesiyle kullanıldı. |
| idempotency_in_progress | 409 | Bu 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.
| Olay | Anlamı |
|---|---|
| email.sent | Gönderildi (alıcı sunucusuna yola çıktı) |
| email.delivered | Teslim edildi |
| email.delivery_delayed | Teslim gecikiyor |
| email.bounced | Geri döndü |
| email.complained | Şikâyet edildi (istenmeyen olarak işaretlendi) |
| email.rejected | Reddedildi (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 "", 204Değ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.