REST API

ارفع الملفات، أنشئ مجموعات، وادِر المشاركات عبر HTTP. جميع الردود بصيغة JSON؛ لا حاجة لمفتاح API للرفع المجهول.

مقدمة

توفر API الخاصة بـ storage.to الطاقة لـ CLI، تطبيق سطح المكتب، رافع الويب، وأي عميل طرف ثالث ترغب في بنائه.

تتكون عملية الرفع من ثلاث خطوات:

  1. التهيئة — أخبرنا أنك تريد رفع ملف. نُعيد رابطًا أو أكثر مسبق التوقيع يشير إلى Cloudflare R2.
  2. ارفع إلى R2 — :ضع بياناتك مباشرة إلى عنوان URL الموقع مسبقًا. البيانات لا تمر عبر خوادمنا.
  3. التأكيد — أخبرنا أن الرفع انتهى. ننشئ سجل File ونزودك برابط قابل للمشاركة.

الرابط الأساسي

https://storage.to/api

جميع نقاط النهاية أدناه نسبية لهذا الرابط الأساسي. مثال: POST /upload/init تعني POST https://storage.to/api/upload/init.

المصادقة

معظم نقاط النهاية لا تتطلب توثيقًا. الرفع المجهول هو ميزة أساسية.

المصادقة اختيارية وتفتح:

  • الملفات المرفقة بحسابك (مرئية في /dashboard)
  • ميزات مميزة (ملفات دائمة، تخزين أكبر)
  • تعديلات قائمة على الملكية (حذف، تعيين كلمة مرور، تغيير انتهاء الصلاحية) بدون الحاجة لمطابقة رمز الزائر

نستخدم رموز حامل Laravel Sanctum. اصدر رمزًا عبر تسليم OAuth في سطح المكتب أو تسجيل الدخول عبر الويب، ثم أرسله كالتالي:

Authorization: Bearer <token>

رمز الزائر

يحتاج العملاء المجهولون إلى طريقة لإثبات ملكيتهم لملفاتهم المرفوعة بدون حساب. نستخدم رمز الزائر — سلسلة عشوائية ينشئها العميل مرة واحدة ويعيد استخدامها. أرسلها مع كل طلب:

X-Visitor-Token: <random-string>

على الويب، يُخزن الرمز تلقائيًا في ملف تعريف الارتباط visitor_token. يخزنه CLI في ~/.config/storageto/token (انظر وثائق CLI).

لنقاط النهاية الخاصة بالتعديلات (حذف، تعيين كلمة مرور، تغيير انتهاء الصلاحية)، يتم تأكيد الملكية إذا إما رمز الزائر يطابق أو الطلب يأتي من نفس عنوان IP الذي أنشأ الملف.

الأخطاء

تتبع الأخطاء نمطًا موحدًا:

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

رموز حالة HTTP الشائعة:

الرمزالمعنى
200تم بنجاح.
201تم الإنشاء.
400طلب غير صالح (مثلاً تجاوز حد حجم المجموعة).
401كلمة المرور مطلوبة أو غير صحيحة.
403غير مصرح (لست مالك المورد).
404المورد غير موجود أو منتهي الصلاحية.
422فشل التحقق، أو تقييد الخطة/الحصة.
429تم الوصول إلى حد المعدل أو حصة الرفع.
500خطأ في الخادم. تحقق من الحالة.

حدود المعدل

جميع حدود المعدل لكل عنوان IP. استجابة 429 تتضمن رؤوس Retry-After و X-RateLimit-Limit و X-RateLimit-Remaining القياسية.

النطاقالحد
بدء التحميل / التأكيد / الإلغاء60 / دقيقة
إكمال التحميل متعدد الأجزاء500 / دقيقة
روابط أجزاء التحميل متعدد الأجزاء120 / دقيقة
بدء الدفعة / التأكيد500 / دقيقة
استطلاعات الحالة (ملف ومجموعة)120 / دقيقة
الإعدادات (كلمة المرور، انتهاء الصلاحية، الحد الأقصى للتحميلات)30 / دقيقة
التحقق من كلمة المرور10 / دقيقة
إنشاء مجموعة30 / دقيقة
الإدارة (جاهز، حذف)60 / دقيقة
رفع الصورة المصغرة120 / دقيقة
رفع عبر ShareX20 / يوم
تحليلات التطبيق / الأخطاء120 و 60 / دقيقة

حصة الرفع: العملاء المجهولون لديهم حدان يعملان بالتوازي — 100 جيجابايت / 24 ساعة لكل رمز الزائر و 500 جيجابايت / 24 ساعة لكل IP (حد IP يلتقط حركة المرور بدون رمز والشبكات المشتركة). عند تجاوز أي منهما ستحصل على 429 مع التفاصيل. هذا هو حد رفع فقط — التنزيلات غير محدودة وغير مقيدة (تُقدم مباشرة من عناوين R2 الموقعة).

رفع

عملية الرفع ثلاثية الخطوات لأي ملف، بما في ذلك الملفات التي تزيد عن 5 جيجابايت (متعددة الأجزاء تلقائيًا). إذا كنت تحتاج فقط إلى رفع سريع على شكل لقطة شاشة، راجع ShareX بدلاً من ذلك.

POST /upload/init 60/min

ابدأ رفعًا. للملفات التي تزيد عن 50 ميجابايت، تتضمن الاستجابة part_urls لرفع متعدد الأجزاء؛ وإلا رابط واحد url.

محتوى الطلب

الحقلالنوعالوصف
filenamestring · requiredاسم الملف الأصلي. الحد الأقصى 255 حرفًا.
content_typestring · requiredنوع MIME.
sizeinteger · requiredحجم الملف بالبايت. الحد الأدنى 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, "url": "https://r2.cloudflarestorage.com/...signed...", "r2_key": "uuid-abc123", "upload_id": null, "is_multipart": false }
Response · multipart
{ "success": true, "upload_id": "01HXYZ...", "r2_key": "uuid-abc123", "is_multipart": true, "part_size": 52428800, "part_urls": [ { "partNumber": 1, "url": "https://..." }, { "partNumber": 2, "url": "https://..." } ] }
POST /upload/parts 120/min

اطلب روابط أجزاء إضافية لرفع متعدد الأجزاء قيد التنفيذ. يُستخدم عندما يرجع /init روابط أقل من عدد الأجزاء لديك (أو انتهت صلاحيتها).

محتوى الطلب

الحقلالنوعالوصف
upload_idstring · requiredupload_id من /init.
part_numbersarray<int> · requiredأرقام الأجزاء للحصول على روابط لها.
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 500/min

إنهاء رفع متعدد الأجزاء على R2 بمجرد رفع جميع الأجزاء.

محتوى الطلب

الحقلالنوعالوصف
upload_idstring · requiredupload_id من /init.
partsarray · requiredكل إدخال: { partNumber, etag } من استجابة R2.
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 60/min

إلغاء رفع متعدد الأجزاء وتنظيف أي بيانات جزئية على R2.

محتوى الطلب

الحقلالنوعالوصف
upload_idstring · requiredالرفع الذي سيتم إلغاؤه.
Request
curl -X POST https://storage.to/api/upload/abort \ -H "Content-Type: application/json" \ -d '{ "upload_id": "01HXYZ..." }'
POST /upload/confirm 60/min

تأكيد اكتمال الرفع. عندها نقوم بإنشاء سجل File وإرجاع الرابط القابل للمشاركة.

محتوى الطلب

الحقلالنوعالوصف
filenamestring · requiredاسم الملف الأصلي.
sizeinteger · requiredحجم الملف بالبايت.
content_typestring · requiredنوع MIME.
r2_keystring · requiredr2_key من /init.
collection_idstring · optionalالإرفاق بمجموعة.
crc32integer · optionalمجموع تحقق CRC32 للتحقق من السلامة.
file_idstring(9) · optionalإتمام ملف معرفه محجوز سابقًا.
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" } }
POST /file/reserve 60/min

احجز معرف ملف ورابط قابل للمشاركة قبل جاهزية البيانات. مفيد عندما تحتاج إلى إعطاء رابط أولاً وإتمام الرفع لاحقًا. الملكية مرتبطة برمز الزائر + IP الخاص بك. أكمل الرفع لاحقًا باستخدام /upload/init + /upload/confirm، مع تمرير file_id للتأكيد.

محتوى الطلب

الحقلالنوعالوصف
filenamestring · optionalاسم ملف نائب. الافتراضي هو "Pending".
content_typestring · optionalنوع MIME نائب.
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" } }
POST /upload/init-batch 500/min

معادل الدُفعة لـ /upload/init، مُحسّن لواجهة الويب للتحميل. يبدأ حتى 250 ملفًا في جولة واحدة.

يُستخدم داخليًا بواسطة واجهة الويب للتحميل. يفضل معظم العملاء استخدام /upload/init لملف واحد.

POST /upload/confirm-batch 500/min

معادل الدُفعة لـ /upload/confirm. يؤكد العديد من الملفات في جولة واحدة.

المجموعات

المجموعة تجمع عدة ملفات تحت رابط مشاركة واحد (/c/{id}). حتى 10,000 ملف و25 جيجابايت إجمالاً.

POST /collection 30/min

أنشئ مجموعة جديدة. أرفق الملفات لاحقًا بتمرير collection_id على /upload/confirm.

محتوى الطلب

الحقلالنوعالوصف
expected_file_countinteger · optionalتلميح لوضع علامة تلقائية على المجموعة بأنها جاهزة بمجرد تأكيد جميع الملفات المتوقعة.
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" } }
GET /collection/{id}/status 120/min

استعلم عن حالة المجموعة. كما يضع علامة تلقائية على المجموعة بأنها جاهزة إذا تم تأكيد جميع الملفات المتوقعة.

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

وضع علامة على المجموعة بأنها جاهزة للتحميل. عادةً غير مطلوب — المجموعات تصبح جاهزة تلقائيًا عند الوصول إلى expected_file_count.

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

احذف مجموعة وجميع ملفاتها.

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

اضبط كلمة مرور على المجموعة. يتطلب من 4 إلى 100 حرف.

محتوى الطلب

الحقلالنوعالوصف
passwordstring · requiredمن 4 إلى 100 حرف.
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

أزل كلمة المرور من المجموعة.

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

تحقق من كلمة المرور. يعيد 200 عند النجاح، و401 عند كلمة مرور غير صحيحة.

محتوى الطلب

الحقلالنوعالوصف
passwordstring · required
POST /collection/{id}/expiry Owner only 30/min

غيّر انتهاء صلاحية المجموعة.

محتوى الطلب

الحقلالنوعالوصف
daysinteger · optionalمن 1 إلى 7 أيام من الآن. اتركها فارغة أو استخدم null للمدة الدائمة (للمميزين فقط).
POST /collection/{id}/max-downloads Owner only 30/min

حدد حدًا للتحميل (حذف بعد N تحميلات). تُحذف المجموعة تلقائيًا عند الوصول للحد.

محتوى الطلب

الحقلالنوعالوصف
max_downloadsinteger · optionalمن 1 إلى 1000. يجب أن يتجاوز عدد التنزيلات الحالي. استخدم null لإزالة الحد.

الملفات

جميع إعدادات الملف (كلمة المرور، الانتهاء، الحد الأقصى للتحميلات) تعكس نقاط نهاية المجموعة. مخصصة للمالك فقط.

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

تحقق مما إذا كان الملف لا يزال في انتظار التحميل.

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

احذف ملفًا فورًا.

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

حمّل صورة مصغرة لفيديو أو ملف صورة (تُستخدم في صفحة التنزيل). الحد الأقصى 2 ميجابايت.

محتوى الطلب

الحقلالنوعالوصف
thumbnailimage · requiredتحميل متعدد الأجزاء. الحد الأقصى 2 ميجابايت.
Response
{ "success": true, "thumbnail_url": "https://..." }
POST /file/{id}/password Owner only 30/min

اضبط كلمة مرور على ملف. يتطلب من 4 إلى 100 حرف.

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

أزل كلمة مرور الملف.

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

تحقق من كلمة مرور الملف.

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

غيّر انتهاء صلاحية الملف.

محتوى الطلب

الحقلالنوعالوصف
daysinteger · optionalمن 1 إلى 7 أيام من الآن. اتركها فارغة أو استخدم null للمدة الدائمة (للمميزين فقط).
POST /file/{id}/max-downloads Owner only 30/min

حدد حدًا إجماليًا لتحميلات الملف. يُحذف تلقائيًا عند الوصول.

رفع عبر ShareX

نقطة تحميل لمرة واحدة — أرسل ملفًا متعدد الأجزاء، واحصل على رابط قابل للمشاركة فورًا. لا حاجة لخطوات بدء/تأكيد. مثالي لأدوات لقطة الشاشة. دليل الإعداد الكامل على /ar/docs/sharex.

POST /sharex/upload 20/day

حمّل صورة أو ملفًا مباشرة (نموذج متعدد الأجزاء، حقل file). الحد الأقصى 25 ميجابايت.

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" }

مصادقة سطح المكتب

للعملاء الموثقين (مثل تطبيق سطح المكتب) الذين يحملون رمز Sanctum.

GET /user Bearer token

إرجاع المستخدم الموثق.

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

إلغاء رمز الوصول الحالي.

متفرقات

GET /health

فحص الحالة. يتحقق من قاعدة البيانات، تخزين R2، وذاكرة Redis المؤقتة. يعيد 200 إذا كان كل شيء جيدًا، و503 خلاف ذلك.

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

تدفق نشاط مباشر لرمز الكرة في الصفحة الرئيسية. مخزن مؤقت على حافة Cloudflare.

GET /bandwidth/status 60/min

استخدام حصة التحميل الحالية للمتصل — يستخدمه CLI وتطبيق سطح المكتب لعرض السعة المتبقية. شكل الاستجابة يختلف للمستخدمين الموثقين. رغم اسم الرابط، هذا يتتبع فقط رفع بايت؛ التنزيلات غير محسوبة.

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

أرسل حدث استخدام من واجهة الأوامر أو تطبيق سطح المكتب.

محتوى الطلب

الحقلالنوعالوصف
appstring · requireddesktop، cli، أو web.
versionstring · optionalإصدار العميل.
eventstring · requiredاسم الحدث، مثلاً upload_complete.
contextobject · optionalبيانات وصفية إضافية.
POST /app-errors 60/min

أرسل تقرير خطأ من واجهة الأوامر أو تطبيق سطح المكتب. يتم إزالة التكرار على الخادم — بحد أقصى 10 من نفس الخطأ في الساعة.

محتوى الطلب

الحقلالنوعالوصف
appstring · requireddesktop، cli، أو web.
typestring · requiredفئة/نوع الخطأ.
messagestring · requiredرسالة الخطأ.
stackstring · optionalتتبع المكدس.
version, os, os_version, arch, contextvarious · optionalبيانات وصفية تشخيصية.