الواجهة البرمجية العامة
تتيح الواجهة البرمجية العامة لخوادمك استدعاء وكلائك. وهي منفصلة عن لوحة التحكم: لها مفاتيحها ووثائقها وحدودها الخاصة.
- العنوان الأساسي:
https://api.eu.backcrew.ai/v1لمساحات العمل المستضافة في أوروبا، وتستخدمه الأمثلة أدناه. ولكل نشر إقليمي لـ backcrew عنوانه الخاص، وتعرض المقتطفات البرمجية في صفحة التضمين للوكيل دائمًا عنوان مساحة عملك. - المرجع التفاعلي:
https://api.eu.backcrew.ai/v1/docs
المصادقة
Section titled “المصادقة”أنشئ مفتاحًا سريًا من الإعدادات ثم مفاتيح API. يبدأ المفتاح بـ bk_live_ ولا يُعرض إلا مرة واحدة، فاحفظه في مكان آمن. أرسله مع كل طلب:
Authorization: Bearer bk_live_...ويأتي مع كل مفتاح أيضًا سر توقيع (bks_...) يُعرض مرة واحدة بجانبه. ولا تحتاج إليه إلا للاستدعاءات الراجعة، إذ يتيح لخادمك التحقق من أن النتيجة صادرة فعلًا عن backcrew. وإن فقدته أو لم يكن لديك سر، فاختر سر توقيع جديد على المفتاح، فيتوقف السر القديم عن المطابقة فورًا.
عرض وكلائك
Section titled “عرض وكلائك”curl https://api.eu.backcrew.ai/v1/agents \ -H "Authorization: Bearer $BACKCREW_API_KEY"[{ "id": "7c9f…", "name": "support-bot", "status": "deployed" }]لا يجيب إلا الوكلاء بحالة deployed.
إرسال رسالة
Section titled “إرسال رسالة”POST /v1/agents/{agent_id}/invoke
| الحقل | مطلوب | المعنى |
|---|---|---|
prompt |
نعم | الرسالة. |
session_id |
لا | يجمع الرسائل في محادثة واحدة. |
user_id |
لا | معرّفك الخاص للشخص الذي تتصرف نيابةً عنه. عند تفعيل الذاكرة، يحصل كل user_id على ذاكرته الخاصة. |
curl -X POST https://api.eu.backcrew.ai/v1/agents/$AGENT_ID/invoke \ -H "Authorization: Bearer $BACKCREW_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "أين طلبي؟", "user_id": "customer-123", "session_id": "conversation-1"}'{ "response": "تم شحن طلبك أمس ومن المتوقع وصوله يوم الخميس.", "usage": { "input_tokens": 1240, "output_tokens": 310, "credits_charged": 5, "unmetered": [] }}يصل الرد كاملًا عند انتهاء الوكيل، فالردود لا تُبث تدريجيًا.
قد تنتهي مهلة الطلب الذي يستغرق أكثر من 100 ثانية قبل وصول الرد. وإن كان وكيلك قد يستغرق وقتًا أطول، فابدأ تشغيلًا بدلًا من ذلك.
Python
Section titled “Python”import os, requests
res = requests.post( f"https://api.eu.backcrew.ai/v1/agents/{os.environ['AGENT_ID']}/invoke", headers={"Authorization": f"Bearer {os.environ['BACKCREW_API_KEY']}"}, json={"prompt": "أين طلبي؟", "user_id": "customer-123"}, timeout=120,)res.raise_for_status()print(res.json()["response"])JavaScript
Section titled “JavaScript”const res = await fetch(`https://api.eu.backcrew.ai/v1/agents/${agentId}/invoke`, { method: "POST", headers: { Authorization: `Bearer ${process.env.BACKCREW_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ prompt: "أين طلبي؟", user_id: "customer-123" }),});if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);console.log((await res.json()).response);الطلبات الطويلة: عمليات التشغيل والاستدعاءات الراجعة
Section titled “الطلبات الطويلة: عمليات التشغيل والاستدعاءات الراجعة”يمكن للوكيل أن يعمل مدةً تصل إلى 5 دقائق، غير أن الطلب الواحد الذي يبقى مفتوحًا أكثر من 100 ثانية قد ينقطع قبل وصول الرد. ويتجنب التشغيل ذلك: تبدؤه فيجيبك backcrew فورًا، ويعمل الوكيل في الخلفية. ثم إما أن تستعلم عن التشغيل، وإما أن تحدد callback_url فيرسل إليك backcrew النتيجة عند الانتهاء.
تخضع عمليات التشغيل للتكلفة والفحوصات نفسها التي يخضع لها invoke: فإن لم يكن الوكيل منشورًا (409)، أو نفدت الأرصدة أو بُلغ الحد الشهري (402)، يُرفض التشغيل عند بدئه دون أي خصم. وتُحفظ عمليات التشغيل لمدة ساعة.
بدء تشغيل
Section titled “بدء تشغيل”يقبل POST /v1/agents/{agent_id}/runs الحقول نفسها التي يقبلها invoke، إضافةً إلى callback_url الاختياري، ويجيب بالرمز 202:
curl -X POST https://api.eu.backcrew.ai/v1/agents/$AGENT_ID/runs \ -H "Authorization: Bearer $BACKCREW_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "طابق فواتير شهر أكتوبر", "user_id": "finance-team"}'{ "id": "3f1c…", "agent_id": "7c9f…", "status": "running", "started_at": "2026-10-22T09:00:00+00:00", "finished_at": null, "response": null, "usage": null, "error": null }الاستعلام عن التشغيل
Section titled “الاستعلام عن التشغيل”يعيد GET /v1/agents/{agent_id}/runs/{run_id} الكائن نفسه، وتكون قيمة status إحدى ما يلي:
| الحالة | المعنى |
|---|---|
running |
لا يزال الوكيل يعمل. أعد السؤال بعد بضع ثوانٍ. |
answered |
اكتمل: يحتوي response وusage على النتيجة. |
failed |
لم يُجب: يوضح error السبب (مثل نفاد الأرصدة أو تعطل شيفرة الوكيل). |
lost |
توقف دون إجابة. راجع سجل نشاط الوكيل، ثم أعد المحاولة. |
يُحتسب الاستعلام ضمن حد المعدل لمفتاحك، لذا يكفي الاستعلام كل ثانيتين إلى خمس ثوانٍ. ويُعد معرّف التشغيل التابع لمساحة عمل أخرى أو لوكيل آخر غير موجود (404).
import os, time, requests
API = f"https://api.eu.backcrew.ai/v1/agents/{os.environ['AGENT_ID']}"HEADERS = {"Authorization": f"Bearer {os.environ['BACKCREW_API_KEY']}"}
run = requests.post(f"{API}/runs", headers=HEADERS, json={"prompt": "طابق فواتير شهر أكتوبر"}, timeout=30)run.raise_for_status()run = run.json()while run["status"] == "running": time.sleep(3) run = requests.get(f"{API}/runs/{run['id']}", headers=HEADERS, timeout=30).json()
if run["status"] == "answered": print(run["response"])else: print(f"{run['status']}: {run['error']}")استلام النتيجة على خادمك
Section titled “استلام النتيجة على خادمك”أضف "callback_url": "https://your-server.example.com/backcrew" عند بدء التشغيل. وعند انتهائه (answered أو failed)، يرسل backcrew طلب POST إلى ذلك العنوان، ويكون متن الطلب كائن التشغيل بصيغة JSON. أجب بأي رمز 2xx. وإن صادف الإرسال خطأً، أو تلقى ردًا غير 2xx، أو لم يتلقَّ ردًا خلال 10 ثوانٍ، فإنه يُعاد بعد 5 ثوانٍ ثم بعد 30 ثانية: 3 محاولات في المجموع. ولا تُتبع عمليات إعادة التوجيه.
يجب أن يبدأ العنوان بـ https:// وأن يكون متاحًا على الإنترنت العام: إذ تُرفض العناوين الخاصة والمحلية والمحجوزة بالرمز 422 عند بدء التشغيل.
ويحمل كل إرسال توقيعًا مُنشأً بسر التوقيع الخاص بمفتاحك:
X-Backcrew-Signature: t=1792659600,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bdقيمة v1 هي HMAC-SHA256 بالترميز الست عشري للطابع الزمني متبوعًا بنقطة ثم متن الطلب الخام ("{t}.{body}"). تحقق منه قبل الوثوق بالمتن، مستخدمًا البايتات الخام التي استلمتها (لا JSON معاد ترميزه)، وارفض الطابع الزمني القديم كي لا يُعاد إرسال طلب مُعترَض:
import hashlib, hmac, os, time
def verify(body: bytes, header: str, secret: str = os.environ["BACKCREW_SIGNING_SECRET"]) -> bool: try: fields = dict(part.split("=", 1) for part in header.split(",")) timestamp = int(fields["t"]) except (KeyError, ValueError): return False if abs(time.time() - timestamp) > 300: # أقدم من 5 دقائق return False expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, fields.get("v1", ""))
# في إطار الويب لديك، مثل Flask:# if not verify(request.get_data(), request.headers.get("X-Backcrew-Signature", "")): abort(401)import crypto from "node:crypto";
// `body` هو متن الطلب الخام بصيغة Buffer، مثل express.raw({ type: "application/json" }).function verify(body, header, secret = process.env.BACKCREW_SIGNING_SECRET) { const fields = Object.fromEntries((header || "").split(",").map((part) => part.split("=", 2))); const timestamp = Number(fields.t); if (!timestamp || Math.abs(Date.now() / 1000 - timestamp) > 300) return false; const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.`).update(body).digest("hex"); const given = Buffer.from(fields.v1 || "", "utf8"); return given.length === expected.length && crypto.timingSafeEqual(given, Buffer.from(expected, "utf8"));}قد تصل نتيجة التشغيل أكثر من مرة (مثلًا إذا تأخر خادمك في الرد)، لذا استخدم معرّف التشغيل id لمعالجة كل نتيجة مرة واحدة. ولا يُرسل استدعاء راجع لمفتاح أُلغي قبل انتهاء التشغيل، ولا لتشغيل بحالة lost: فاستعلم عن التشغيل إن لم تصلك النتيجة.
الأخطاء
Section titled “الأخطاء”| الرمز | المعنى |
|---|---|
401 |
المفتاح مفقود أو غير معروف أو ملغى. |
402 |
نفدت أرصدة مساحة العمل (أو تجاوزت حدها الشهري). |
404 |
لا يوجد وكيل بهذا المعرّف في مساحة عمل هذا المفتاح، أو لا يوجد تشغيل كهذا (تُحفظ عمليات التشغيل لمدة ساعة). |
409 |
الوكيل غير منشور حاليًا (مثلًا: قيد التحديث). |
422 |
قيمة callback_url ليست عنوان https:// عامًا، أو ليس للمفتاح سر توقيع بعد. |
429 |
بلغت حد المعدل؛ انتظر عدد الثواني في Retry-After. |
502 |
تعذّر على الوكيل الإجابة. |
504 |
تجاوز الوكيل الحد الأقصى لمدة الطلب (5 دقائق). |
الحدود والتكلفة
Section titled “الحدود والتكلفة”- 60 طلبًا في الدقيقة لكل مفتاح، بما في ذلك بدء عمليات التشغيل والاستعلام عنها.
- يستهلك كل استدعاء أرصدة تمامًا كطلب من لوحة التحكم. راجع الأرصدة.