تنبيه API

استعلم عن أي حساب ديسكورد من بوتك أو من موقعك، واحصل على ما لدينا من بلاغات عليه

فيم تستخدمه

سؤال واحد: هل على هذا الحساب بلاغ لدينا؟ طلب واحد يأتي بالجواب، وتبني فوقه ما تحتاجه

استخدامان متوقعان: بوت يفحص العضو عند دخوله السيرفر، وسيرفر بيع وشراء يفحص الطرف الآخر قبل إتمام الصفقة. وكل ما يرجع بياناتُ بلاغات منشورة أصلاً، ولا توجد فيه معلومة شخصية واحدة.

/flags/{userId}
GET /api/v1/flags/987654321098765432
Authorization: Bearer tnbeh_live_EXAMPLEONLY_notARealKey_9f2c4b7d8e1a3c5b7d9

HTTP/1.1 200 OK
{
  "userId": "987654321098765432",
  "state": "clear",
  "flagged": false,
  "summary": { "total": 0, "scammer": 0, "traitor": 0, "dwc": 0 },
  "flags": []
}

كيف تأخذ مفتاحاً

المفتاح تابع لحسابك في ديسكورد، والفريق هو مَن يصدره

  1. اطلبه في سيرفر تنبيه

    أخبرنا لأي حساب ديسكورد يكون المفتاح وأين ستستخدمه. نقرأ اسمك وصورتك ومعرّفك، ولا شيء غيرها: لا نصل إلى رسائلك ولا إلى سيرفراتك ولا إلى أي شيء خاص.

  2. نصرفه لك، مرة واحدة

    من قسم الـ API في لوحة التحكم. ثلاثة مفاتيح حدّاً أعلى للحساب، ولكل مفتاح اسم لتعرف لاحقاً أين تستخدمه، والمفتاح نفسه محفوظ مشفَّراً، فليست عندنا نسخة منه.

  3. أرسله مع كل طلب

    في هيدر Authorization. المفتاح يُعرض مرة واحدة عند إنشائه، وبعدها لا نستطيع عرضه لك مرة ثانية، بل نستطيع تبديله فقط.

إصدار المفتاح وسحبه مسار بذاته (tnbeh.com/api/v1/keys)، ومصادقته بجلسة لوحة التحكم، لا بمفتاح. ولهذا ليس مذكوراً في القائمة أدناه: المفتاح القادر على إنشاء مفاتيح لا يمكن سحبه، لأن صاحبه ينشئ غيره.

المصادقة

هيدر واحد، ولا شيء غيره

Authorization
Authorization: Bearer tnbeh_live_EXAMPLEONLY_notARealKey_9f2c4b7d8e1a3c5b7d9
المفتاح لا يُوضع في الرابط

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

المسارات

ثلاثة مسارات، كلها GET، وكلها تحت قاعدة واحدة، والرد دائماً JSON

القاعدة https://tnbeh.com/api/v1

GET /flags/{userId}

فحص حساب

البلاغات على آيدي واحد، الأحدث أولاً، ومعها عدد لكل نوع

المعاملالنوعإلزاميالوصف
userIdstringنعمآيدي حساب ديسكورد، من ١٧ إلى ٢٠ رقماً، في المسار نفسه

الطلب

/flags/{userId}
GET /api/v1/flags/123456789012345678
Authorization: Bearer tnbeh_live_EXAMPLEONLY_notARealKey_9f2c4b7d8e1a3c5b7d9

الرد

200 OK
{
  "userId": "123456789012345678",
  "state": "flagged",
  "flagged": true,
  "summary": { "total": 2, "scammer": 1, "traitor": 1, "dwc": 0 },
  "flags": [
    {
      "type": "scammer",
      "reason": "باع حساب ما يملكه",
      "caseId": "TN-00042",
      "createdAt": "2026-04-18T19:05:00.000Z"
    },
    {
      "type": "traitor",
      "reason": "استلم أول وما سلّم",
      "caseId": "TN-00017",
      "createdAt": "2025-11-30T08:22:00.000Z"
    }
  ]
}

الرد: حساب لا شيء عليه

200 OK
{
  "userId": "987654321098765432",
  "state": "clear",
  "flagged": false,
  "summary": { "total": 0, "scammer": 0, "traitor": 0, "dwc": 0 },
  "flags": []
}

الرد: حساب ليس لدينا عنه شيء

200 OK
{
  "userId": "111111111111111111",
  "state": "unknown",
  "flagged": false,
  "summary": { "total": 0, "scammer": 0, "traitor": 0, "dwc": 0 },
  "flags": []
}
GET /flags

فحص مجموعة

حتى خمسين معرّفاً في طلب واحد، للبوت الذي يفحص قائمة أعضاء. والرد أعداد فقط، وللتفصيل عن حساب واحد تعود إلى المسار الأول

المعاملالنوعإلزاميالوصف
idsstringنعممعرّفات مفصولة بفاصلة، من واحد إلى خمسين

الطلب

/flags
GET /api/v1/flags?ids=123456789012345678,987654321098765432
Authorization: Bearer tnbeh_live_EXAMPLEONLY_notARealKey_9f2c4b7d8e1a3c5b7d9

الرد

200 OK
{
  "requested": 2,
  "results": [
    { "userId": "123456789012345678", "state": "flagged", "flagged": true,  "total": 2 },
    { "userId": "987654321098765432", "state": "unknown", "flagged": false, "total": 0 }
  ]
}
GET /me

مفتاحك نفسه

ما هذا المفتاح، وكم بقي لك من الدقيقة الحالية. وهو المسار الذي تعود إليه عند الشك في أن المشكلة في المصادقة

الطلب

/me
GET /api/v1/me
Authorization: Bearer tnbeh_live_EXAMPLEONLY_notARealKey_9f2c4b7d8e1a3c5b7d9

الرد

200 OK
{
  "keyId": "key_7Qd12ba9",
  "label": "trade-bot",
  "createdAt": "2026-02-09T11:40:00.000Z",
  "rateLimit": { "limit": 60, "remaining": 58, "resetAt": "2026-09-25T10:15:00.000Z" },
  "idsPerHour": { "limit": 20000, "remaining": 19871 }
}

شكل الرد

دائماً JSON، ودائماً الحقول نفسها. والحقل الذي لا شيء فيه يرجع بقيمته الفارغة (صفراً، أو مصفوفة فارغة)، ولا يرجع null أبداً

state
flagged أو clear أو unknown. و clear تعني أن عندنا سجلاً عن الحساب ولا شيء عليه إلى الآن، و unknown تعني أنه ليس عندنا عنه شيء أصلاً، وليستا الجملة نفسها ولا تبرئة
flagged
صحيح إذا كان على الحساب بلاغ واحد على الأقل
summary
عدد البلاغات لكل نوع، وصفر للنوع الذي لا شيء عليه
flags
البلاغات نفسها، الأحدث أولاً، ومصفوفة فارغة للحساب الذي لا شيء عليه
flags[].type
ما يقوله البلاغ: scammer (خائن للثقة) أو traitor (نصاب) أو dwc (تعامل بحذر، لحساب يُتعامل معه على مسؤوليتك)
flags[].reason
السبب كما كتبه الفريق، ومعنى ذلك أنه بالعربية. وقد تُحذف منه الروابط.
flags[].caseId
رقم السجل بالصيغة TN-00042: يُمنح للبلاغ مرة واحدة عند تقديمه ولا يُعاد استخدامه أبدًا، فيدل على بلاغ واحد بعينه، وهو الرقم نفسه الذي تطبعه بطاقة ديسكورد وصفحة الدلائل. والبلاغ الذي يُقدَّم في أثناء تحديث الخدمة، قبل أن يُمنح رقمه، يعود بصيغته السابقة TN-YYYY-MMDD-n حتى يُرقَّم.
flags[].createdAt
متى سُجّل البلاغ. بصيغة ISO 8601 وبتوقيت UTC، في كل اللغات

وعندما يفشل الطلب

الخطأ له شكله الخاص: كود ثابت تبني عليه، ورسالة إنجليزية مكتوبة لمن يقرأ السجلات. الرسالة لا تُعرض للمستخدم.

400 Bad Request
{
  "error": {
    "code": "INVALID_USER_ID",
    "message": "user id must be 17-20 digits"
  }
}

الحد

ستون طلباً في الدقيقة، محسوبة على المفتاح

  • النافذة

    دقيقة متحركة لا دقيقة ساعة: المحسوب هو آخر ستين ثانية

  • الفحص الجماعي

    طلب واحد، وإن كان فيه خمسون معرّفاً. هذا سبب وجوده

  • الآيديات في الساعة

    عشرون ألفاً في الساعة، تُحسب لكل مفتاح ولكل معرّف مختلف. وستون طلباً بخمسين معرّفاً تساوي ثلاثة آلاف في الدقيقة، فهذا السقف هو ما يحدد كم يمكن أن يخرج من السجل

  • الهيدرات

    كل رد يحمل X-RateLimit-Limit و X-RateLimit-Remaining و X-RateLimit-Reset لمفتاحك. وأما الـ RateLimit-* المجاورة لها فهي حد الموقع على عنوانك، وهو سقف آخر

  • إذا تجاوزت الحد

    429، ومعه Retry-After بالثواني. انتظر المدة، لأن إعادة المحاولة فوراً تستهلك النافذة الجديدة أيضاً

429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1790000012

{ "error": { "code": "RATE_LIMITED", "message": "60 requests per minute exceeded" } }

الأخطاء

ابنِ على الكود. لا على الرسالة لأنها كلام، ولا على رقم الحالة وحده لأن كودين يشتركان فيه

الكودالحالةما يسببه
UNAUTHORIZED401لا يوجد هيدر Authorization في الطلب
INVALID_KEY401الهيدر موجود لكن شكل المفتاح خاطئ، أو المفتاح غير موجود
KEY_REVOKED403المفتاح مسحوب، إما أنت حذفته أو نحن سحبناه
INVALID_USER_ID400ليس معرّف ديسكورد: أرقام فقط، من ١٧ إلى ٢٠ خانة
TOO_MANY_IDS400أكثر من خمسين معرّفاً في طلب مجموعة واحد
RATE_LIMITED429تجاوزت ستين طلباً في الدقيقة، وRetry-After يخبرك كم تنتظر
PAYLOAD_TOO_LARGE413جسم الطلب أكبر مما يقبله الـ endpoint. ويُرفض من الـ Content-Length قبل قراءته، فلا حاجة إلى إرساله.
SERVICE_UNAVAILABLE503الخدمة مغلقة عن قصد في الوقت الحالي: وضع صيانة أو توقّف الفحص. أعد المحاولة لاحقاً، وليست هذه عِلّة برمجية.
SERVER_ERROR500خلل عندنا. أعد المحاولة بعد قليل، لا في حلقة متواصلة

المفتاح الذي يستمر في السحب فوق سقفه الساعي يتوقف الرد عليه، ويراجعه شخص قبل سحبه. والمفتاح المسحوب لا يعود.

تريد مفتاحاً؟

اطلبه في سيرفر تنبيه وأخبرنا بما تبنيه. وإن كان كل ما تحتاجه فحصاً داخل سيرفرك، فالبوت يقوم به اليوم بلا مفتاح.