Nuvaka › Geliştirici belgeleri › Proje API'si

Proje API'si

Proje sitenin ya da servisinin sunucusu, dosyalarını Nuvaka'da tutar: yükler, listeler, gerektiğinde geri indirir ve ziyaretçilerine herkese açık indirme bağlantısı verir. Kimlik tek bir sunucu tarafı proje anahtarıdır (nvk_…); kullanıcı girişi, tarayıcı akışı yoktur.

Proje anahtarı nedir

  • Bir proje anahtarı, bir Nuvaka hesabının Dosyalarım'ındaki tek bir kök klasöre (ör. Projeler/cyd) erişim verir. Bütün yollar bu köke göredir; anahtar kökün dışına, başka klasörlere ve Güvenli Alan'a hiçbir yoldan ulaşamaz.
  • Anahtarı yalnız Nuvaka yöneticileri verir; kendin oluşturamazsın. Anahtar, kök klasör, izinler, isteğe bağlı klasör kotası ve IP izin listesiyle birlikte tanımlanır. Anahtar yalnız bir kez gösterilir; Nuvaka yalnız özetini saklar.
  • Kullanıcıların kendi hesaplarıyla giriş yapacağı bir uygulama yazıyorsan bu sayfa değil, Nuvaka ile giriş (OAuth, storage.folder) senin için.

Anahtar bir sunucu sırrıdır

  • Anahtarı yalnız projenin kendi sunucusunda tut: ortam değişkeni ya da izni kısıtlı bir dosya. Tarayıcıya giden JavaScript'e, mobil uygulamaya, cihaz yazılımına ya da git deposuna koyma.
  • Bu yüzden API CORS vermez: tarayıcıdan doğrudan çağrılamaz. Ziyaretçiye dosya vermek için sunucun bir paylaşım bağlantısı oluşturur ya da dosyayı indirip kendisi sunar.
  • Anahtar sızdıysa yöneticiden yenilemesini iste: eski anahtar anında çalışmaz olur. Sunucunun sabit bir çıkış IP'si varsa anahtarı o IP'ye kısıtlatmak iyi bir ek önlemdir.

Anahtar silinirse

  • Silinen anahtar anında çalışmaz: her istek 401 invalid_key alır.
  • 30 gün boyunca anahtarın açtığı paylaşım bağlantıları çalışmaya devam eder; kök klasördeki dosyalara hiç dokunulmaz. Bu sürede yönetici anahtarı geri yükleyebilir.
  • Geri yükleme eski anahtarı diriltmez: yenilemede olduğu gibi yeni bir nvk_… verilir (bir kez gösterilir) ve sunucuna onu koyman gerekir. Eski anahtar geçersiz kalır; paylaşım bağlantıları aynı kalır ve yeni anahtarın GET shares listesinde görünür.
  • 30 gün dolunca anahtar kalıcı silinir ve açtığı paylaşım bağlantıları kapanır. Dosyalar ve klasörler hesabın Dosyalarım'ında kalır.

Kimlik

Taban adres https://generalappapi.nuvaka.com/api/project/v1. Anahtarı şu başlıklardan biriyle gönder:

Authorization: Bearer nvk_…
X-Api-Key: nvk_…

Anahtar yanlışsa, devre dışı bırakıldıysa, silindiyse ya da yenilendiyse yanıt 401 invalid_key olur. Değişiklikler anında etkilidir.

İzinler

İzinNe verir
files.readlisteleme, bilgi (stat), indirme
files.writeyükleme (tek ve parçalı), klasör oluşturma, taşıma ve yeniden adlandırma
files.deletedosya ya da klasör silme (çöp kutusuna)
files.shareherkese açık indirme bağlantısı oluşturma ve kapatma

İzni olmayan işlem 403 insufficient_scope döner; yanıttaki scope alanı hangi iznin gerektiğini söyler. Yalnız indirme yapan bir sunucu için yalnız files.read isteyin.

Yollar

  • Her path kök klasöre göredir ve parçalar / ile ayrılır: firmware/v1.2.0/cyd-os.bin. Baştaki / yok sayılır; /etc/passwd kökün içindeki etc/passwd demektir.
  • . ya da .. parçası, ters bölü, kontrol karakteri, 255 karakterden uzun ad ve 32'den derin yol 400 bad_path döner.
  • Öğeler kimlikle de gösterilebilir: dosya için fileId, klasör için folderId. Kökün dışındaki bir kimlik 403 out_of_scope, olmayan ya da başka hesabın kimliği 404 not_found döner.

Yanıtlardaki öğeler:

{ "type": "file", "name": "cyd-os.bin", "path": "firmware/v1.2.0/cyd-os.bin", "fileId": "…",
  "size": 1048576, "contentType": "application/octet-stream",
  "createdAt": "2026-10-17T12:00:00Z", "updatedAt": "2026-10-17T12:00:00Z", "version": 1, "encrypted": false }
{ "type": "folder", "name": "v1.2.0", "path": "firmware/v1.2.0", "folderId": 123, "createdAt": "…" }

Uç noktalar

UçİzinAçıklama
GET me—anahtar adı, proje, izinler, usedBytes, quotaBytes ve sınırlar
GET list?path=&recursive=files.readklasör içeriği; önce klasörler, sonra dosyalar. recursive=true bütün alt ağaç (en çok 10000 öğe, aşılırsa truncated: true)
GET stat?path= (ya da fileId, folderId)files.readtek öğe: { item }
GET download?path= (ya da fileId)files.readdosya içeriği; Range desteklenir (206)
POST upload?path=&overwrite=files.writetek istekle yükleme: ham gövde, en çok 100 MB, Content-Length zorunlu. Üst klasörler kendiliğinden oluşur
POST uploadsfiles.writebüyük dosya için parçalı yükleme başlat (aşağıda)
PUT uploads/{id}/chunks/{index}files.writebir parça gönder
GET uploads/{id}files.writegelen ve eksik parçalar (kaldığın yerden devam)
POST uploads/{id}/completefiles.writeyüklemeyi bitir
DELETE uploads/{id}files.writeyüklemeyi iptal et
POST mkdir { path }files.writeklasör oluştur (ara klasörlerle; varsa aynısı döner)
POST move { from, to }files.writetaşı ya da yeniden adlandır; to yeni tam yoldur. from yerine fromFileId / fromFolderId verilebilir
DELETE item?path= (ya da fileId, folderId)files.deleteçöp kutusuna taşır; klasör içeriğiyle gider. Kök silinemez
POST share { path, expiresAt?, maxDownloads? }files.shareherkese açık indirme bağlantısı
GET sharesfiles.sharebu anahtarın açtığı etkin bağlantılar
DELETE shares/{id}files.sharebağlantıyı kapat

Yükleme ve üzerine yazma

Aynı yolda dosya varsa yükleme 409 exists döner. overwrite=true ile aynı dosyanın yeni sürümü yüklenir: fileId ve dosyaya açılmış paylaşım bağlantıları aynı kalır, bağlantı artık yeni içeriği verir. Gönderdiğin Content-Type dosyanın türü olarak saklanır. Ağ hatasından sonra yeniden denerken X-Idempotency-Key başlığı gönderirsen aynı yükleme iki kez yapılmaz (10 dakika).

{ "success": true, "replaced": false, "item": { "type": "file", "path": "firmware/v1.2.0/cyd-os.bin", "fileId": "…", … } }

Parçalı yükleme (büyük dosyalar)

Tek istek en çok 100 MB olabilir; 64 MB üstünde parçalı yükleme kullan, kopan bağlantı baştan başlamasın.

  1. Başlat

    POST uploads { "path": "images/big.img", "size": 734003200, "contentType": "application/octet-stream", "overwrite": false } → { uploadId, chunkSize, totalChunks, expiresAt }. Parça boyu 32 MB, oturum 24 saat geçerli.

  2. Parçaları gönder

    PUT uploads/{id}/chunks/{index}, ham gövde; her parça tam chunkSize bayt, son parça kalan kadar. İsteğe bağlı X-Chunk-SHA256 başlığı doğrulanır. Aynı parçayı yeniden göndermek güvenlidir. 503 buffer_full gelirse Retry-After kadar bekleyip aynı parçayı yeniden gönder; bu bir hata değildir.

  3. Bitir

    POST uploads/{id}/complete → { success, item }. 202 { status: "processing" } gelirse birkaç saniye sonra yeniden çağır; aynı sonuç döner.

Paylaşım bağlantısı

POST share dosya için herkese açık bir bağlantı oluşturur. Bağlantıyı bilen herkes dosyayı anahtarsız indirebilir.

{ "success": true, "id": 42, "code": "AbCd1234",
  "url": "https://generalappapi.nuvaka.com/share/AbCd1234/download",
  "pageUrl": "https://generalappapi.nuvaka.com/share/AbCd1234",
  "expiresAt": null, "maxDownloads": null, "path": "firmware/v1.2.0/cyd-os.bin", "fileId": "…" }
  • url dosyanın kendisidir: sayfana doğrudan indirme bağlantısı olarak konabilir, Range desteklenir. pageUrl Nuvaka'nın indirme sayfasıdır.
  • expiresAt (UTC) ve maxDownloads isteğe bağlıdır. Parola da verilebilir, ama parolalı bağlantı önce Nuvaka sayfasında doğrulama ister; doğrudan site bağlantısı için kullanma.
  • Aynı dosyayı overwrite=true ile güncellemek bağlantıyı bozmaz. Klasör ve uçtan uca şifreli dosya paylaşılamaz.

Kota

  • Anahtarın isteğe bağlı bir klasör kotası olabilir; aşılınca 413 quota_exceeded ve "scope": "folder". Sayılan, kök altındaki güncel dosyaların toplamıdır; eski sürümler ve çöp kutusu sayılmaz.
  • Dosyalar sahibin hesabındadır; hesabın depolama kotası dolarsa 413 quota_exceeded ve "scope": "owner". Hesabın tek dosya sınırı 413 file_too_large olarak döner.
  • Güncel kullanımı GET me verir: usedBytes, quotaBytes.

Hız sınırları

  • Anahtar başına dakikada 600 okuma (GET) ve 120 yazma (POST, PUT, DELETE; her parça bir yazmadır).
  • Aşılınca 429 rate_limited, Retry-After başlığı ve retryAfter alanı. Bekle ve yeniden dene.
  • Hesap başına aynı anda en çok 5 açık parçalı yükleme (429 too_many_uploads). Hesabın günlük indirme kotası dolarsa 429 download_quota_exceeded.
  • Ziyaretçi trafiğini anahtarla değil, paylaşım bağlantılarıyla taşı: bağlantı indirmeleri anahtarın sınırına sayılmaz.

Hatalar

Hata yanıtı her zaman { "success": false, "error": "…", "message": "…" } biçimindedir.

KoderrorNe zaman
400bad_pathyol geçersiz ya da hedef verilmedi
400not_a_folder, not_a_filedosyayı listeleme, klasörü indirme/paylaşma
400root_immutable, bad_targetkökü taşıma/silme, klasörü kendi içine taşıma
401invalid_keyanahtar yok, yanlış, devre dışı, silinmiş ya da yenilenmiş
403insufficient_scopeanahtarda gereken izin yok
403out_of_scopekimlikle gösterilen öğe kök klasörün dışında
403ip_not_allowedistek, anahtarın izinli IP'lerinden gelmiyor
404not_found, upload_not_foundöğe ya da yükleme oturumu yok
409existshedef yolda zaten bir öğe var
411length_requiredtek yüklemede Content-Length yok
413quota_exceeded, too_large_for_single, file_too_largekota ya da boyut sınırı
429rate_limited, too_many_uploads, download_quota_exceededsınırlar
503buffer_fullparça: Retry-After kadar bekle, aynı parçayı yeniden gönder

curl örnekleri

export NVK=nvk_...        # yalnız sunucuda
B=https://generalappapi.nuvaka.com/api/project/v1

# anahtarı dene
curl -sS "$B/me" -H "Authorization: Bearer $NVK"

# yükle (ara klasörler oluşur; aynı yolu güncellemek için overwrite=true)
curl -sS -X POST "$B/upload?path=firmware/v1.2.0/cyd-os.bin&overwrite=true" \
  -H "Authorization: Bearer $NVK" -H "Content-Type: application/octet-stream" \
  --data-binary @cyd-os.bin

# listele
curl -sS "$B/list?path=firmware&recursive=true" -H "Authorization: Bearer $NVK"

# geri indir (yarıda kaldıysa: -C - ile Range)
curl -sS -o cyd-os.bin "$B/download?path=firmware/v1.2.0/cyd-os.bin" -H "X-Api-Key: $NVK"

# taşı / yeniden adlandır
curl -sS -X POST "$B/move" -H "Authorization: Bearer $NVK" -H "Content-Type: application/json" \
  -d '{"from":"firmware/v1.2.0/cyd-os.bin","to":"firmware/archive/cyd-os-1.2.0.bin"}'

# sil (çöp kutusuna)
curl -sS -X DELETE "$B/item?path=firmware/archive/cyd-os-1.2.0.bin" -H "Authorization: Bearer $NVK"

# herkese açık indirme bağlantısı
curl -sS -X POST "$B/share" -H "Authorization: Bearer $NVK" -H "Content-Type: application/json" \
  -d '{"path":"firmware/v1.2.0/cyd-os.bin"}'

Büyük dosyayı parça parça yükle:

size=$(stat -c%s big.img)
r=$(curl -sS -X POST "$B/uploads" -H "Authorization: Bearer $NVK" -H "Content-Type: application/json" \
     -d "{\"path\":\"images/big.img\",\"size\":$size}")
id=$(echo "$r" | jq -r .uploadId); cs=$(echo "$r" | jq -r .chunkSize); n=$(echo "$r" | jq -r .totalChunks)
for i in $(seq 0 $((n-1))); do
  dd if=big.img bs=$cs skip=$i count=1 status=none | \
    curl -sS -X PUT "$B/uploads/$id/chunks/$i" -H "Authorization: Bearer $NVK" \
         -H "Content-Type: application/octet-stream" --data-binary @-
done
curl -sS -X POST "$B/uploads/$id/complete" -H "Authorization: Bearer $NVK"

Tipik proje sitesi akışı

Örnek: cyd.nuvaka.com sunucusu yeni bir cihaz yazılımı sürümünü yayınlar ve ziyaretçilerine indirme bağlantısı verir.

  1. Yükle

    Derleme bitince sunucu dosyayı yükler: POST upload?path=firmware/v1.3.0/cyd-os.bin. Yanıttaki item.fileId ve item.path değerlerini kendi veritabanına yazar.

  2. Listele

    Sürümler sayfasını hazırlarken GET list?path=firmware&recursive=true ile klasördeki dosyaları, boyutlarını ve tarihlerini alır. Sonucu kendi tarafında önbelleğe alır; her ziyaretçi isteğinde API'yi çağırmaz.

  3. Bağlantı ver

    Her sürüm için bir kez POST share çağırır ve dönen url'yi saklar. Sayfadaki "İndir" düğmesi doğrudan bu adrese gider; ziyaretçi anahtarı hiç görmez ve indirmeler anahtarın hız sınırını tüketmez.

  4. Gerektiğinde geri al

    Sunucunun kendisi bir dosyaya ihtiyaç duyarsa (ör. sürüm notunu ya da derleme çıktısını işlemek) GET download?path=… ile indirir.

  5. Güncelle ya da kaldır

    Aynı sürümü düzeltmek için overwrite=true ile yükler (bağlantı aynı kalır, yeni içeriği verir). Eski sürümü kaldırmak için DELETE shares/{id} ve DELETE item?path=….

Nuvaka Apps API v1 · son güncelleme 2026-10-17