توثيق API

واجهة REST API لتفريغ الصوت والفيديو. يستخدم العملاء المدفوعون مفتاح API يتم إنشاؤه من إعدادات الحساب لتوثيق التكاملات الخارجية.

عنوان URL الأساسي

https://scribe.uustudio.cc

المصادقة

يجب أن ترسل التكاملات الخارجية مفتاح API لحساب مدفوع في رأس Authorization.

رأس Authorization

Authorization: Bearer {token}

أنشئ المفاتيح وألغها من صفحة مفاتيح API في الإعدادات. نقاط مصادقة التطبيق مخصصة للعملاء الرسميين فقط.

استجابات الخطأ

ترجع جميع الأخطاء جسم JSON مع حقل message .

خطأ قياسي

{
    "message": "Description of the error"
}

خطأ في التحقق (422)

{
    "message": "The name field is required.",
    "errors": {
        "name": ["The name field is required."]
    }
}
الحالةالوصف
401غير مصادق (التوكن مفقود أو غير صالح)
403محظور أو تجاوز حد الخطة
404المورد غير موجود
422فشل التحقق
429محدود المعدل أو عدد كبير جداً من المهام المتزامنة
500خطأ في الخادم الداخلي

حدود المعدل

نقاط نهاية API المصادق عليها محدودة بـ 10 طلبات في الدقيقة لكل توكن.

حدود الاستخدام

توفر API

واجهة REST API الخارجية غير متاحة في الخطة المجانية. قم بالترقية إلى Pro أو Max، أو اشترِ باقة الدفع حسب الاستخدام، لإنشاء مفاتيح API واستخدامها.

الحد الأقصى لحجم الملف
2 GB
المهام المتزامنة
الحد الأقصى 3
الحد الأقصى لإعادة المحاولة لكل مهمة
3

مقارنة الخطط المدفوعة

الميزةPay as you goProMax
الرفع اليوميغير محدودغير محدودغير محدود
صيغ التصديرالكلالكلالكل
أولوية المهمةمتوسطةمتوسطةعالية

سير العمل

رفع ملف صوتي/مرئي

  1. POST /api/uploads/sign → الحصول على upload_id ومعلومات الجزء
  2. PUT {presigned_url} → رفع كل جزء إلى التخزين
  3. POST /api/uploads/complete → إنهاء الرفع، إنشاء تلقائي للمهمة
  4. GET /api/tasks/{id} → استطلاع الحالة (pending -> scribing -> finished)
  5. GET /api/tasks/{id}/download/srt → تصدير (اختياري)

إنشاء مهمة يدوياً

  1. POST /api/tasks → إنشاء بـ disk و path و name
  2. GET /api/tasks/{id} → استطلاع الحالة
  3. GET /api/tasks/{id} → الحصول على segments و summary و mindmap

المصادقة

POST /api/login

المصادقة بالبريد الإلكتروني وكلمة المرور. يرجع توكن Sanctum.

جسم الطلب

الحقلالنوعمطلوبالوصف
emailstringYesبريد المستخدم الإلكتروني (الحد الأقصى 255)
passwordstringYesكلمة مرور المستخدم

الاستجابة 200

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}

محدود بـ 5 محاولات في الدقيقة لكل بريد إلكتروني.

POST /api/register

إنشاء حساب جديد. يرجع توكن Sanctum.

جسم الطلب

الحقلالنوعمطلوبالوصف
namestringYesاسم العرض (الحد الأقصى 255)
emailstringYesبريد إلكتروني فريد (الحد الأقصى 255)
passwordstringYesيجب التأكيد
password_confirmationstringYesتأكيد كلمة المرور

الاستجابة 201

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}
POST /api/auth/social-login

المصادقة عبر Google OAuth. ينشئ حساباً إذا لم يكن موجوداً.

جسم الطلب

الحقلالنوعمطلوبالوصف
providerstringYesgoogle المزودون المدعومون
codestringYesرمز التفويض OAuth

الاستجابة 200

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}
POST /api/logout

إلغاء توكن الوصول الحالي.

الاستجابة 204

لا يرجع جسماً.

المهام

POST /api/tasks

إنشاء مهمة تفريغ. الحد الأقصى 3 مهام متزامنة لكل مستخدم.

جسم الطلب

الحقلالنوعمطلوبالوصف
diskstringYesr2 / remote / youtube معرف مصدر التخزين
namestringYesاسم المهمة (الحد الأقصى 255)
pathstringYesمسار الملف أو عنوان URL المصدر
filestringNoاسم الملف الأصلي (الحد الأقصى 255)
sizeintegerNoحجم الملف بالبايت
durationintegerNoالمدة بالثواني
costintegerNoالتكلفة بالثواني
segmentsarrayNoمقاطع التفريغ
speaker_diarizationbooleanلاapp.tasks.speaker_diarization_api_description

الاستجابة 201

{
    "id": 1,
    "name": "Meeting Recording",
    "status": "pending",
    "speaker_diarization": true,
    "created_at": "2026-03-02T10:30:00+08:00"
}

الأخطاء

الحالةالوصف
403لا يمكن للمستخدمين المجانيين إرسال روابط YouTube عبر API.
429تم الوصول إلى الحد الأقصى للمهام المتزامنة (3)
GET /api/tasks/{id}

الحصول على تفاصيل المهمة الكاملة بما في ذلك نتائج التفريغ.

الاستجابة

{
    "id": 1,
    "name": "Meeting Recording",
    "file": "meeting.mp3",
    "path": "2026-03-02/01HQX...mp3",
    "disk": "r2",
    "size": 50545869,
    "duration": 1965,
    "cost": 33,
    "status": "finished",
    "attempts": 1,
    "quality": 3,
    "created_at": "2026-03-02T10:30:00+08:00",
    "updated_at": "2026-03-02T10:45:00+08:00",
    "summary": "The meeting discussed three topics...",
    "mindmap": "# Topic\n## Sub-topic 1",
    "folder": "Work",
    "tags": ["Work"],
    "url": "https://youtube.com/watch?v=...",
    "segments": [
        {
            "id": 1,
            "start": 0,
            "end": 5000,
            "speaker": "Speaker 1",
            "tokens": ["Okay", "so let's", "begin"],
            "text": "Okay, so let's begin..."
        }
    ],
    "export": {
        "allowed_formats": ["txt", "srt", "vtt", "csv", "pdf", "docx"],
        "heavy_formats": ["pdf", "docx"],
        "version": "20260302104500"
    }
}

حقول الاستجابة

الحقلالنوعالوصف
diskstring|nullقرص التخزين: r2 / remote / youtube
sizeint|nullحجم الملف بالبايت
costint|nullالتكلفة بالثواني
attemptsintعدد إعادة المحاولات
qualityint|nullدرجة الجودة (0-5)
summarystring|nullملخص مولّد بالذكاء الاصطناعي
mindmapstring|nullخريطة ذهنية مولّدة بالذكاء الاصطناعي
folderstring|nullاسم أول وسم (المجلد)
tagsarrayجميع أسماء الوسوم
urlstring|nullعنوان URL المصدر (لمهام YouTube)
segmentsarray|nullمقاطع التفريغ
segments[].startintوقت البدء (مللي ثانية)
segments[].endintوقت الانتهاء (مللي ثانية)
segments[].textstringنص المقطع
segments[].speakerstring|nullمعرف المتحدث
segments[].tokensarray|nullمصفوفة رموز الكلمات
exportobjectالبيانات الوصفية للتصدير (allowed_formats و heavy_formats و version)
GET /api/tasks

معاملات الاستعلام

المعاملالنوعالافتراضيالوصف
statusstringallتصفية حسب الحالة
searchstring—البحث بالاسم
folderstring—تصفية حسب المجلد (أو Uncategorized)
pageint1رقم الصفحة
per_pageint25العناصر لكل صفحة (الحد الأقصى 100)

الاستجابة

{
    "data": [
        {
            "id": 1,
            "name": "Meeting Recording",
            "file": "meeting.mp3",
            "disk": "r2",
            "size": 50545869,
            "duration": 1965,
            "cost": 33,
            "status": "finished",
            "attempts": 1,
            "quality": 3,
            "folder": "Work",
            "created_at": "2026-03-02T10:30:00+08:00"
        }
    ],
    "current_page": 1,
    "last_page": 1,
    "per_page": 25,
    "total": 1
}
PATCH /api/tasks/{id}/retry

إعادة محاولة مهمة فاشلة. يضبط الحالة على pending (R2) أو waiting (remote/YouTube). الحد الأقصى 3 محاولات.

الاستجابة 200

{
    "id": 1,
    "status": "pending",
    "attempts": 2
}
GET /api/tasks/{id}/download/{format}

تصدير التفريغ. الصيغ الخفيفة ترجع الملف مباشرة. الصيغ الثقيلة (pdf/docx) قد ترجع 202 أثناء المعالجة.

معاملات المسار

المعاملالوصف
formattxt / srt / vtt / csv / pdf / docx

الاستجابات

200 - الملف جاهز (صيغ خفيفة)

يرجع ملفاً ثنائياً.

200 - الملف جاهز (صيغ ثقيلة، طلب JSON)

{
    "status": "ready",
    "url": "https://scribe.uustudio.cc/api/tasks/1/download/pdf"
}

202 - جاري معالجة الصيغة الثقيلة

{
    "status": "processing",
    "message": "Your export is being generated. Please try again shortly."
}
GET /api/tasks/{id}/audio

تدفق ملف الصوت أو الفيديو الأصلي مباشرة من التخزين (R2 فقط).

الاستجابة

200 - دفق ثنائي لملف الصوت أو الفيديو. يرجع 404 إذا كان الملف مفقوداً أو غير مخزن على قرص R2.

GET /api/tasks/{id}/refresh-summary

تحديث وإرجاع أحدث ملخص وخريطة ذهنية مولّدَين بالذكاء الاصطناعي.

الاستجابة

{
    "summary": "The meeting discussed three topics...",
    "mindmap": "# Topic\n## Sub-topic 1"
}
GET /api/tasks/{id}/share-url

Get or generate a public share URL for the task.

الاستجابة

{
    "share_url": "https://scribe.uustudio.cc/share/tasks/1"
}
PATCH /api/tasks/{id}

تحديث حقول المهمة. جميع الحقول اختيارية.

جسم الطلب

الحقلالنوعالوصف
namestringالاسم الجديد (الحد الأقصى 255)
folderstring|nullاسم المجلد (null يزيل المهمة من مجلد)
durationintegerالمدة بالثواني
costintegerالتكلفة بالثواني
segmentsarrayمصفوفة المقاطع الكاملة للاستبدال
textstringنص التفريغ الكامل
qualityintegerدرجة الجودة (0-5)
indexintegerفهرس ترتيب المهمة

الاستجابة 200

يرجع كائن المهمة الكامل (نفس تفاصيل المهمة).

DELETE /api/tasks/{id}

Response 200

{
    "message": "Task deleted successfully"
}
DELETE /api/tasks/bulk

حذف مهام متعددة دفعة واحدة. سيتم حذف المهام التابعة للمستخدم المصادق عليه فقط. يتم تجاهل المعرفات التي لا تنتمي للمستخدم.

جسم الطلب

الحقلالنوعمطلوبالوصف
idsarrayYesمصفوفة من معرّفات المهام للحذف (1 كحد أدنى)

الاستجابة 200

{
    "message": "2 task(s) deleted successfully",
    "deleted_count": 2
}
PATCH /api/tasks/bulk/move

نقل مهام متعددة إلى مجلد دفعة واحدة. سيتم نقل المهام التابعة للمستخدم المصادق عليه فقط.

جسم الطلب

الحقلالنوعمطلوبالوصف
idsarrayYesمصفوفة من معرّفات المهام للنقل (1 كحد أدنى)
folderstringYesاسم المجلد الهدف (الحد الأقصى 255)

الاستجابة 200

{
    "message": "2 task(s) moved to Work",
    "moved_count": 2
}

الرفع

الرفع متعدد الأجزاء
POST /api/uploads/sign

جسم الطلب

الحقلالنوعمطلوبالوصف
filestringYesاسم الملف (يجب استخدام صيغة مدعومة)
content_typestringYesنوع MIME (يجب أن يطابق امتداد الملف)
sizeintegerYesحجم الملف بالبايت (الحد الأقصى 2,147,483,648 / 2 GB)
durationintegerNoمدة الصوت بالثواني

الاستجابة

{
    "path": "2026-03-02/01HQX...mp3",
    "upload_id": "abc123",
    "part_size": 5242880,
    "part_count": 10,
    "expires_at": "2026-03-02T10:40:00+08:00"
}
POST /api/uploads/sign-part

جسم الطلب

الحقلالنوعمطلوبالوصف
pathstringYesمسار الرفع (الحد الأقصى 2048)
upload_idstringYesمعرف الرفع (الحد الأقصى 2048)
part_numberintegerYesرقم الجزء (1-10000)

الاستجابة

{
    "url": "https://storage.example.com/...?X-Amz-...",
    "headers": {
        "Content-Type": "audio/mpeg"
    }
}

استخدم PUT مع عنوان URL والرؤوس المرجعة لرفع الجزء.

POST /api/uploads/complete

إكمال رفع متعدد الأجزاء. ينشئ هذا مهمة تفريغ تلقائياً ويرجع 403 عندما تكون API غير متاحة أو يتم تجاوز حد الخطة.

جسم الطلب

الحقلالنوعمطلوبالوصف
pathstringYesمسار الرفع (الحد الأقصى 2048)
upload_idstringYesمعرف الرفع (الحد الأقصى 2048)
original_namestringYesاسم الملف الأصلي (يجب استخدام صيغة مدعومة)
content_typestringYesنوع MIME (يجب أن يطابق امتداد الملف)
sizeintegerYesحجم الملف بالبايت (الحد الأقصى 2 GB)
namestringNoاسم المهمة (الافتراضي اسم الملف بدون امتداد)
durationintegerNoالمدة بالثواني (الحد الأدنى 1)
speaker_diarizationbooleanلاapp.tasks.speaker_diarization_api_description

الاستجابة 201

{
    "message": "File uploaded to the upload server successfully.",
    "task": {
        "id": 1,
        "name": "meeting",
        "path": "2026-03-02/01HQX...mp3",
        "size": 50545869,
        "status": "pending",
        "speaker_diarization": true
    }
}
POST /api/uploads/abort

جسم الطلب

الحقلالنوعمطلوبالوصف
pathstringYesمسار الرفع (الحد الأقصى 2048)
upload_idstringYesمعرف الرفع (الحد الأقصى 2048)

الاستجابة

{
    "message": "Multipart upload cancelled successfully."
}

المجلدات

مستند بالوسوم
GET /api/folders

سرد جميع المجلدات مع أعداد المهام.

الاستجابة

{
    "folders": [
        {"id": 1, "name": "Work", "count": 5},
        {"id": 2, "name": "Personal", "count": 3}
    ],
    "uncategorized_count": 2,
    "total_count": 10
}
POST /api/folders

جسم الطلب

الحقلالنوعمطلوبالوصف
namestringYesاسم المجلد (الحد الأقصى 14 حرفاً / 7 أحرف صينية، فريد لكل مستخدم)

الاستجابة 201

{
    "id": 1,
    "name": "Work"
}
PATCH /api/folders/{name}

جسم الطلب

الحقلالنوعمطلوبالوصف
namestringYesاسم المجلد الجديد (نفس قيود الإنشاء)

الاستجابة 200

{
    "id": 1,
    "name": "New Name"
}
DELETE /api/folders/{name}

Response 200

{
    "message": "Folder deleted successfully"
}

المستخدم

GET /api/user

الاستجابة

{
    "id": 1,
    "name": "Zhang San",
    "email": "[email protected]",
    "avatar": "https://...",
    "balance": {
        "used_seconds": 9000,
        "remaining_seconds": 36000,
        "allowance_remaining_seconds": 30000,
        "top_up_remaining_seconds": 6000,
        "total_seconds": 45000,
        "usage_percent": 20
    },
    "subscription": {
        "plan": "year",
        "plan_key": "max_yearly",
        "tier": "max",
        "billing_interval": "yearly",
        "active": true,
        "access_tier": "max"
    },
    "queue": {
        "pending_count": 1,
        "running_count": 1,
        "failed_count": 0
    }
}

حقول الرصيد

الحقلالنوعالوصف
used_secondsintالثواني المستخدمة منذ آخر منحة شهرية
remaining_secondsintالثواني المتبقية
total_secondsintإجمالي الثواني
usage_percentintنسبة الاستخدام (0-100)
PUT /api/user

جسم الطلب

الحقلالنوعمطلوبالوصف
namestringNoاسم العرض (الحد الأقصى 255)
emailstringلاالبريد الإلكتروني الجديد (يجب أن يكون فريداً)
avatarfileNoملف صورة (الحد الأقصى 5 MB)

الاستجابة 200

{
    "id": 1,
    "name": "New Name",
    "email": "[email protected]",
    "avatar": "https://..."
}

الإشعارات

GET /api/notifications

الحصول على آخر 10 إشعارات.

الاستجابة

[
    {
        "id": "abc123",
        "title": "Task Completed",
        "message": "Meeting Recording has been transcribed.",
        "read_at": null,
        "created_at": "2026-03-02T10:45:00+08:00"
    }
]
POST /api/notifications/mark-all-as-read

تحديد جميع الإشعارات غير المقروءة كمقروءة.

Response 200

{
    "success": true
}

الدفع

GET /api/checkout/{plan}

الحصول على رابط دفع Paddle لخطة اشتراك.

معاملات المسار

المعاملالوصف
plantest / month / year

الاستجابة

يرجع كائن خيارات الدفع من Paddle. يرجع 404 لخطة غير صالحة.

GET /api/health

نقطة نهاية فحص الصحة العامة. لا تتطلب مصادقة.

الاستجابة 200

{
    "status": "ok"
}