Files API وملفات PDF
واجهة Files API في GetVibe API المتوافقة مع OpenAI وإدخال ملفات PDF: base64 أو رابط أو file_id في chat/completions وresponses وmessages، والنماذج التي ترى الصور داخل ملف PDF، والحدود والأخطاء.
واجهة Files API متوافقة مع OpenAI لرفع الملفات وقراءتها وحذفها. وتتطلب كل عملية مفتاح API؛ ولا يمكن الوصول إلى الملف إلا من الحساب نفسه الذي رفعه.
رفع ملف
أرسل multipart/form-data مع الحقلين المطلوبين file وpurpose. الأغراض المسموح بها: assistants، batch، fine-tune، vision وuser_data. الحد الأقصى لحجم الملف 50 MiB (52 428 800 بايت)؛ وتجاوزه يعيد 413.
curl -X POST https://getvibeapi.com/v1/files \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-F "purpose=user_data" \
-F "file=@./report.pdf"الحصول على البيانات الوصفية أو المحتوى أو الحذف
يعيد الرفع كائن file يحوي id غير شفّاف وname وsize وpurpose ووقت الإنشاء. ويعيد GET بدون /content هذه البيانات الوصفية؛ أما GET /content فينزّل البايتات الخام. وبعد نجاح DELETE يعيد كلا طلبَي GET الخطأ 404. ويعيد ملف موجود لحساب آخر الخطأ 403، ويعيد معرّف غير معروف الخطأ 404.
سير العمل الآمن
- ارفع الملف واحتفظ فقط بـ
file_idالمُعاد. - تحقّق من البيانات الوصفية بالمفتاح نفسه؛ وعند العمل مع Responses مرّر هذا المعرّف في
input_file.file_id. - لا ترفع الأسرار واحذف الملف بعد الانتهاء. الملف المحذوف لا يمكن استعادته.
ملف PDF في طلبات النماذج
يقبل كل نموذج نصي ملف PDF عبر تنسيقات API الثلاثة. باختصار: أرسل الملف بإحدى الطرق الثلاث أدناه — فنحن نستخرج نصه مجانًا افتراضيًا ونمرر النص إلى النموذج. يقرأ النموذج النص والجداول، لكنه لا يقرأ الصور الموجودة داخل ملف PDF أو المستندات الممسوحة ضوئيًا. عندما تكون الصور أو التنسيق أو النسخة الممسوحة ضوئيًا مهمة، اختر نموذجًا من الجدول أدناه وأوقف استخراج النص. تم التحقق من كل ما في هذه الصفحة باستخدام طلبات مباشرة في 2 نوفمبر 2026، مع ملف PDF من ثلاث صفحات يتضمن نصًا وجدولًا وصورة.
ثلاث طرق لإرسال ملف PDF
| الطريقة | كيفية التنفيذ | متى يُستخدم |
|---|---|---|
| base64 في الطلب | Chat: {"type":"file","file":{"filename":"report.pdf","file_data":"data:application/pdf;base64,…"}}؛ Responses: {"type":"input_file","filename":"report.pdf","file_data":"data:…"}؛ Messages: {"type":"document","source":{"type":"base64","media_type":"application/pdf","data":"…"}} | مستند للاستخدام مرة واحدة. يعمل مع نقاط النهاية الثلاث. الملفات التي يصل حجمها إلى 20 MiB. |
| رابط عام | Chat: "file":{"file_url":"https://…"}؛ Responses: {"type":"input_file","file_url":"https://…"}؛ Messages: "source":{"type":"url","url":"https://…"} | الملف متاح بالفعل على الإنترنت. ننزّله بأنفسنا: عبر HTTPS فقط، دون تسجيل دخول أو كلمة مرور، ويجب أن يستجيب الخادم بـ application/pdf، بحد أقصى 20 MiB، خلال 10 ثوانٍ ومع 3 عمليات إعادة توجيه على الأكثر. |
file_id بعد الرفع | حمّل باستخدام POST /v1/files وpurpose=user_data، ثم: Chat "file":{"file_id":"file-pv-…"}، Responses {"type":"input_file","file_id":"file-pv-…"}، Messages "source":{"type":"file","file_id":"file-pv-…"} | مستند واحد عبر عدة طلبات: لا حاجة إلى إعادة إرسال الميغابايتات في كل مرة، كما تُخزَّن بادئة الطلب المطابقة مؤقتًا. يُحتفظ بالملف لمدة 7 أيام، ولا يراه إلا حسابك. |
أمثلة جاهزة للتشغيل
يُقرأ المفتاح من متغير البيئة GETVIBE_API_KEY. تستخدم أمثلة Python حزمتي SDK الرسميتين openai وanthropic من دون تغيير — العنوان فقط هو المختلف.
/v1/chat/completions
# PDF inline (base64); jq builds the body so a large file does not hit the command-line length limit
# macOS: replace base64 -w0 report.pdf with base64 -i report.pdf
jq -n --rawfile b64 <(base64 -w0 report.pdf) '{model: "deepseek-v4.1-flash", messages: [{role: "user", content: [
{type: "text", text: "Summarise the document"},
{type: "file", file: {filename: "report.pdf", file_data: ("data:application/pdf;base64," + $b64)}}]}]}' |
curl https://getvibeapi.com/v1/chat/completions \
-H "Authorization: Bearer $GETVIBE_API_KEY" -H "Content-Type: application/json" -d @-/v1/responses
# FILE_ID comes from the upload, see the "curl · file_id" tab above
curl https://getvibeapi.com/v1/responses \
-H "Authorization: Bearer $GETVIBE_API_KEY" -H "Content-Type: application/json" \
-d '{"model":"gpt-6.1-sol","input":[{"role":"user","content":[
{"type":"input_text","text":"What were the sales in Kazan in August?"},
{"type":"input_file","file_id":"'"$FILE_ID"'"}]}]}'
# base64 instead of file_id:
# {"type":"input_file","filename":"report.pdf","file_data":"data:application/pdf;base64,…"}/v1/messages
curl https://getvibeapi.com/v1/messages \
-H "x-api-key: $GETVIBE_API_KEY" -H "anthropic-version: 2023-06-01" -H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-5.5","max_tokens":1024,"messages":[{"role":"user","content":[
{"type":"document","source":{"type":"file","file_id":"'"$FILE_ID"'"}},
{"type":"text","text":"Summarise the document"}]}]}'
# other sources:
# "source":{"type":"base64","media_type":"application/pdf","data":"<base64>"}
# "source":{"type":"url","url":"https://example.com/report.pdf"}ما يراه النموذج: النص أو الملف نفسه
النص المستخرج افتراضيًا. نأخذ طبقة النص من ملف PDF ونمررها إلى النموذج بدلًا من الملف. هذه العملية مجانية وتعمل مع أي نموذج، حتى النماذج التي لا تدعم PDF. يرى النموذج الكلمات والأرقام، بما في ذلك الجداول (من دون حدود، لكن مع القيم الصحيحة). ما لا يراه: الصور والمخططات والطوابع والتوقيعات والألوان والتنسيق. نمرر ما يصل إلى 60,000 حرف من النص في كل طلب (نحو 28 صفحة كثيفة)؛ ويُقتطع الباقي ويُبلَّغ النموذج بأن المستند قد اقتُطع. توضّح ترويسة الاستجابة x-pv-document-shim ما حدث: تعني applied:text_extracted أن النموذج تلقى النص، وتعني not-needed:lane_reads_pdf أنه تلقى الملف نفسه.
الملف نفسه. لكي يرى النموذج الصفحات كاملةً، بما فيها الصور والتنسيق، أضف "plugins":[{"id":"documents","enabled":false}] إلى نص الطلب (فتصبح الترويسة not-needed:disabled_by_client). لا تفعل ذلك إلا مع النماذج المعلَّمة بـ «نعم» في الجدول: أما النماذج الأخرى فتجيب بالرمز 400 أو تقول إنها لا ترى أي ملف، وتظل رموز إدخال الملف محتسبةً.
# curl: add the field to the request body
"plugins": [{"id": "documents", "enabled": false}]
# Python (openai SDK)
r = client.chat.completions.create(
model="gpt-6.1-sol",
messages=[...],
extra_body={"plugins": [{"id": "documents", "enabled": False}]},
)| النموذج | افتراضيًا | يرى الملف نفسه (الاستخراج متوقف) |
|---|---|---|
gpt-6.1-sol | الملف نفسه | نعم — على /chat/completions و/responses |
gpt-6-luna | text | نعم — على /chat/completions و/responses |
gpt-5.6-sol | text | غير مؤكّد — أبقِ الإعداد الافتراضي |
claude-sonnet-5.5, claude-opus-5.5 | text | لا — لا يستطيع النموذج رؤية الملف، لذا نستخرج النص حتى عند تعطيل الإضافة (الترويسة x-getvibe-warnings: plugin_overridden:documents)؛ وللملف نفسه استخدم gpt-6.1-sol |
claude-haiku-5.5 | text | لا — لا يرى النموذج الملف |
gemini-4-argon, gemini-3.8-flash | text | لا — لا يرى النموذج الملف، أو 400 |
qwen3.8-flash | text | نعم — على /chat/completions؛ و400 على /responses |
deepseek-v4.1-flash, glm-5.3, kimi-k3 | text | لا — 400 |
كيفية إجراء الاختبار: طُلب من النموذج ذكر كلمة من الصفحة 1، ورقم من خلية في جدول، ووصف صورة (أشكال وألوان ورقم مرسوم كصورة). تعني «النص» أنه سمّى الكلمة والرقم بشكل صحيح وقال إنه لا يستطيع رؤية الصورة. وتعني «نعم» أنه وصف الصورة بشكل صحيح أيضًا. أرسل ملفات PDF إلى نماذج GPT وGemini وQwen عبر /v1/chat/completions أو /v1/responses: في /v1/messages لا ترى هذه النماذج الملف نفسه.
not-needed:no_text_layer_unmeasured_lane). ويعتمد الأمر بعد ذلك على النموذج: يقرأ gpt-6.1-sol وqwen3.8-flash نسختنا الممسوحة ضوئيًا، بينما تُجيب نماذج DeepSeek بالرمز 400. إذا كان نموذجك لا يستطيع قراءة النسخة الممسوحة ضوئيًا، فأجرِ OCR من جانبك وأرسل النص، أو أرسل الصفحات بصور PNG/JPEG عبر image_url إلى نموذج يقبل الصور.الحدود والرموز والوقت
| ما هو | الحد |
|---|---|
| ملف PDF في طلب نموذج (base64 أو رابط أو file_id) | ما يصل إلى 20 MiB لكل ملف؛ ويجب أن يبدأ الملف بـ %PDF- |
التحميل إلى POST /v1/files | ما يصل إلى 50 MiB (52,428,800 بايت)، لكن لا يمكن أن يدخل في طلب النموذج سوى ملف PDF بحجم يصل إلى 20 MiB |
file_id lifetime | 7 أيام (حقل expires_at)، ثم يُحذف الملف |
| الصفحات | لا يوجد حد منفصل؛ مع استخراج النص، ما يصل إلى 60,000 حرف لكل طلب؛ ومع الملف نفسه، ما يصل إلى نافذة سياق النموذج |
| التنزيل عبر رابط | ما يصل إلى 10 ثوانٍ وما يصل إلى 3 عمليات إعادة توجيه |
كيفية احتساب الرموز. تُحتسب تكلفة PDF باعتباره رموز إدخال عادية للنموذج المختار وبسعره؛ ولا توجد رسوم منفصلة للملف أو لاستخراج النص. وهذه هي التكلفة (مقاسةً، بما في ذلك سؤال قصير):
- النص المستخرج: نحو 700 رمز لكل صفحة نصية كثيفة (10 صفحات — 7,300 رمز؛ 40 صفحة مقتطعة عند 60,000 حرف — 20,300 رمز). الصفحة التي تحتوي على جدول قصير — 100–200 رمز.
- الملف نفسه على نماذج GPT: نحو 600–700 رمز لكل صفحة (10 صفحات — 5,900؛ 40 — 23,300)؛ وعلى
gemini-4-argonنحو 1,200 لكل صفحة؛ وعلى Claude نحو 1,600 لكل صفحة. الصفحة الممسوحة ضوئيًا علىgpt-6.1-sol— نحو 5,800 رمز. - يُصيب تكرار المستند ذاكرة التخزين المؤقت عندما لا يتغير بدء الطلب: فقد قرأ طلب ثانٍ يتضمن
file_idنفسه 7,168 من أصل 7,309 رموز من ذاكرة التخزين المؤقت.
الوقت. يستغرق استخراج النص جزءًا من الثانية؛ وقد عادت إجابة عن مستند من 40 صفحة خلال 4–12 ثانية. بالنسبة إلى المستندات الكبيرة والإجابات الطويلة، استخدم stream: true واضبط مهلة العميل على 300 ثانية على الأقل.
الأخطاء وكيفية إصلاحها
| الاستجابة | السبب | ما ينبغي فعله |
|---|---|---|
400 invalid_pdf | The PDF must start with the %PDF- signature. | هذا ليس ملف PDF، أو أن base64 تالف. تأكد من ترميز الملف نفسه، لا مساره، ومن أن النوع هو application/pdf. |
400 invalid_pdf | The PDF size must not exceed 20 MiB. | قسّم المستند أو اضغط الصور الموجودة بداخله. |
413 invalid_request_error | على POST /v1/files: الملف أكبر من 52,428,800 بايت | حجم الملف يتجاوز 50 MiB: قسّمه. |
400 invalid_request_error | file_id غير متاح | حُذف الملف أو انتهت صلاحيته (7 أيام)، أو حمّله حساب آخر، أو أن المعرّف صادر عن خدمة مختلفة. أعد تحميل الملف باستخدام المفتاح نفسه. |
400 invalid_pdf | The PDF URL must be a public HTTPS URL without credentials. | الرابط من نوع http://، أو يتضمن اسم مستخدم وكلمة مرور، أو يستخدم منفذًا غير قياسي، أو نطاقًا غير موجود. قدّم رابط HTTPS عامًا أو أرسل base64. |
400 invalid_pdf | Could not safely fetch the PDF from the URL. | يعيد الرابط الخطأ 404، أو صفحة تسجيل دخول، أو HTML بدلًا من ملف PDF، أو لم يُجب الخادم في غضون 10 ثوانٍ. افتح الرابط في نافذة متصفح خاصة؛ وإذا لم يُنزَّل الملف فورًا، فأرسل base64. |
400 unsupported_input | لا يستطيع النموذج قراءة ملفات PDF، والملف لا يحتوي على نص (إنه نسخة ممسوحة ضوئيًا). | استخدم نموذجًا يقرأ النسخ الممسوحة ضوئيًا (انظر أعلاه)، أو شغّل OCR من جانبك. |
400 invalid_request_error | Invalid request… مع إيقاف استخراج النص، أو مع إجراء مسح ضوئي. | لا يقبل النموذج ملف PDF. أزِل plugins documents enabled:false لكي يحصل النموذج على النص، أو اختر نموذجًا مُعلَّمًا بـ "yes" في الجدول. |
| 200، لكن «لا أرى أي ملف» | استخراج النص متوقف، والنموذج أو القناة لا يقرأ الملف. | عُد إلى استخراج النص الافتراضي، أو اختر نموذجًا معلَّمًا بـ «نعم» في الجدول. |
أفضل الممارسات
- هل تحتاج إلى المستند في عدة طلبات؟ ارفعه مرة واحدة ومرّر
file_id: سيكون الطلب أصغر، كما تُخزَّن البادئة المتكررة مؤقتًا وتكلف أقل. - ضع ملف PDF والتعليمات الدائمة في بداية الرسالة، والسؤال المتغير في نهايتها: عندئذٍ تحدث إصابة ذاكرة التخزين المؤقت بوتيرة أكبر.
- قسّم المستندات الأطول من نحو 28 صفحة كثيفة حسب الفصول: عند استخدام استخراج النص، لا يصل إلى النموذج أي شيء يتجاوز 60,000 حرف.
- بالنسبة إلى العقود والتقارير والملفات المُصدَّرة التي تحتوي على طبقة نص، يكفي استخراج النص — وهو الخيار الأقل تكلفة على أي نموذج، بما في ذلك
deepseek-v4.1-flash. - هل تحتاج إلى مخططات أو طوابع أو مستندات ممسوحة ضوئيًا؟ أوقف الاستخراج واستخدم نموذجًا معلَّمًا بـ «نعم» في الجدول، مثل
gpt-6.1-sol. - تُقرأ النصوص غير اللاتينية (الروسية والصينية وغيرها) في ملف PDF من دون أي إعدادات. أزل كلمة مرور ملف PDF قبل إرساله.
- احذف الملفات المرفوعة باستخدام
DELETE /v1/files/{file_id}بمجرد ألا تعود بحاجة إليها.
file_id بمعرّف من طرف ثالث.