واجهة الوكلاء

وكلاء يستدعون النماذج والأدوات نيابة عنك، تشغّلهم المنصة

الإصدار التجريبي

لا تستقبل واجهة الوكلاء الطلبات بعد: حتى يفتحها فريق MindLab تُجيب مساراتها بالرمز 503. تصف هذه الصفحة العقد الذي ستعمل به.

واجهة الوكلاء في مرحلة تجريبية. يحتاج المفتاح إلى النطاق agents، ويمنحه فريق MindLab. والبتّ في الموافقات عبر الواجهة يحتاج النطاق agents.approve على مفتاح غير المفتاح الذي بدأ التشغيل.

في الإصدار التجريبي (0.1.0) تضيف التغييرات حقولاً ومسارات، ولا تعيد تسمية شيء ولا تحذفه. ويسرد سجل التغييرات ما تغيّر.

عنوان القاعدة https://api.mindlabsa.com/v1 والمصادقة هما نفسهما في واجهة المحادثة: Authorization: Bearer <API key> مع كل طلب، عدا الخطاف الموقّع POST /v1/hooks/{trigger_id}. التشغيلات التي يبدؤها مفتاح تتصرف باسمه: لا تستخدم إلا النماذج التي يحق له استدعاؤها.

يُرفض دائماً المفتاح الذي لا يملك agents.approve عند البتّ في موافقة، ويُرفض دائماً المفتاح الذي لا يملك agents في كل مسارات الـ Webhooks وفي كل مسارات المشغّلات (القراءة والكتابة على السواء؛ أما الخطاف الموقّع الوارد فلا يأخذ مفتاحاً) وفي ملخّص الاستخدام. أما في بقية المسارات فرفض المفتاح الذي لا يملك agents قيد التفعيل وقد لا يسري بعد: وحتى يسري يُخدَم هذا المفتاح. امنح كل مفتاح النطاقات التي يحتاجها فقط، ولا تعتمد على هذا الرفض لإبعاد مفتاح عن تشغيلات وكلائك.

المفاهيم

المفهومما هو
agentوكيل له اسم وslug وحالة (active أو archived) وإصدار حالي تستخدمه التشغيلات الجديدة. وحين يُوقف فريق تشغيل المنصة الوكيل أو حسابك كله مؤقتاً، يذكر ذلك الحقل operator_hold ولا تبدأ تشغيلاته (agent_held).
versionلقطة ثابتة لا تتغير من سلوك الوكيل: موجّه النظام والنموذج والأدوات والسياسة والميزانيات. يستخدم التشغيل الإصدار الحالي عند بدئه، والإصدار الجديد يرث كل حقل لم ترسله.
threadمحادثة تضيف إليها كل التشغيلات التي تبدأ عليها. تخص وكيلاً واحداً، ولا يجري فيها إلا تشغيل واحد في كل مرة (thread_busy). التشغيل الذي يبدأ دون thread_id يبدأ محادثة جديدة.
runتنفيذ واحد لإصدار: يبدأ queued، ثم running، وقد ينتظر waiting_approval، وينتهي succeeded أو failed أو budget_exceeded أو cancelled. القيمتان waiting_input وsleeping محجوزتان.
stepخطوة محفوظة من التشغيل بترتيب seq، ونوعها assistant (رد النموذج) أو tool_call أو tool_result أو system أو approval.
approvalاستدعاء أداة ينتظر قرار شخص، فيتوقف التشغيل في waiting_approval حتى يُوافَق عليه أو يُرفض، أو تنتهي مهلته بعد approval_ttl_seconds من سياسة الإصدار.
toolأداة من المنصة (builtin) أو أداة HTTP تسجّلها أنت (http)، ولكلٍّ مستوى خطورة: read أو write أو irreversible.
connectionسر محفوظ ترسله أداة HTTP مع كل استدعاء (bearer أو ترويسة تسمّيها). لا يُعاد السر أبداً.
triggerيبدأ تشغيلات وكيل وفق جدول (cron) أو عند وصول طلب موقّع (webhook). كل انطلاق يُسجَّل مع نتيجته.
webhookنقطة استقبال تُرسل إليها المنصة الأحداث التي تختارها، موقّعة بسرّها.

مستويات الخطورة ومتى يلزم الموافقة

المستوىالأثر
readيجري دون موافقة، إلا إن ورد اسمه في require_approval.
writeيحتاج موافقة، إلا إن كانت unattended_writes تساوي true. وبعد أن يقرأ التشغيل محتوى من خارج المنصة تحتاج كتاباته موافقة ما لم تكن writes_after_external_content تساوي allow.
irreversibleيحتاج موافقة دائماً.

البداية السريعة

أنشئ وكيلاً، ثم ابدأ تشغيلاً وتابعه. لا تحتاج أي حزمة: الواجهة HTTP عادية.

حتى تُفتح الواجهة تُجاب هذه الطلبات بالرمز 503.

# 1. Create an agent (it gets its version 1)
curl https://api.mindlabsa.com/v1/agents \
  -H "Authorization: Bearer $QIRNAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support triage",
    "system_prompt": "صنّف رسالة العميل واقترح رداً قصيراً."
  }'

# 2. Start a run: answered 202 at once, with the queued run's id
curl https://api.mindlabsa.com/v1/agents/$AGENT_ID/runs \
  -H "Authorization: Bearer $QIRNAS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": { "message": "فاتورتي الأخيرة بمبلغ خاطئ." } }'

# 3. Follow it as server-sent events (or poll GET /v1/runs/$RUN_ID)
curl -N https://api.mindlabsa.com/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $QIRNAS_API_KEY"

الوكلاء وإصداراتهم

POST/v1/agents
إنشاء وكيل مع إصداره الأولالنطاقagents
GET/v1/agents
عرض وكلائكالنطاقagents
GET/v1/agents/{id}
جلب وكيل مع إصداره الحاليالنطاقagents
GET/v1/agents/{id}/versions
عرض إصدارات وكيلالنطاقagents
POST/v1/agents/{id}/versions
إنشاء إصدار جديد من وكيلالنطاقagents

التشغيلات

POST/v1/agents/{id}/runs
بدء تشغيل (يُجاب 202 فوراً)النطاقagents
GET/v1/agents/{id}/runs
عرض تشغيلات وكيلالنطاقagents
GET/v1/runs
عرض تشغيلاتكالنطاقagents
GET/v1/runs/{id}
جلب تشغيلالنطاقagents
GET/v1/runs/{id}/steps
عرض خطوات تشغيلالنطاقagents
POST/v1/runs/{id}/cancel
إلغاء تشغيلالنطاقagents
GET/v1/runs/{id}/events
متابعة تشغيل كأحداث مُرسلة من الخادم (SSE)النطاقagents

الاستخدام

GET/v1/agents/usage
مجاميع تشغيلاتك المنتهية حسب اليوم أو حسب الوكيلالنطاقagents

المحادثات

GET/v1/threads/{id}
جلب محادثةالنطاقagents
GET/v1/threads/{id}/messages
عرض رسائل محادثةالنطاقagents

الموافقات

GET/v1/approvals
عرض الموافقاتالنطاقagents
GET/v1/approvals/{id}
جلب موافقةالنطاقagents
POST/v1/approvals/{id}/approve
الموافقة على استدعاء أداةالنطاقagents.approve
POST/v1/approvals/{id}/reject
رفض استدعاء أداةالنطاقagents.approve

قواعد البتّ في الموافقة

الحالةالرد
الموافقة غير موجودة أو تخص مالكاً آخر404 approval_not_found
المفتاح لا يملك agents.approve403 scope_required
المفتاح هو الذي بدأ التشغيل403 permission_denied: يجب أن يقرر مفتاح آخر أو شخص
القرار نفسه مرة أخرى200 بالموافقة دون تغيير
القرار الآخر بعد البتّ409 approval_decided
بعد انتهاء المهلة409 approval_expired
أُلغيت أو انتهى تشغيلها409 approval_closed
# With a key that holds agents.approve and did not start the run
curl https://api.mindlabsa.com/v1/approvals/$APPROVAL_ID/approve \
  -H "Authorization: Bearer $APPROVER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Checked the amount." }'

الأدوات والاتصالات

GET/v1/tools
عرض الأدوات التي يمكن أن يستخدمها إصدار وكيلالنطاقagents
POST/v1/tools
تسجيل أداة HTTPالنطاقagents
POST/v1/tools/{name}/revisions
إضافة مراجعة لأداة HTTPالنطاقagents
POST/v1/tools/{name}/disable
تعطيل أداة HTTPالنطاقagents
GET/v1/tools/{name}
عرض مراجعات أداة HTTPالنطاقagents
POST/v1/tools/connections
حفظ اتصال (سر ترسله أدوات HTTP)النطاقagents
GET/v1/tools/connections
عرض اتصالاتكالنطاقagents
GET/v1/tools/connections/{id}
جلب اتصالالنطاقagents
DELETE/v1/tools/connections/{id}
حذف اتصالالنطاقagents
PUT/v1/tools/connections/{id}/secret
استبدال سر اتصالالنطاقagents

المشغّلات والخطافات

POST/v1/triggers
إنشاء مشغّلالنطاقagents
GET/v1/triggers
عرض مشغّلاتكالنطاقagents
GET/v1/triggers/{id}
جلب مشغّلالنطاقagents
PATCH/v1/triggers/{id}
تعديل مشغّل أو إيقافه مؤقتاً أو إعادة تسليحهالنطاقagents
DELETE/v1/triggers/{id}
حذف مشغّلالنطاقagents
POST/v1/triggers/{id}/rotate-secret
تدوير سر مشغّل webhookالنطاقagents
GET/v1/triggers/{id}/fires
عرض انطلاقات مشغّلالنطاقagents
POST/v1/hooks/{trigger_id}
إطلاق مشغّل webhook (موقّع، دون مفتاح API)دون مفتاح: طلب موقّع

مشغّل cron يحمل جدولاً بخمسة حقول ومنطقة زمنية IANA. ومشغّل webhook يُطلَق بطلب موقّع إلى POST /v1/hooks/{trigger_id} (انظر التوقيع أدناه). قيمة overlap تحدد ما يحدث إن كان التشغيل السابق ما زال جارياً: skip أو allow.

نقاط الاستقبال وعمليات التسليم

POST/v1/webhooks
إنشاء نقطة استقبالالنطاقagents
GET/v1/webhooks
عرض نقاط الاستقبالالنطاقagents
GET/v1/webhooks/{id}
جلب نقطة استقبالالنطاقagents
PATCH/v1/webhooks/{id}
تعديل نقطة استقبالالنطاقagents
DELETE/v1/webhooks/{id}
حذف نقطة استقبالالنطاقagents
POST/v1/webhooks/{id}/rotate-secret
تدوير سر نقطة استقبالالنطاقagents
POST/v1/webhooks/{id}/test
إرسال حدث تجريبيالنطاقagents
GET/v1/webhooks/{id}/deliveries
عرض عمليات تسليم نقطة استقبالالنطاقagents
GET/v1/webhooks/{id}/deliveries/{delivery_id}
جلب عملية تسليم مع حدثهاالنطاقagents
POST/v1/webhooks/{id}/deliveries/{delivery_id}/replay
إعادة إرسال حدث عملية تسليمالنطاقagents

تستقبل نقطة الاستقبال الأحداث run.completed وrun.failed وapproval.requested وapproval.decided وtrigger.fired، وwebhook.test للتجربة. جسم كل حدث {id, type, created_at, data}. تحمل كل محاولة وكل إعادة إرسال نفس webhook-id، فاستخدمه لتجاهل ما وصلك من قبل.

البث (SSE)

يرسل GET /v1/runs/{id}/events إطار data: <JSON> لكل حدث:

الإطارمتى
run.statusأولاً، ثم عند كل تغيّر في الحالة.
step.completedلكل خطوة محفوظة، بترتيب seq.
approval.requestedبعد خطوة approval تطلب موافقة (تظهر الموافقة كما كانت حينها: معلّقة).
approval.decidedبعد خطوة approval تغلقها.
run.completedنجح التشغيل؛ يليه data: [DONE].
run.failedانتهى التشغيل بأي حالة نهائية أخرى؛ يليه data: [DONE].
: keep-alive

data: {"type":"run.status","status":"running"}

data: {"type":"step.completed","step":{"seq":1,"kind":"assistant", ...}}

data: {"type":"run.completed","run":{"id":"…","status":"succeeded", ...}}

data: [DONE]
  • إن لم يحدث شيء لمدة 15 ثانية يرسل البث سطر تعليق : keep-alive: تجاهل الأسطر التي تبدأ بـ :.
  • ينتهي البث دون [DONE] بعد ساعة، أو عند إعادة تشغيل الخادم: أعد الاتصال.
  • كل اتصال يعيد إرسال كل الخطوات من الأولى، فاحتفظ بآخر seq وصلك وتجاهل ما سبقه.
  • يُبقي كل خادم 20 بثاً مفتوحاً على الأكثر لكل مفتاح؛ وبعدها يُجاب 429 too_many_streams.
// Follow a run to its end. A stream that closes without [DONE] is reconnected;
// each connection replays every step, so the steps already seen are dropped by seq.
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function follow(runId, onEvent) {
  let lastSeq = 0;
  for (;;) {
    const res = await fetch(`https://api.mindlabsa.com/v1/runs/${runId}/events`, {
      headers: { Authorization: `Bearer ${process.env.QIRNAS_API_KEY}` },
    });
    if (res.status === 429) {
      await sleep(Number(res.headers.get("retry-after") ?? 1) * 1000);
      continue;
    }
    if (!res.ok) {
      const body = await res.json().catch(() => null); // a 503 page from in front of the API is not JSON
      throw new Error(`${res.status} ${body?.error?.code ?? body?.error?.type ?? res.statusText}`);
    }

    const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
    let buffer = "";
    let replayed = false; // the last step frame was one already seen
    for (;;) {
      const { value, done } = await reader.read();
      if (done) break; // closed without [DONE]: reconnect
      buffer += value;
      let end;
      while ((end = buffer.indexOf("\n\n")) >= 0) {
        const frame = buffer.slice(0, end);
        buffer = buffer.slice(end + 2);
        for (const line of frame.split("\n")) {
          if (!line.startsWith("data: ")) continue; // ": keep-alive" and other comments
          const data = line.slice(6);
          if (data === "[DONE]") return;
          const event = JSON.parse(data);
          if (event.type === "step.completed") {
            replayed = event.step.seq <= lastSeq;
            if (!replayed) lastSeq = event.step.seq;
          } else if (!event.type.startsWith("approval.")) {
            replayed = false; // approval frames follow their approval step
          }
          if (!replayed) onEvent(event);
        }
      }
    }
  }
}

التوقيع

الأحداث التي تُرسل إلى نقاط الاستقبال والطلبات التي ترسلها أنت إلى POST /v1/hooks/{trigger_id} موقّعة بطريقة Standard Webhooks، بثلاث ترويسات:

الترويسةالقيمة
webhook-idمعرّف الحدث، نفسه في كل إعادة محاولة (في الخطاف: من 1 إلى 128 محرف ASCII قابل للطباعة تختاره أنت).
webhook-timestampثواني Unix. يقبل الخطاف طابعاً زمنياً في حدود 300 ثانية من ساعة الخادم.
webhook-signaturev1,<base64>، وقد تُرسل عدة توقيعات تفصل بينها مسافات (توقيع لكل سر أثناء التدوير).

التوقيع هو HMAC-SHA256 للنص <webhook-id>.<webhook-timestamp>.<body> بمفتاح هو بايتات السر بعد whsec_ (جزء base64 بعد فك ترميزه)، مرمّزاً بـ base64. احسبه على الجسم الخام كما وصل، قبل تحليل JSON، وقارن بزمن ثابت.

التحقق من حدث وصل إلى نقطة استقبالك

بمكتبة crypto في Node ومكتبة hmac في Python، دون أي حزمة إضافية:

import { createHmac, timingSafeEqual } from "node:crypto";

// secret: the endpoint's whsec_... secret. body: the raw request body, before JSON.parse.
export function verifyWebhook(secret, headers, body) {
  const id = headers["webhook-id"];
  const timestamp = headers["webhook-timestamp"];
  const signatures = headers["webhook-signature"];
  if (!id || !timestamp || !signatures || !/^[0-9]+$/.test(timestamp)) return false;
  // Refuse stale timestamps (the platform allows 300 s on hooks).
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
  const expected = createHmac("sha256", key).update(`${id}.${timestamp}.${body}`).digest();
  // Several space-separated signatures can arrive (one per secret during a rotation).
  return signatures.split(" ").some((entry) => {
    const [version, value] = entry.split(",");
    if (version !== "v1" || !value) return false;
    const given = Buffer.from(value, "base64");
    return given.length === expected.length && timingSafeEqual(given, expected);
  });
}

إطلاق مشغّل webhook من خدمتك

الجسم JSON بحجم 64 KiB على الأكثر، بنوع application/json. التوقيع الخاطئ أو المفقود، والطابع الزمني القديم، والمشغّل غير المعروف كلها تُجاب بنفس 401 invalid_signature. وإرسال نفس webhook-id مرة أخرى يُجاب 200 بالانطلاق الأول ولا يبدأ شيئاً.

import { createHmac, randomUUID } from "node:crypto";

// Fire a webhook trigger from your service. No API key: the request is signed with the
// trigger's whsec_... secret (shown once, when the trigger was created or rotated).
const secret = process.env.TRIGGER_SECRET;
const body = JSON.stringify({ order_id: "A-1042", status: "delayed" });
const id = randomUUID(); // send the same webhook-id again when you retry
const timestamp = String(Math.floor(Date.now() / 1000));
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const signature = createHmac("sha256", key).update(`${id}.${timestamp}.${body}`).digest("base64");

const res = await fetch(`https://api.mindlabsa.com/v1/hooks/${process.env.TRIGGER_ID}`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "webhook-id": id,
    "webhook-timestamp": timestamp,
    "webhook-signature": `v1,${signature}`,
  },
  body,
});
// 202: { fire: { id, outcome, run_id } }; 200: this webhook-id was already received.
console.log(res.status, await res.json());
جسم الخطاف يصبح جزءاً من أول رسالة مستخدم في التشغيل، معلَّماً كبيانات من خارج المنصة، ويُرسَل إلى النموذج. لذلك تحتاج كتابات ذلك التشغيل موافقة ما لم تقل سياسته غير ذلك.

التكلفة

  • المبالغ بالريال السعودي (SAR) كنصوص عشرية بست خانات، مثل "0.012500". في cost للتشغيل: model وtools وtotal.
  • المبلغ null يعني غير معروف: استُخدم شيء لا سعر له. لا يُحسب صفراً أبداً، وtotal يكون null إن كان model أو tools كذلك.
  • تُجمَّد الأسعار عند بدء التشغيل (cost.prices): السعر الذي يتغير بعدها لا يغيّر تكلفته.
  • يُفحص max_cost_sar قبل كل جولة للنموذج مقابل الأجزاء المسعّرة من التكلفة فقط، فقد يتجاوزه التشغيل بتكلفة جولة واحدة قبل أن ينتهي budget_exceeded.
  • يجمع GET /v1/agents/usage تشغيلاتك المنتهية حسب اليوم (بتوقيت UTC) أو حسب الوكيل، على مدى 92 يوماً على الأكثر: عدد التشغيلات وكيف انتهت، والرموز، واستدعاءات الأدوات، وcost_sar وهي تكلفة التشغيلات المسعّرة وحدها؛ أما التشغيل المجهولة تكلفته فيُعدّ في unpriced_runs.

الحدود والأخطاء

لكل خطأ الجسم نفسه: {"error": {"message", "type", "code", "param"}}. تعامل مع error.code (تُضاف الرموز ولا يُعاد تسميتها) لا مع الرسالة. الرفض بسبب التحقق من الصحة أو غياب المفتاح أو حد الطلبات يحمل type فقط، وparam يسمّي الحقل المخطئ إن وُجد.

الحد 120 طلباً في الدقيقة لكل مفتاح، مع حد لكل عنوان عميل. ردود 429 تحمل Retry-After (ثوانٍ كاملة) حيث يذكرها المسار: انتظرها ثم أعد المحاولة. حدود التشغيلات والمشغّلات ونقاط الاستقبال وعمليات التسليم تُعرف برموزها أدناه، وقيمها ليست نهائية بعد.

الرمزHTTPالمعنى
invalid_request400حقل يخالف قاعدة في المسار (يسمّيه param)، أو الجسم ليس JSON في الخطاف.
url_refused400العنوان غير مسموح (تسمّي الرسالة القاعدة): https والمنفذ 443 واسم DNS عام.
invalid_signature401تعذّر التحقق من توقيع الخطاف أو طابعه الزمني أو المشغّل.
scope_required403المفتاح لا يملك النطاق المطلوب: agents، أو agents.approve للقرار في موافقة.
agent_held403, 503فريق تشغيل المنصة يُوقف الوكيل أو حسابك مؤقتاً (operator_hold): يُرفض بدء التشغيل (403)، ولا يبدأ انطلاق مشغّل webhook شيئاً (503؛ أعد المحاولة بنفس webhook-id بعد Retry-After).
permission_denied403مفتاح لا تتصرف به المنصة لهذا الطلب: مفتاح داخلي، أو مفتاح بلا مالك، أو المفتاح الذي بدأ التشغيل يحاول البتّ في موافقته.
model_not_permitted403المفتاح لا يحق له استدعاء النموذج (يسمّيه param).
not_enabled403, 503الميزة غير مفعّلة على المنصة: أدوات HTTP أو الـ Webhooks الصادرة أو المشغّلات.
agent_not_found404الوكيل غير موجود أو ليس لك.
agent_version_not_found404لا إصدار للوكيل يمكن تشغيله.
approval_not_found404الموافقة غير موجودة أو ليست لك.
connection_not_found404الاتصال غير موجود أو ليس لك.
delivery_not_found404لا توجد عملية التسليم هذه لنقطة الاستقبال.
model_not_found404النموذج ليس من النماذج التي تعرفها المنصة.
run_not_found404التشغيل غير موجود أو ليس لك.
thread_not_found404المحادثة غير موجودة أو ليست لك.
tool_not_found404الأداة غير موجودة أو ليست لك.
trigger_not_found404المشغّل غير موجود أو ليس لك.
webhook_not_found404نقطة الاستقبال غير موجودة أو ليست لك.
approval_closed409أُلغيت الموافقة أو انتهى تشغيلها.
approval_decided409سبق البتّ في الموافقة بالقرار الآخر.
approval_expired409انتهت مهلة الموافقة.
connection_limit_reached409بلغت الحد الأعلى لعدد الاتصالات.
connection_name_taken409لديك اتصال بهذا الاسم.
endpoint_disabled409نقطة الاستقبال معطّلة؛ فعّلها أولاً.
event_expired409لم يعد الحدث محفوظاً.
name_taken409لديك مشغّل بهذا الاسم.
slug_taken409لديك وكيل بهذا المعرّف المختصر (slug).
thread_agent_mismatch409المحادثة تخص وكيلاً آخر.
thread_busy409في المحادثة تشغيل قيد التنفيذ.
tool_exists409لديك أداة بهذا الاسم: أضف مراجعة لها.
tool_limit_reached409بلغت الحد الأعلى لأسماء الأدوات.
trigger_paused409المشغّل متوقف مؤقتاً (رفضُ انطلاقٍ بسبب مفتاحه أو وكيله أو نموذجه يوقفه أيضاً).
unsupported_media_type415جسم الخطاف ليس application/json.
active_runs_limit429لديك تشغيلات كثيرة في الانتظار أو قيد التنفيذ؛ أعد المحاولة حين ينتهي أحدها.
admission_busy429بدايات كثيرة في وقت واحد لحسابك؛ أعد المحاولة بعد قليل.
daily_runs_limit429تشغيلات كثيرة بدأت خلال آخر 24 ساعة.
deliveries_limit429عمليات تسليم كثيرة تنتظر الإرسال؛ أعد المحاولة بعد إرسالها.
endpoints_limit429بلغت الحد الأعلى لنقاط الاستقبال.
rate_limited429طلبات كثيرة لهذا المشغّل، أو تشغيلاته عند حدٍّ ما؛ أعد المحاولة لاحقاً.
too_many_streams429للمفتاح عدد البثوث الأقصى مفتوحاً على هذا الخادم؛ أغلق أحدها أو أعد المحاولة لاحقاً.
triggers_limit429بلغت الحد الأعلى للمشغّلات.
internal_error500تعذّرت معالجة الخطاف؛ أعد المحاولة بنفس webhook-id.
connections_unavailable503لا يمكن حفظ الأسرار على هذا النشر حالياً.
no_model_available503تعذّر التحقق من قائمة نماذج المفتاح حالياً؛ أعد المحاولة لاحقاً.
triggers_unavailable503لا يمكن حفظ أسرار المشغّلات على هذا النشر حالياً.
webhooks_unavailable503لا يمكن حفظ أسرار نقاط الاستقبال على هذا النشر حالياً.