مرجع API
نقاط النهاية والحقول والاستجابات والأرصدة والحدود والأخطاء.
آخر تحديث
كيف يعمل#
يُنشأ كل نص مفرّغ عبر مهمة. ترسل مصدرًا، فتعمل المهمة في الخلفية، وعند نجاحها تشير إلى نص مفرّغ يمكنك قراءته أو تصديره متى شئت. عنوان URL الأساسي: https://www.transcriptdock.com. جميع الطلبات والردود بصيغة JSON.
# 1. Submitcurl -X POST https://www.transcriptdock.com/v1/jobs \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: video-7680721699171601694" \-H "Content-Type: application/json" \-d '{ "source": { "url": "https://www.tiktok.com/@tiktok/video/7680721699171601694" }, "mode": "captions_only" }'# 2. Wait (returns as soon as the job finishes, up to 25 s per call)curl "https://www.transcriptdock.com/v1/jobs/11111111-1111-4111-8111-111111111111?wait=25" \-H "Authorization: Bearer td_live_YOUR_KEY"# 3. Exportcurl "https://www.transcriptdock.com/v1/transcripts/22222222-2222-4222-8222-222222222222/export?format=srt" \-H "Authorization: Bearer td_live_YOUR_KEY"
المصادقة#
أنشئ المفاتيح من صفحة مفاتيح API. يظهر المفتاح مرة واحدة فقط، ويبدأ بـ td_live_...، ويُرسل في ترويسة Authorization مع كل طلب. تحمل المفاتيح صلاحيات تختارها عند إنشائها: jobs:read و jobs:write و transcripts:read و uploads:write. أنشئ مفتاحًا لكل تكامل، حتى تتمكن من إلغاء أحدها وحده.
Authorization: Bearer td_live_YOUR_KEY
Idempotency-Key#
مطلوب في POST /v1/jobs، و /v1/batches، و /v1/jobs/{id}/retry، و /v1/video-discoveries، و /v1/language-discoveries: أي سلسلة من 8 إلى 128 حرفًا ASCII قابلًا للطباعة. إرسال المفتاح نفسه مع محتوى الطلب نفسه خلال 48 ساعة يعيد الكائن الأصلي، فلا ينشئ الطلب المعاد إرساله شيئًا جديدًا ولا يُحتسب مرتين. وإرسال المفتاح نفسه مع محتوى مختلف يعيد 409 IDEMPOTENCY_CONFLICT. والمفتاح الجيد هو معرّفك الخاص بالشيء الذي تفرّغه.
X-Request-Id#
تحمل كل استجابة هذا المعرّف. اذكره عند التواصل مع الدعم.
نقاط النهاية#
| الطريقة | المسار | الوظيفة | الأرصدة |
|---|---|---|---|
| POST | /v1/jobs | تفريغ فيديو أو ملف أو رابط واحد | رصيد واحد لكل نص من الترجمات، ورصيدان لكل دقيقة تفريغ بالذكاء الاصطناعي |
| GET | /v1/jobs/{id} | حالة المهمة، مع انتظار يصل إلى 25 ثانية | مجاني |
| GET | /v1/jobs | سجل المهام | مجاني |
| POST | /v1/jobs/{id}/cancel | إلغاء مهمة في الانتظار | مجاني |
| POST | /v1/jobs/{id}/retry | إعادة محاولة مهمة فاشلة | كمهمة جديدة |
| POST | /v1/batches | تفريغ عدة فيديوهات (حسب حجم الدفعة في خطتك) | لكل عنصر، كما سبق |
| GET | /v1/batches/{id} | حالة الدفعة | مجاني |
| GET | /v1/transcripts/{id} | النص المفرّغ بصيغة JSON | مجاني |
| GET | /v1/transcripts/{id}/export | ملف txt أو srt أو vtt أو json | مجاني |
| DELETE | /v1/transcripts/{id} | حذف نص مفرّغ | مجاني |
| POST | /v1/uploads | الحصول على رابط لرفع ملف | مجاني |
| POST | /v1/uploads/{id}/complete | وضع علامة على اكتمال الرفع | مجاني |
| POST | /v1/video-discoveries | البحث في YouTube، أو عرض قناة أو قائمة تشغيل أو ملف TikTok شخصي | 1 لكل صفحة |
| GET | /v1/video-discoveries/{id} | نتيجة البحث عن الفيديوهات | مجاني |
| POST | /v1/language-discoveries | عرض لغات ترجمات فيديو YouTube | 1 |
| GET | /v1/language-discoveries/{id} | قائمة اللغات | مجاني |
| POST | /v1/webhook-endpoints | تسجيل عنوان Webhook (داخل جلسة تسجيل دخول) | مجاني |
| GET | /v1/webhook-endpoints | عرض عناوين Webhook | مجاني |
| DELETE | /v1/webhook-endpoints/{id} | تعطيل عنوان Webhook (داخل جلسة تسجيل دخول) | مجاني |
| GET | /v1/usage | الأرصدة والخطة | مجاني |
| GET | /v1/capabilities | ما يمكن لمفتاحك فعله | مجاني |
إنشاء مهمة#
/v1/jobsيُعيد 202 مع المهمة. وإذا كانت مساحة العمل تملك نصًا مفرّغًا للفيديو نفسه وبالخيارات نفسها، فإنه يُعيد 200 مع مهمة ناجحة مجانًا (billing.kind: "cached").
{"id": "11111111-1111-4111-8111-111111111111","status": "queued","stage": "resolve","result_id": null,"error": null,"billing": { "credits_reserved": 2, "credits_charged": 0, "kind": "captions" },"source": { "platform": "tiktok", "media_id": "7680721699171601694", "canonical_url": "https://www.tiktok.com/@tiktok/video/7680721699171601694", "title": null, "upload_id": null },"options": { "mode": "auto", "language": null, "caption_preference": "prefer_creator" },"created_at": "2026-09-16T10:00:00.000Z"}
كائن المهمة#
استعلام عن مهمة#
/v1/jobs/{id}?wait=25يُعيد المهمة. ومع wait (من 0 إلى 25 ثانية) يبقى الطلب مفتوحًا، ويعود فور انتهاء المهمة، فيغني استدعاء واحد عن حلقة الاستعلام المتكرر. ولطلبات القراءة حد خاص به، وهو 120 طلبًا في الدقيقة.
عرض المهام#
/v1/jobs?limit=20&cursor=من الأحدث إلى الأقدم، و limit من 1 إلى 100. مرّر القيمة next_cursor من الاستجابة إلى cursor لجلب الصفحة التالية. أضف platform و source_id (وهو source.media_id للمهمة) معًا لعرض المهام الخاصة بفيديو واحد فقط، في أي وضع. بهذه الطريقة يتحقق العميل من وجود نص مفرّغ لدى مساحة العمل قبل إرسال الفيديو من جديد.
إلغاء مهمة#
/v1/jobs/{id}/cancelيلغي مهمة لم تبدأ التفريغ بالذكاء الاصطناعي بعد، ويُفكّ الحجز المرتبط بها. وبعد ذلك يُعيد 409 CANCELLATION_NOT_ALLOWED وتكتمل المهمة.
إعادة محاولة مهمة#
/v1/jobs/{id}/retryينشئ مهمة جديدة من مهمة فاشلة كان خطؤها retryable. يتطلب Idempotency-Key جديدًا، ويقبل محتوى اختياريًا { "max_credits": 40 }. وتُسعَّر كمهمة جديدة. أما الأخطاء النهائية (مثل فيديو خاص أو عدم وجود ترجمات) فيُعاد معها 409 JOB_NOT_RETRYABLE: صحّح المدخل ثم أرسل الطلب من جديد.
النص المفرّغ#
/v1/transcripts/{id}{"id": "22222222-2222-4222-8222-222222222222","source": { "platform": "youtube", "media_id": "dQw4w9WgXcQ", "canonical_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "title": "Never Gonna Give You Up" },"source_origin": "creator_captions","language": "en","text": "Never gonna give you up. Never gonna let you down.","segments": [{ "start": 0, "end": 2.4, "text": "Never gonna give you up" },{ "start": 2.4, "end": 4.9, "text": "Never gonna let you down" }],"words": null,"timing_granularity": "segment","duration_seconds": 212.0,"recognition": null,"extraction_version": "worker-0.1.0","created_at": "2026-09-16T10:00:14.000Z"}
تُحفظ النصوص المفرّغة طوال مدة الاحتفاظ في خطتك: 7 أيام في التجربة، و30 يومًا في Starter، و90 يومًا في Pro وScale. ويمكنك حذف نص قبل ذلك عبر DELETE /v1/transcripts/{id}.
تصدير نص مفرّغ#
/v1/transcripts/{id}/export?format=srt| format | ما تحصل عليه |
|---|---|
| txt | نص عادي، مقطع واحد في كل سطر. |
| srt | ترجمات بصيغة SubRip. |
| vtt | ترجمات بصيغة WebVTT. |
| json | كائن النص المفرّغ أعلاه. |
مجاني وبلا حد. تحتاج srt و vtt إلى التوقيتات، والنص الذي لا يحتوي عليها يُعيد 422 TIMESTAMPS_UNAVAILABLE.
الدفعات#
/v1/batchesطلب واحد لعدة فيديوهات. لكل عنصر الحقول نفسها الموجودة في إنشاء مهمة، ويُقبل الطلب كله أو يُرفض كله معًا. عدد العناصر في الدفعة: 1 في التجربة، و10 في Starter، و25 في Pro، و50 في Scale.
curl -X POST https://www.transcriptdock.com/v1/batches \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: playlist-2026-09-16" \-H "Content-Type: application/json" \-d '{ "items": [{ "source": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }, "mode": "captions_only" },{ "source": { "url": "https://www.tiktok.com/@tiktok/video/7680721699171601694" }, "mode": "captions_only" }] }'
لكائن الدفعة status (queued و processing و succeeded و partial_success و failed و cancelled)، وأعداد (total_items، و succeeded_items و failed_items و cancelled_items)، و items، ولكل عنصر job_id خاص به. اقرأه عبر GET /v1/batches/{id}، فكل عنصر مهمة عادية.
رفع الملفات#
ملفاتك الصوتية أو المرئية (mp3 وwav وm4a وogg وaac وmp4 وwebm، بحد أقصى 250 ميغابايت ومدة ساعتين). احجز مكانًا، ثم أرسل الملف بطريقة PUT إلى الرابط الموقّع، وضع علامة على اكتماله، ثم أرسله كمهمة باستخدام source.upload_id. تُفرَّغ الملفات المرفوعة دائمًا بالذكاء الاصطناعي.
# 1. Reservecurl -X POST https://www.transcriptdock.com/v1/uploads \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Content-Type: application/json" \-d '{ "filename": "interview.mp3", "content_type": "audio/mpeg", "bytes": 48213920 }'# -> { "id": "33333333-...", "signed_upload_url": "https://...", "expires_at": "...", "status": "pending" }# 2. Upload the bytes (same Content-Type you declared)curl -X PUT "SIGNED_UPLOAD_URL" -H "Content-Type: audio/mpeg" --data-binary @interview.mp3# 3. Completecurl -X POST https://www.transcriptdock.com/v1/uploads/33333333-3333-4333-8333-333333333333/complete \-H "Authorization: Bearer td_live_YOUR_KEY"# 4. Transcribe itcurl -X POST https://www.transcriptdock.com/v1/jobs \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: interview-01" \-H "Content-Type: application/json" \-d '{ "source": { "upload_id": "33333333-3333-4333-8333-333333333333" }, "mode": "transcribe" }'
صلاحية الرابط الموقّع 24 ساعة، وبعدها احجز مكانًا جديدًا.
Webhooks#
/v1/webhook-endpointsسجّل عنوان https وأرسل id الخاص به باسم webhook_endpoint_id عند إرسال الطلب. نرسل حدثًا بطريقة POST عند انتهاء المهمة أو الدفعة. تتضمن الاستجابة المفتاح السري للتوقيع secret مرة واحدة فقط. يتطلب تسجيل عناوين Webhook وتعطيلها جلسة تسجيل دخول، لذلك نفّذ ذلك من صفحة Webhooks في لوحة التحكم، أما مفتاح API فيتلقى هناك 403 FORBIDDEN لكنه يستطيع عرض نقاط النهاية.
الأحداث#
{"event_id": "44444444-4444-4444-8444-444444444444","type": "job.succeeded","created_at": "2026-09-16T10:00:14.000Z","job_id": "11111111-1111-4111-8111-111111111111","batch_id": null,"result_id": "22222222-2222-4222-8222-222222222222","metadata": { "order": "8812" },"error": null}
job.succeeded: اجلبresult_idأو صدّره.job.failed: يحملerrorالرمز.batch.completed: انتهت كل العناصر، فاقرأ الدفعة للاطلاع على نتيجة كل عنصر.
أعد أي استجابة من فئة 2xx خلال بضع ثوانٍ. تُعاد محاولة التسليمات الفاشلة بتأخير متزايد، ويمكن إعادة إرسالها من لوحة التحكم. وقد يصل الحدث أكثر من مرة، لذا استبعد المكرر اعتمادًا على event_id.
التحقق من التوقيع#
الترويسات X-TranscriptDock-Event-Id و X-TranscriptDock-Timestamp و X-TranscriptDock-Signature. التوقيع هو HMAC-SHA256 بالترميز السداسي للقيمة {event_id}.{timestamp}.{raw_body} باستخدام سرّك. ارفض أي طلب أقدم من خمس دقائق.
import crypto from "node:crypto";export function verify(eventId: string, timestamp: string, rawBody: string, signature: string, secret: string): boolean {if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;const expected = crypto.createHmac("sha256", secret).update(`${eventId}.${timestamp}.${rawBody}`).digest("hex");return expected.length === signature.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));}
البحث عن الفيديوهات#
/v1/video-discoveriesابحث في YouTube أو اعرض قناة أو قائمة تشغيل أو ملف TikTok شخصي، ثم أرسل الروابط إلى مهام التفريغ. يعمل البحث في الخلفية مثل المهمة: اقرأه عبر GET /v1/video-discoveries/{id} حتى تصبح status بقيمة succeeded. رصيد واحد لكل صفحة، وتُحفظ النتائج 24 ساعة.
curl -X POST https://www.transcriptdock.com/v1/video-discoveries \-H "Authorization: Bearer td_live_YOUR_KEY" \-H "Idempotency-Key: search-async-rust-1" \-H "Content-Type: application/json" \-d '{ "kind": "youtube_search", "query": "async rust", "limit": 5 }'
يُعيد الطلب 202 مع status: "queued". وبعد اكتمال GET /v1/video-discoveries/{id} يبدو كالتالي:
{"id": "55555555-5555-4555-8555-555555555555","kind": "youtube_search","status": "succeeded","request": { "kind": "youtube_search", "query": "async rust", "limit": 5 },"videos": [{"platform": "youtube","video_id": "wXtngLBkK4Q","url": "https://www.youtube.com/watch?v=wXtngLBkK4Q","title": "Async Rust explained in 20 minutes","channel_id": "UCSp-OaMpsO8K0KkOqyBl7_w","channel_title": "Let's Get Rusty","duration_s": 1155,"published_at": null,"published_text": "5 months ago","view_count": 83635,"view_count_text": "83,635 views","thumbnail_url": "https://i.ytimg.com/vi/wXtngLBkK4Q/hq720.jpg","tiktok": null}],"profile": null,"next_cursor": "opaque-token","error": null,"created_at": "2026-09-16T12:00:00.000Z","updated_at": "2026-09-16T12:00:03.000Z","expires_at": "2026-09-17T12:00:00.000Z"}
لغات ترجمات الفيديو#
/v1/language-discoveriesالمحتوى { "source": { "url": "https://www.youtube.com/watch?v=..." } } مع Idempotency-Key (لـ YouTube فقط، برصيد واحد). اقرأ GET /v1/language-discoveries/{id} للحصول على قائمة مسارات الترجمات مع رموزها، وما إذا كانت من صانع المحتوى أو تلقائية، والمسار الافتراضي. استخدم الرموز في caption_languages.
الاستخدام والإمكانات#
/v1/usage{"plan": "pro","period_end": "2026-10-16T00:00:00.000Z","credits_remaining": 5840,"credits_total": 6000,"credits_reserved": 4,"prepaid_credits": 0,"transcribe_credits_per_minute": 2,"minimum_billable_seconds": 60,"subscription": {"status": "active","interval": "yearly","cancel_at_period_end": false,"current_period_end": "2027-09-16T00:00:00.000Z"}}
credits_remaining لا يتضمن credits_reserved (الأرصدة المحجوزة للمهام الجارية). و prepaid_credits هي الأرصدة التي اشتريتها، ولا تنتهي صلاحيتها.
subscription هو اشتراك Stripe الذي تقوم عليه الخطة المدفوعة، ويكون null إذا لم يوجد اشتراك. ويتضمن status، و interval لدورة الفوترة (monthly أو yearly)، و cancel_at_period_end، و current_period_end وهو موعد تجديد الخطة أو انتهائها. أما period_end فهو موعد تجديد الأرصدة الشهرية، وتتجدد كل شهر حتى في الخطط السنوية.
/v1/capabilitiesما يمكن لمفتاحك فعله الآن: لكل مصدر (youtube، و tiktok، و instagram، و upload، و direct) الأوضاع المتاحة، إضافة إلى الحدود والأسعار. اقرأ هذه البيانات بدلًا من تثبيتها في الكود؛ فالتجربة مثلًا تُرجع auto و transcribe بقيمة false.
{"youtube": { "enabled": true, "captions_only": true, "auto": true, "transcribe": true, "social_acquisition_fee": true },"tiktok": { "enabled": true, "captions_only": true, "auto": true, "transcribe": true, "social_acquisition_fee": true },"instagram": { "enabled": false, "captions_only": false, "auto": false, "transcribe": false, "social_acquisition_fee": true, "native_captions": "unverified_disabled" },"upload": { "enabled": true, "captions_only": false, "auto": true, "transcribe": true, "social_acquisition_fee": false },"direct": { "enabled": true, "captions_only": false, "auto": true, "transcribe": true, "social_acquisition_fee": false },"max_duration_ms": 7200000,"max_media_bytes": 262144000,"export_formats": ["txt", "json", "srt", "vtt"],"recognition_profiles": ["standard"],"transcribe_credits_per_minute": 2,"minimum_billable_seconds": 60,"price_version": "2026-09-14","asr_enabled": true,"instagram_enabled": false,"free_caption_credits": 50,"free_caption_credits_period": "month"}
حدود الاستخدام#
| الخطة | الإرسال في الدقيقة | المهام الجارية | القراءات في الدقيقة |
|---|---|---|---|
| التجربة | 10 | 10 | 120 |
| Starter | 60 | 100 | 120 |
| Pro | 120 | 500 | 120 |
| Scale | 300 | 2,000 | 120 |
عند تجاوز الحد تحصل على 429 RATE_LIMITED مع ترويسة retry-after (بالثواني) وحقل details.detail يسمّي الحد. ولا يُخصم أي رصيد. وتُبعدك Webhooks و ?wait=25 كثيرًا عن حد القراءة.
الأخطاء#
لكل خطأ الشكل نفسه. تعني retryable: true أن الطلب نفسه قد ينجح لاحقًا: انتظر عدد الثواني الموجود في retry-after إن وُجد، وإلا فتراجع بضع ثوانٍ، وأعد استخدام Idempotency-Key نفسه حتى لا يتكرر شيء. أما أي خطأ آخر فيحتاج إلى تغيير من جهتك.
{"error": {"code": "INSUFFICIENT_BALANCE","message": "Not enough credits. Buy credits or upgrade your plan to continue.","retryable": false,"details": { "detail": "This job needs more credits than you have left. Buy credits or upgrade your plan." },"doc_url": "https://www.transcriptdock.com/docs/api-reference#error-codes"},"request_id": "66666666-6666-4666-8666-666666666666"}
المهمة التي تفشل بعد قبولها تُعيد 200 عند GET /v1/jobs/{id}، مع status: "failed" وكائن الخطأ نفسه في error. ولا يُخصم أي رصيد عن المهمة الفاشلة.
الرموز#
| الرمز | HTTP | إعادة المحاولة | المعنى والإجراء المطلوب |
|---|---|---|---|
INVALID_REQUEST | 422 | لا | A field is missing or has the wrong shape. details.detail names it. |
INVALID_URL | 422 | لا | The URL is not a valid https link (max 2048 characters). |
UNSUPPORTED_SOURCE | 422 | لا | The link is not a YouTube or TikTok video URL. |
UNSAFE_URL | 422 | لا | The direct media link points at a private or blocked network address. |
INVALID_CURSOR | 422 | لا | A video discovery cursor expired or is malformed. Start again from the first page. A bad job list cursor returns INVALID_REQUEST. |
CAPABILITY_UNAVAILABLE | 422 | لا | This mode is not available for this source. GET /v1/capabilities shows what is. |
IDEMPOTENCY_CONFLICT | 409 | لا | This Idempotency-Key was already used with a different body. Use a new key. |
UNAUTHENTICATED | 401 | لا | No valid API key or OAuth token in the Authorization header. |
FORBIDDEN | 403 | لا | The key lacks the scope for this endpoint, or the workspace is disabled. |
EMAIL_UNVERIFIED | 403 | لا | Verify the account email before using the API. |
NOT_FOUND | 404 | لا | No such object in this workspace. |
INSUFFICIENT_BALANCE | 402 | لا | Not enough credits for this job. Buy credits or upgrade. |
PLAN_REQUIRED | 402 | لا | This needs a paid plan (AI transcription, larger batches) or the trial credits are used up. |
BUDGET_EXCEEDED | 402 | لا | The measured cost is above max_credits. Nothing was charged; raise the cap or skip the media. |
JOB_NOT_RETRYABLE | 409 | لا | The failure was final (private video, no captions). Fix the input and submit a new job. |
CANCELLATION_NOT_ALLOWED | 409 | لا | AI transcription already started; the job will finish. |
RATE_LIMITED | 429 | نعم | Over a rate or queue limit. Wait retry-after seconds; details.detail says which limit. |
SOURCE_NOT_FOUND | 422 | لا | The video does not exist or was removed. |
SOURCE_PRIVATE | 422 | لا | The video is private. Only public videos work. |
SOURCE_AUTH_REQUIRED | 422 | لا | The video needs a login, age check or membership. |
SOURCE_REGION_RESTRICTED | 422 | لا | The video is blocked in the regions we fetch from. |
NO_CAPTIONS | 422 | لا | No captions on this video and mode was captions_only. Use auto or transcribe. |
LANGUAGE_UNAVAILABLE | 422 | لا | None of caption_languages exists on this video. Drop the list to take the default track. |
LANGUAGE_UNSUPPORTED | 422 | لا | AI transcription does not support the requested language. |
NO_SPEECH | 422 | لا | AI transcription found no speech in the audio. |
NO_AUDIO | 422 | لا | The media has no audio track. |
INVALID_MEDIA | 422 | لا | The file could not be read as audio or video. |
UNSUPPORTED_MEDIA | 422 | لا | Not an audio or video file type. |
DURATION_LIMIT_EXCEEDED | 413 | لا | Longer than 2 hours. |
FILE_TOO_LARGE | 413 | لا | Larger than 250 MB. |
TIMESTAMPS_UNAVAILABLE | 422 | لا | This transcript has no timings, so srt and vtt exports are unavailable. Use txt or json. |
PROVIDER_REJECTED | 422 | لا | The AI transcription model could not process this audio. |
SOURCE_RATE_LIMITED | 503 | نعم | The source platform is throttling us. The job retries automatically. |
SOURCE_BLOCKED | 503 | نعم | The source platform blocked the fetch. The job retries automatically. |
SOURCE_TIMEOUT | 503 | نعم | The source platform timed out. The job retries automatically. |
SOURCE_CHANGED | 503 | نعم | The source changed while we read it. The job retries automatically. |
PROVIDER_UNAVAILABLE | 503 | نعم | AI transcription is temporarily unavailable. The job retries automatically. |
STORAGE_UNAVAILABLE | 503 | نعم | File storage is temporarily unavailable. Retry the request. |
INTERNAL_ERROR | 500 | نعم | Our fault. Retry with the same Idempotency-Key; quote X-Request-Id if it persists. |