# رفع الملفات

> ارفع ملفا حتى 95 MB بطلب واحد، أو حتى 2 GB على أجزاء يمكنك إكمالها إذا انقطع الاتصال.

Canonical: https://transcript1.com/ar/docs/uploads
Language: ar
Last updated: 2026-10-14

نستخدم التفريغ الصوتي بالذكاء الاصطناعي لملفات الصوت والفيديو التي ترفعها. اختر `auto` أو `stt` في `source`؛ لا تقبل الملفات خيارا آخر. لإعداد اللغة وتمييز المتحدثين، راجع `language` و`diarize` في [المصادر والخيارات](https://transcript1.com/ar/docs/sources-and-options).

## تحقق من الملف قبل رفعه

نقبل الامتدادات `mp3` و`wav` و`m4a` و`flac` و`ogg` و`opus` و`mp4` و`mov` و`webm` و`mkv`. يجب أن ينتهي اسم الملف بأحدها، وإلا تحصل على `422 unsupported_media`. ويجب أن يحتوي الملف على مسار صوتي؛ غيابه يؤدي إلى `unsupported_media` أيضا.

| طريقة الرفع أو القيد | الحد الأقصى |
|---|---|
| طلب واحد بصيغة `multipart/form-data` | 95 MB |
| ملف مقسم إلى أجزاء | 2 GB، أي 2,000,000,000 بايت. قد يكون حد باقتك أقل. |
| عمليات رفع على أجزاء لم تكتمل بعد، لكل فريق | 20 |

إذا تجاوز الملف الحد، تحصل على `413 media_too_large`. يوضح `max_bytes` في الخطأ الحجم المسموح بالبايت.

## ارفع الملف بطلب واحد

للملف الذي لا يتجاوز 95 MB، استخدم `POST /v1/transcriptions` بصيغة `multipart/form-data`، وضع الملف في الجزء المسمى `file`. يمكنك إضافة حقول النموذج `language` و`diarize` بقيمة `true` أو `false`، و`source` بقيمة `auto` أو `stt`، و`webhook_url`. كلها اختيارية.

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F file=@interview.m4a \
  -F language=en \
  -F diarize=true
```

يعيد API كائن التفريغ مع `source.platform` بقيمة `upload`. كما في روابط الفيديو، يعني `202` أن المعالجة جارية، و`200` أنها وصلت إلى حالة نهائية. إذا كان الملف فارغا، تحصل على `422 invalid_request`.

## ارفع الملف على أجزاء

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

### 1. احجز عملية رفع

ابدأ بإرسال اسم الملف وحجمه في JSON. يمكنك تحديد `mime_type` أيضا. أضف `Idempotency-Key` إلى الترويسات حتى لا تنشئ تفريغا آخر إذا اضطررت إلى تكرار الطلب:

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -H "Idempotency-Key: interview-2026-10-13" \
  -H "Content-Type: application/json" \
  -d '{"upload":{"filename":"interview.m4a","size":48210334,"mime_type":"audio/mp4"},"language":"auto","diarize":true}'
```

تحصل على `201`، وتكون الحالة `awaiting_upload`. يحتوي الحقل `upload` على تفاصيل الرفع:

```json
{
  "id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "object": "transcription",
  "status": "awaiting_upload",
  "upload": {
    "chunk_url_template": "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/chunks/{index}",
    "headers": { "X-Upload-Token": "t1u_..." },
    "expires_at": "2026-10-13T10:30:00.000Z",
    "chunks": [
      { "index": 0, "offset": 0, "size": 8388608 },
      { "index": 1, "offset": 8388608, "size": 8388608 }
    ]
  }
}
```

يحدد الخادم أجزاء الملف ويعيدها في `chunks`؛ القائمة أعلاه مختصرة. حجم الجزء نحو 8 MiB، أي 8,388,608 بايت. احتفظ بسرية `X-Upload-Token`؛ فهو token خاص بهذه العملية وحدها، وصلاحيته ساعة واحدة حتى `expires_at`.

### 2. أرسل أجزاء الملف

لكل جزء، استبدل `{index}` في `chunk_url_template` بقيمة `index` الخاصة به وأرسل `PUT` إلى الرابط. اقرأ من الملف `size` بايت بدءا من `offset`، وأرسل هذه البايتات في body بنوع `application/octet-stream`. يجب أن يطابق الحجم القيمة المحددة تماما. تكفي ترويسة `X-Upload-Token` للمصادقة؛ لا تحتاج إلى `Authorization`.

```bash
curl -X PUT "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/chunks/0" \
  -H "X-Upload-Token: t1u_..." \
  -H "Content-Type: application/octet-stream" \
  --data-binary @chunk-0.bin
```

بعد قبول الجزء، تحصل على رد مثل `{ "object": "upload_chunk", "index": 0, "size": 8388608 }`. إذا أرسلت الجزء نفسه مجددا، يحل محل السابق. يعيد الحجم غير المطابق أو `index` غير الموجود في القائمة `422 invalid_request`. وإذا غاب token أو انتهت صلاحيته، تحصل على `401 unauthorized`.

### 3. أكمل الرفع بعد انقطاعه

لمعرفة الأجزاء التي وصلت، استدع `GET /v1/transcriptions/:id/upload`:

```json
{
  "object": "upload",
  "status": "awaiting_upload",
  "total_bytes": 48210334,
  "uploaded_bytes": 16777216,
  "received_chunks": [0, 1],
  "chunks": [ { "index": 0, "offset": 0, "size": 8388608 } ],
  "expires_at": "2026-10-13T10:30:00.000Z"
}
```

أرسل الأجزاء التي لا تظهر في `received_chunks` فقط. إذا انتهت صلاحية token، أعد طلب الإنشاء في الخطوة 1 بالمعاملات نفسها وقيمة `Idempotency-Key` نفسها. تحصل على التفريغ ذاته مع token رفع جديد.

### 4. أكد اكتمال الرفع

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/complete" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY"
```

يفحص `POST /v1/transcriptions/:id/upload/complete` وصول جميع الأجزاء وأحجامها. ثم يجمع الملف ويضيف التفريغ إلى قائمة الانتظار، ويعيد `202` مع كائن التفريغ. إذا نقصت أجزاء، تحصل على `409 upload_incomplete`؛ أرسل الأجزاء التي يحددها `missing_chunks` مجددا. وإذا أكملت الرفع أو ألغيته من قبل، تحصل على `409 invalid_state`. بعد قبول الملف، تابع الحالة عبر `GET /v1/transcriptions/:id?wait=60` أو استقبل [webhook](https://transcript1.com/ar/docs/webhooks).

### مثال Python من البداية إلى إكمال الرفع

```python
import os
import requests

API = "https://api.transcript1.com"
auth = {"Authorization": f"Bearer {os.environ['TRANSCRIPT1_API_KEY']}"}
path = "interview.m4a"

created = requests.post(
    f"{API}/v1/transcriptions",
    headers={**auth, "Idempotency-Key": "interview-2026-10-13"},
    json={"upload": {"filename": os.path.basename(path), "size": os.path.getsize(path)}},
)
created.raise_for_status()
transcription = created.json()
upload = transcription["upload"]

with open(path, "rb") as file:
    for chunk in upload["chunks"]:
        file.seek(chunk["offset"])
        url = upload["chunk_url_template"].replace("{index}", str(chunk["index"]))
        response = requests.put(
            url,
            data=file.read(chunk["size"]),
            headers={**upload["headers"], "Content-Type": "application/octet-stream"},
        )
        response.raise_for_status()

done = requests.post(f"{API}/v1/transcriptions/{transcription['id']}/upload/complete", headers=auth)
done.raise_for_status()
print(done.json()["status"])
```

## حدود الرفع ومتى نحذف الملف

- لكل فريق 20 عملية رفع مفتوحة بحالة `awaiting_upload` في الوقت نفسه. إذا حاولت فتح المزيد، تحصل على `429 too_many_active_jobs` مع `Retry-After`.
- أكمل الرفع خلال 24 ساعة من إنشائه. بعد ذلك، نلغي العملية ونحذف الأجزاء التي أرسلتها.
- نحذف الملف بعد 24 ساعة من وصول التفريغ إلى `completed` أو `failed` أو `canceled`. يبقى النص المفرغ في حسابك حتى تحذفه عبر `DELETE /v1/transcriptions/:id`.
- بعد معرفة مدة الملف، نحسب أي جزء من الدقيقة كدقيقة كاملة. إذا فشل التفريغ أو ألغيته، لا تدفع شيئا. راجع [الفوترة وحدود الاستخدام](https://transcript1.com/ar/docs/billing-and-limits).
