REST API

HTTP üzerinden dosya yükleyin, koleksiyonlar oluşturun ve paylaşımları yönetin. Tüm yanıtlar JSON’dur; anonim yüklemeler için API anahtarı gerekmez.

Giriş

storage.to API, CLI, masaüstü uygulaması, web yükleyici ve oluşturmak istediğiniz herhangi bir üçüncü taraf istemciyi destekler.

Yükleme akışı üç adımdan oluşur:

  1. Başlat — bir dosya yüklemek istediğinizi söyleyin. Cloudflare R2’ye işaret eden bir veya daha fazla önceden imzalanmış URL döndürürüz.
  2. R2’ye yüklePUT baytlarını doğrudan önceden imzalanmış URL(ler)e gönder. Baytlar sunucularımızdan geçmez.
  3. Onayla — yüklemenin bittiğini bize bildirin. Bir File kaydı oluşturur ve paylaşılabilir bir URL veririz.

Temel URL

https://storage.to/api

Aşağıdaki tüm uç noktalar bu temel adrese göredir. Örnek: POST /upload/init, POST https://storage.to/api/upload/init anlamına gelir.

Kimlik doğrulama

Çoğu uç nokta kimlik doğrulama gerektirmez. Anonim yüklemeler temel bir özelliktir.

Kimlik doğrulama isteğe bağlıdır ve şunların kilidini açar:

  • Hesabınıza eklenen yüklemeler ( /dashboard bölümünde görünür )
  • Premium özellikler (kalıcı dosyalar, daha büyük depolama)
  • Ziyaretçi-token eşleşmesi gerektirmeden sahipliğe dayalı işlemler (silme, şifre belirleme, son kullanma tarihini değiştirme)

Laravel Sanctum bearer token’ları kullanırız. Masaüstü OAuth yönlendirmesi veya web girişi üzerinden bir token alın, ardından bunu şu şekilde gönderin:

Authorization: Bearer <token>

Ziyaretçi belirteci

Anonim istemcilerin, hesap olmadan kendi yüklemelerinin sahipliğini kanıtlaması için bir yol gerekir. İstemcinin bir kez oluşturup yeniden kullandığı rastgele bir ziyaretçi token’ı kullanırız. Her istekle birlikte gönderin:

X-Visitor-Token: <random-string>

Web’de token otomatik olarak visitor_token cookie’sinde saklanır. CLI bunu ~/.config/storageto/token konumunda saklar (bkz. CLI dokümantasyonu).

Değişiklik (mutation) uç noktalarında (silme, şifre belirleme, son kullanma tarihini değiştirme) sahiplik, ya da ziyaretçi token’ı eşleşiyorsa veya isteğin dosyayı oluşturan aynı IP’den gelmesi durumunda doğrulanır. İkisi de kaybolabilir (çerezlerin temizlenmesi, ağ değişiklikleri). Bundan sonra tercih edilen kanıt sahip token’ı’dır.

Sahip belirteci

Kaynak oluşturan her uç nokta (/upload/init multipart, /upload/confirm, /upload/reserve, /collection) yanıtında bir owner_token döndürür. Token, IP’nizden veya ziyaretçi token’ınızdan bağımsız olarak, o belirli kaynağa bağlı imzalı bir sahiplik kanıtıdır.

Token’ı kaynak kimliğiyle birlikte saklayın ve herhangi bir mutation işleminde şu şekilde gönderin:

Authorization: Owner <token>

Ya da kimliği doğrulanmış bir oturum için zaten Authorization: Bearer kullanıyorsanız, şu şekilde gönderin:

X-Owner-Token: <token>

Sunucu, eski ziyaretçi token’ı + IP yedeklemesine ek olarak owner token’ı geçerli bir sahiplik kanıtı olarak kabul eder — token’ı olan istemciler ağ değiştirince veya çerezleri temizleyince de çalışmaya devam eder; token’ı olmayan istemciler ise eskisi gibi aynen çalışır.

Token’lar, kaynak olduğu sürece yaşar; kalıcı olarak saklamak güvenlidir ve bağımsız olarak süresi dolmaz. Kaybolan bir token, o kaynağın kontrolünü kaybetmek demektir (dosya/koleksiyon/yükleme) — onları yerel şifreler gibi düşünün.

Hatalar

Hatalar tutarlı bir yapıda gelir:

{
  "success": false,
  "error": "Human-readable message"
}

Yaygın HTTP durum kodları:

KodAnlam
200Tamam.
201Oluşturuldu.
400Kötü istek (ör. koleksiyon boyutu sınırı aşıldı).
401Şifre gerekli ya da hatalı.
403Yetkilendirilmedi (kaynağın sahibi değilsiniz).
404Kaynak bulunamadı veya süresi doldu.
422Doğrulama başarısız oldu veya plan/kota kısıtlaması var.
429Oran sınırına (rate limit) takıldı veya yükleme kotası aşıldı.
500Sunucu hatası. durum değerini kontrol edin.

Hız limitleri

Tüm oran sınırları (rate limit) IP başınadır. 429 yanıtı standart Retry-After, X-RateLimit-Limit ve X-RateLimit-Remaining başlıklarını içerir.

KapsamSınır
Yükleme başlat / onayla / iptal et60 / dakika
Multipart tamamlandı500 / dakika
Multipart parça URL’leri120 / dakika
Toplu başlat / onayla500 / dakika
Durum yoklamaları (dosya & koleksiyon)120 / dakika
Ayarlar (şifre, son kullanma, en fazla indirme)30 / dakika
Şifre doğrulama10 / dakika
Koleksiyon oluşturma30 / dakika
Yönet (hazırla, sil)60 / dakika
Küçük resim yükleme120 / dakika
ShareX yükleme20 / gün
Uygulama analitiği / hatalardakikada 120 ve 60

Yükleme kotası: anonim istemciler aynı anda çalışan iki sınıra sahiptir — ziyaretçi token’ı başına 100 GB / 24 sa ve IP başına 500 GB / 24 sa (IP sınırı, belirteksiz trafiği ve paylaşılan ağları yakalar). Bunlardan biri aşıldığında ayrıntılarla birlikte bir 429 alırsın. Bu yalnızca bir yükleme kota — indirmeler sınırsız ve hız kısıtlamasızdır (R2 imzalı URL’lerden doğrudan servis edilir).

Yükle

Her dosya için üç adımlı yükleme akışı; 5 GB’tan büyük dosyalar dahil (otomatik olarak multipart). Sadece hızlı bir ekran görüntüsü tarzı yükleme gerekiyorsa bunun yerine ShareX’e bakın.

POST /upload/init 60/min

Bir yükleme başlatın. 50 MB’tan büyük dosyalarda yanıt multipart yüklemedir (type: "multipart" alanı); aksi halde tek bir presigned PUT.

İstek gövdesi

AlanTürAçıklama
filenamestring · requiredOrijinal dosya adı. En fazla 255 karakter.
content_typestring · requiredMIME türü.
sizeinteger · requiredDosya boyutu (bayt). En az 1.
Request
curl -X POST https://storage.to/api/upload/init \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "filename": "report.pdf", "content_type": "application/pdf", "size": 2202009 }'
Response · single upload
{ "success": true, "type": "single", "upload_url": "https://r2.cloudflarestorage.com/...signed...", "headers": { "Host": ["..."] }, "r2_key": "uuid-abc123" }
Response · multipart
{ "success": true, "type": "multipart", "upload_id": "01HXYZ...", "r2_key": "uuid-abc123", "part_size": 33554432, "total_parts": 4, "initial_urls": { "1": "https://...", "2": "https://..." }, "owner_token": "owner_v1_..." }
POST /upload/parts Owner only 120/min

Devam eden bir multipart yükleme için ek parça URL’leri iste. /init, sahip olduğun parça sayısından daha az URL döndürdüyse (veya URL’ler süresi dolduysa) kullanılır.

İstek gövdesi

AlanTürAçıklama
upload_idstring · required/init içinden gelen upload_id.
part_numbersarray<int> · requiredURL’leri alınacak parça numaraları.
Request
curl -X POST https://storage.to/api/upload/parts \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ...", "part_numbers": [3, 4] }'
Response
{ "success": true, "part_urls": [ { "partNumber": 3, "url": "https://..." }, { "partNumber": 4, "url": "https://..." } ] }
POST /upload/complete-multipart Owner only 500/min

Tüm parçalar yüklendikten sonra R2 üzerinde multipart yüklemeyi tamamla.

İstek gövdesi

AlanTürAçıklama
upload_idstring · required/init içinden gelen upload_id.
partsarray · requiredHer giriş: R2 yanıtındaki { partNumber, etag }.
Request
curl -X POST https://storage.to/api/upload/complete-multipart \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ...", "parts": [ { "partNumber": 1, "etag": "\"abc...\"" }, { "partNumber": 2, "etag": "\"def...\"" } ] }'
Response
{ "success": true }
POST /upload/abort Owner only 60/min

Bir multipart yüklemeyi iptal et ve R2 üzerindeki eksik verileri temizle.

İstek gövdesi

AlanTürAçıklama
upload_idstring · requiredİptal edilecek yükleme.
Request
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
POST /upload/confirm 60/min

Yüklemenin tamamlandığını onayla. Bu aşamada File kaydını oluşturur ve paylaşılabilir URL’yi döndürürüz.

İstek gövdesi

AlanTürAçıklama
filenamestring · requiredOrijinal dosya adı.
sizeinteger · requiredDosya boyutu (bayt).
content_typestring · requiredMIME türü.
r2_keystring · required/init içinden gelen r2_key.
collection_idstring · optionalBir koleksiyona ekle.
crc32integer · optionalBütünlük doğrulaması için CRC32 sağlama toplamı.
file_idstring(9) · optionalDaha önceki ayrılmış dosya ID’sini yerine getir.
Request
curl -X POST https://storage.to/api/upload/confirm \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "filename": "report.pdf", "size": 2202009, "content_type": "application/pdf", "r2_key": "uuid-abc123" }'
Response
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "filename": "report.pdf", "size": 2202009, "human_size": "2.1 MB", "expires_at": "2026-04-15T12:00:00Z" }, "owner_token": "owner_v1_..." }
POST /file/reserve 60/min

Dosya ID’sini ve paylaşılabilir URL’yi :baytlar hazır olmadan önce ayır. Önce bir bağlantı dağıtıp ardından yüklemeyi tamamlaman gerektiğinde işe yarar. Sahiplik, ziyaretçi token’ınız + IP’nize bağlıdır. Yüklemeyi daha sonra /upload/init + /upload/confirm ile bitir; onaylamak için file_id iletin.

İstek gövdesi

AlanTürAçıklama
filenamestring · optionalYer tutucu dosya adı. Varsayılan: "Pending".
content_typestring · optionalYer tutucu MIME türü.
Request
curl -X POST https://storage.to/api/file/reserve \ -H "X-Visitor-Token: abc123"
Response
{ "success": true, "file": { "id": "FQxyz1234", "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "expires_at": "2026-04-12T18:00:00Z" }, "owner_token": "owner_v1_..." }
POST /upload/init-batch 500/min

Web yükleyici için optimize edilmiş /upload/init’in toplu karşılığı. Tek gidiş-dönüşte en fazla 250 dosya başlatır.

Web yükleyici tarafından dahili olarak kullanılır. Çoğu istemci tek dosyalık /upload/init’i tercih etmelidir.

POST /upload/confirm-batch 500/min

/upload/confirm’un toplu karşılığı. Tek gidiş-dönüşte birçok dosyayı onaylar.

Koleksiyonlar

Bir koleksiyon, bir tek paylaşım URL’si (/c/{id}) altında birden fazla dosyayı gruplar. Toplamda en fazla 10.000 dosya ve 25 GB.

POST /collection 30/min

Yeni bir koleksiyon oluştur. Dosyaları daha sonra /upload/confirm üzerinde collection_id ile ileterek ekle.

İstek gövdesi

AlanTürAçıklama
expected_file_countinteger · optionalBeklenen tüm dosyalar onaylandıktan sonra koleksiyonun otomatik olarak hazır işaretlenmesi için ipucu.
Request
curl -X POST https://storage.to/api/collection \ -H "Content-Type: application/json" \ -H "X-Visitor-Token: abc123" \ -d '{ "expected_file_count": 3 }'
Response
{ "success": true, "collection": { "id": "ABC123xyz", "url": "https://storage.to/c/ABC123xyz", "expires_at": "2026-04-15T12:00:00Z" }, "owner_token": "owner_v1_..." }
GET /collection/{id}/status 120/min

Bir koleksiyonun durumunu yokla. Ayrıca beklenen tüm dosyalar onaylandıysa koleksiyonu otomatik olarak hazır işaretler.

Request
curl https://storage.to/api/collection/ABC123xyz/status
Response
{ "success": true, "files": [ /* file objects: id, url, filename, size, ... */ ], "is_uploading": false, "file_count": 3, "expected_file_count": 3, "total_size": 6291456, "human_total_size": "6 MB" }
POST /collection/{id}/ready Owner only 60/min

Koleksiyonu indirmeye hazır olarak işaretle. Genellikle gerekmez — expected_file_count değerine ulaşıldığında koleksiyonlar otomatik olarak hazır olur.

DELETE /collection/{id} Owner only 60/min

Bir koleksiyonu ve tüm dosyalarını sil.

POST /collection/{id}/password Owner only 30/min

Koleksiyona bir parola belirle. 4–100 karakter gerekir.

İstek gövdesi

AlanTürAçıklama
passwordstring · required4–100 karakter.
Request
curl -X POST https://storage.to/api/collection/ABC123xyz/password \ -H "X-Visitor-Token: abc123" \ -d '{ "password": "hunter22" }'
DELETE /collection/{id}/password Owner only 30/min

Koleksiyondaki parolayı kaldır.

POST /collection/{id}/verify-password 10/min

Parolayı kontrol et. Başarılıysa 200, yanlışsa 401 döner.

İstek gövdesi

AlanTürAçıklama
passwordstring · required
POST /collection/{id}/expiry Owner only 30/min

Bir koleksiyonun son kullanma süresini değiştir.

İstek gövdesi

AlanTürAçıklama
daysinteger · optionalŞu andan itibaren 1–7 gün. Kalıcı için atla veya null kullan (yalnızca premium).
POST /collection/{id}/max-downloads Owner only 30/min

Bir indirme limiti belirle (burn-after-N-downloads). Limite ulaşıldığında koleksiyon otomatik olarak silinir.

İstek gövdesi

AlanTürAçıklama
max_downloadsinteger · optional1–1000. Mevcut indirme sayısını aşmalı. Limiti kaldırmak için null.

Dosyalar

Tüm dosya düzeyi ayarlar (parola, son kullanma, max-downloads) koleksiyon uç noktalarını yansıtır. Yalnızca sahip.

GET /file/{id}/status 120/min

Bir dosyanın yüklenmeyi bekleyip beklemediğini kontrol et.

Response
{ "pending": false }
DELETE /file/{id} Owner only 60/min

Bir dosyayı hemen sil.

POST /file/{id}/thumbnail Owner only 120/min

Bir video ya da görsel dosya için küçük resim yükle (indirme sayfasında kullanılır). En fazla 2 MB.

İstek gövdesi

AlanTürAçıklama
thumbnailimage · requiredMultipart yükleme. En fazla 2 MB.
Response
{ "success": true, "thumbnail_url": "https://..." }
POST /file/{id}/password Owner only 30/min

Bir dosyaya parola belirle. 4–100 karakter gerekir.

DELETE /file/{id}/password Owner only 30/min

Bir dosyanın parolasını kaldır.

POST /file/{id}/verify-password 10/min

Bir dosyanın parolasını doğrula.

POST /file/{id}/expiry Owner only 30/min

Bir dosyanın son kullanma süresini değiştir.

İstek gövdesi

AlanTürAçıklama
daysinteger · optionalŞu andan itibaren 1–7 gün. Kalıcı için atla veya null kullan (yalnızca premium).
POST /file/{id}/max-downloads Owner only 30/min

Bir dosyanın toplam indirme sayısını sınırla. Eşiğe ulaşıldığında otomatik olarak silinir.

ShareX yükleme

Tek seferlik yükleme uç noktası — multipart dosya gönder, karşılığında paylaşılabilir bir URL al. init/confirm karmaşası yok. Ekran görüntüsü araçları için ideal. Tam kurulum rehberi: /tr/docs/sharex.

POST /sharex/upload 20/day

Bir görseli ya da dosyayı doğrudan yükle (multipart form, file alanı). En fazla 25 MB.

Request
curl -X POST https://storage.to/api/sharex/upload \ -F "[email protected]"
Response
{ "success": true, "url": "https://storage.to/FQxyz1234", "raw_url": "https://storage.to/r/FQxyz1234", "filename": "screenshot.png", "expires_at": "2026-04-15T12:00:00Z" }

Masaüstü kimlik doğrulama

Sanctum token’ı olan doğrulanmış istemciler için (ör. masaüstü uygulaması).

GET /user Bearer token

Kimliği doğrulanmış kullanıcıyı döndür.

Request
curl https://storage.to/api/user \ -H "Authorization: Bearer <token>"
Response
{ "id": 42, "name": "Ada", "email": "[email protected]", "is_premium": true }
POST /auth/logout Bearer token

Mevcut erişim belirtecini (access token) iptal et.

Diğer

GET /health

Sağlık kontrolü. Veritabanına, R2 depolamaya ve Redis önbelleğine ping atar. Hepsi yeşilse 200, değilse 503 döner.

Response
{ "status": "healthy", "checks": { "database": "ok", "storage": "ok", "cache": "ok" }, "timestamp": "2026-04-12T12:00:00Z" }
GET /activity

Ana sayfadaki dünya için canlı etkinlik akışı. Cloudflare kenarında önbelleğe alınır.

GET /bandwidth/status 60/min

Çağıranın mevcut yükleme kota kullanımı — CLI ve masaüstü uygulaması kalan kapasiteyi göstermek için kullanır. Kimliği doğrulanmış kullanıcılar için yanıt biçimi farklıdır. URL adında geçmesine rağmen bu yalnızca yükleme baytları takip eder; indirmeler sayılmaz.

Response · anonymous
{ "success": true, "authenticated": false, "has_token": true, "limit_bytes": 107374182400, "limit_gb": 100, "used_bytes": 12345678, "used_gb": 0.01, "remaining_bytes": 107361836722, "remaining_gb": 99.99, "window_hours": 24 }
Response · authenticated
{ "success": true, "authenticated": true, "plan": "premium" }
POST /app-analytics 120/min

CLI veya masaüstü uygulamasından bir kullanım olayı gönder.

İstek gövdesi

AlanTürAçıklama
appstring · requireddesktop, cli veya web.
versionstring · optionalİstemci sürümü.
eventstring · requiredOlay adı, ör. upload_complete.
contextobject · optionalEk meta veriler.
POST /app-errors 60/min

CLI veya masaüstü uygulamasından bir hata raporu gönder. Sunucu tarafında yinelenenler kaldırılır — aynı hatadan saatte en fazla 10.

İstek gövdesi

AlanTürAçıklama
appstring · requireddesktop, cli veya web.
typestring · requiredHata sınıfı/türü.
messagestring · requiredHata mesajı.
stackstring · optionalStack trace.
version, os, os_version, arch, contextvarious · optionalTanılama meta verileri.