تخطَّ إلى المحتوى
المحتويات
المرجع

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

غلاف واحد لكل إخفاق، ورمز ثابت لكل سبب، ومعرّف طلب على كل استجابة. وهذه الصفحة سطح الإخفاق كاملا: الرموز والحالات وتقسيم الصفحات وتحديد المعدل.

غلاف الخطأ

كل خطأ، من كل نقطة، له الشكل نفسه. لا توجد صيغة ثانية ولا استجابة نصية مجردة.

HTTP
HTTP/1.1 422 Unprocessable Entity
content-type: application/json; charset=utf-8
x-request-id: req_...

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request payload failed validation.",
    "request_id": "req_...",
    "details": {
      "issues": [
        { "path": "to", "message": "must be an E.164 number, e.g. +9665XXXXXXXX" }
      ]
    }
  }
}
الحقلالوصف
error.codeمعرّف ثابت مقروء آليا. وهذا ما يتفرّع عليه كودك.
error.messageنص إنجليزي للإنسان. مفيد في السجل؛ ولا تطابق عليه أبدا.
error.request_idوهو أيضا الـ header المسمى X-Request-Id. يحدد هذا الطلب بعينه في سجلات المنصة.
error.detailsموجود لبعض الرموز فقط. وشكله يتبع الرمز — خطأ التحقق يحمل issues، وخطأ الاستحقاق يحمل الحد والعدد الحالي.

تفرّع على code لا على message

الـ code جزء من عقد الـ API ولن يتغيّر معناه دون رفع الإصدار. أما الـ message فنص بشري يمكن إعادة صياغته في أي وقت. والمطابقة عليه أسرع طريق لبناء تكامل ينكسر عند تحرير لغوي.

أخطاء التحقق

الطلب غير السليم يعطي 422 مع قائمة مقروءة آليا بما كان خطأ.

  • إخفاقات التحقق هي 422 لا 400. والـ 400 الوحيد في الـ API كلها هو غياب سياق مساحة العمل.
  • docs.pages.errors.validation.rules.issues
  • القيمة التي أرسلتها لا تُعاد إليك أبدا، فتسجيل الخطأ آمن حتى لو حمل الطلب شيئا حساسا.
  • معظم أجسام الكتابة صارمة: الحقل المجهول خطأ لا مفتاح يُتجاهل. والاسم المكتوب خطأ يخفق بصوت عال.

رموز الأخطاء

الدليل العام كاملا: 72 رمزا، مجموعة كما تجمعها المنصة. وعمود الرسالة هو نص الـ API الإنجليزي نفسه منقولا حرفيا — فهو بيانات استجابة لا نثر توثيق، ولهذا لم يُترجم.

قد تُضاف رموز إلى هذه القائمة. أما الرمز الموجود فلا يغيّر معناه ولا يختفي دون رفع إصدار الـ API.

النقل والمصادقة

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
UNAUTHORIZED401Authentication is required or the provided credentials are invalid.
FORBIDDEN403You do not have permission to perform this action.
NOT_FOUND404The requested resource was not found.
METHOD_NOT_ALLOWED405That HTTP method is not allowed on this resource.
VALIDATION_ERROR422The request payload failed validation.
CONFLICT409The request conflicts with the current state of the resource.
PAYLOAD_TOO_LARGE413The request payload is too large.
UNSUPPORTED_MEDIA_TYPE415The request content type is not supported.
RATE_LIMITED429Too many requests. Please retry later.
IDEMPOTENCY_CONFLICT409This idempotency key was already used with a different request payload.
INTERNAL_ERROR500An unexpected error occurred while processing the request.
SERVICE_UNAVAILABLE503The service is temporarily unavailable. Please retry later.

الحسابات وتسجيل الدخول

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
INVALID_CREDENTIALS401The email address or password is incorrect.
EMAIL_ALREADY_IN_USE409An account already exists for that email address.
EMAIL_NOT_VERIFIED403Verify your email address before continuing.
ACCOUNT_SUSPENDED403This account is suspended.
TOKEN_INVALID401That link or token is invalid or has already been used.
TOKEN_EXPIRED401That link or token has expired. Request a new one.

مساحات العمل والأعضاء والفرق

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
WORKSPACE_NOT_FOUND404The requested workspace was not found.
WORKSPACE_SUSPENDED403This workspace is suspended.
WORKSPACE_CONTEXT_REQUIRED400A workspace must be specified for this request.
MEMBER_NOT_FOUND404The requested workspace member was not found.
MEMBER_ALREADY_EXISTS409That person is already a member of this workspace.
OWNER_REQUIRED403Only the workspace owner can perform this action.
INVITATION_NOT_FOUND404The requested invitation was not found.
TEAM_NOT_FOUND404The requested team was not found.

مفاتيح API والخطط

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
API_KEY_NOT_FOUND404The requested API key was not found.
API_KEY_REVOKED401This API key has been revoked.
PLAN_NOT_FOUND404The requested plan was not found.
ENTITLEMENT_LIMIT_REACHED409The current plan limit for this resource has been reached.

القنوات والمزوّدون

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
CHANNEL_NOT_FOUND404The requested channel was not found.
CHANNEL_NOT_CONNECTED409The selected channel is not connected.
CHANNEL_CAPABILITY_UNAVAILABLE409The selected channel does not support this capability.
PROVIDER_RATE_LIMITED429The upstream messaging provider is rate limiting this channel.
PROVIDER_REJECTED502The upstream messaging provider rejected this request.

الـ Sandbox

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
SANDBOX_RECIPIENT_NOT_VERIFIED403The recipient is not verified for this sandbox allocation.
SANDBOX_TEST_KEY_REQUIRED403A test-mode API key is required for sandbox operations.
SANDBOX_SESSION_NOT_FOUND404The requested sandbox session was not found.
SANDBOX_SESSION_EXPIRED409This sandbox session has expired. Request a new one.
SANDBOX_NO_NUMBER_AVAILABLE503No shared test number is available right now. Please retry shortly.
SANDBOX_VERIFICATION_PENDING409Send the verification code from the recipient number to the assigned test number to complete verification.
SANDBOX_VERIFICATION_INVALID422That verification code is incorrect.
SANDBOX_VERIFICATION_EXPIRED409That verification code has expired. Request a new one.

جهات الاتصال والمجموعات والاستيراد

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
CONTACT_NOT_FOUND404The requested contact was not found.
CONTACT_ALREADY_EXISTS409A contact with that phone number already exists in this workspace.
CONTACT_GROUP_NOT_FOUND404The requested contact group was not found.
TAG_NOT_FOUND404The requested tag was not found.
IMPORT_NOT_FOUND404The requested import was not found.
IMPORT_FILE_TOO_LARGE413The uploaded file is larger than the import limit.
IMPORT_FORMAT_UNSUPPORTED415That file format is not supported for contact import.

المحادثات والإسناد

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
CONVERSATION_NOT_FOUND404The requested conversation was not found.
CONVERSATION_ACCESS_DENIED403You do not have access to this conversation.
ASSIGNEE_NOT_FOUND404The requested assignee was not found in this workspace.
CONVERSATION_CONFLICT409This conversation was changed by someone else. Reload and try again.
NOTE_NOT_FOUND404The requested note was not found.

القوالب

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
TEMPLATE_NOT_FOUND404The requested template was not found.
TEMPLATE_NOT_APPROVED409The requested template is not approved for sending.
TEMPLATE_ALREADY_EXISTS409A template with that name and language already exists.
TEMPLATE_VARIABLE_MISSING422One or more template variables were not supplied.
TEMPLATE_NOT_SENDABLE409This template is not available for sending.
META_SERVICE_WINDOW_REQUIRED_TEMPLATE409The customer service window is closed. Send an approved template instead.

QR

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
QR_SAFETY_LIMIT_REACHED429The channel safety limit for this period has been reached.

الـ Webhooks

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
WEBHOOK_ENDPOINT_NOT_FOUND404The requested webhook endpoint was not found.
WEBHOOK_DELIVERY_NOT_FOUND404The requested webhook delivery was not found.
WEBHOOK_ENDPOINT_DISABLED409This webhook endpoint was disabled after repeated delivery failures. Update it and set it back to active.
WEBHOOK_URL_NOT_ALLOWED422That webhook URL is not accepted by this environment.

الحملات والأتمتة

رموز محجوزة

هذه الرموز معرّفة وثابتة، لكن لا نقطة تصدرها: فالحملات والأتمتة غير مبنية. وقد سُردت حتى لا يُفاجأ عميل يعالجها أصلا لاحقا، لا لأنك ستراها اليوم.

الرمزHTTPالرسالة الافتراضية التي تعيدها الـ API
CAMPAIGN_NOT_FOUND404The requested campaign was not found.
CAMPAIGN_PAUSED409The campaign is paused.
CAMPAIGN_INVALID_STATE409That action is not available while the campaign is in its current state.
CAMPAIGN_AUDIENCE_EMPTY422The selected audience contains no contacts that may receive a marketing message.
CAMPAIGN_CHANNEL_NOT_ELIGIBLE409The selected channel cannot be used to run a campaign.
AUTOMATION_LIMIT_REACHED409The automation execution limit has been reached.

حالات HTTP

الحالة تخبرك بصنف المشكلة؛ والرمز يخبرك أيّها.

HTTPالوصف
400لم تُحدَّد مساحة عمل. وهذا هو الـ 400 الوحيد في الـ API.
401لا بيانات اعتماد، أو بيانات غير صالحة.
403بيانات اعتماد صحيحة لكنها غير مسموحة هنا، أو حساب أو مساحة عمل موقوفة.
404المورد غير موجود، أو يخص مساحة عمل أخرى — والاثنان لا يمكن التمييز بينهما عمدا.
409الطلب يتعارض مع الحالة الراهنة: قناة غير متصلة، أو حد خطة، أو تعارض حماية من التكرار.
413الحمولة أكبر من الحد.
415نوع المحتوى أو صيغة الملف غير مدعومة.
422أخفقت الحمولة في التحقق. راجع details.issues.
429تجاوز حد المعدل. اقرأ Retry-After.
500إخفاق غير متوقع في المنصة. إعادة المحاولة آمنة.
502رفض مزوّد الرسائل الأعلى الطلب.
503تبعية غير متاحة مؤقتا. إعادة المحاولة آمنة.

التحقق 422 لا 400

إن كان عميلك يعامل 400 حالةَ التحقق فسيفوته كل خطأ تحقق تنتجه هذه الـ API. والـ 400 الوحيد هو WORKSPACE_CONTEXT_REQUIRED.

تقسيم الصفحات

قوائم النتائج مقسّمة بالـ cursor. اقرأ page.next_cursor وأعده في after؛ وتوقّف حين تصير has_more بقيمة false.

curl
curl "https://whats.azzamkh.sa/api/v1/messages?limit=50" \
  -H "Authorization: Bearer $WA_API_KEY"

# 200 OK
# {
#   "data": [ { "id": "msg_...", ... } ],
#   "page": { "next_cursor": "bXNnXzAxSj...", "has_more": true }
# }

# Follow the cursor. Send it back verbatim; it is opaque.
curl "https://whats.azzamkh.sa/api/v1/messages?limit=50&after=bXNnXzAxSj..." \
  -H "Authorization: Bearer $WA_API_KEY"
المعاملالافتراضيالوصف
limit50يُحصر بين 1 و100.
afterقيمة next_cursor من الصفحة السابقة.
  • قيمة limit الخارجة عن المدى أو غير القابلة للقراءة تُحصر ولا تُرفض. فطلب 5000 صف يعيد 100.
  • الـ cursor مبهم. أعده كما هو ولا تفكّه — والمشوّه منه يُتجاهل فتحصل على الصفحة الأولى ثانية بصمت.
  • معظم القوائم الأحدث أولا، لكن القوالب الأقدم أولا. لا تفترض اتجاها؛ اتبع الـ cursor.
  • قيمة next_cursor تكون null في الصفحة الأخيرة. كرّر على has_more لا على مصفوفة data فارغة.

تحديد المعدل

المسارات المحدودة تجيب بـ 429 مع الـ headers القياسية وتلميح إعادة المحاولة في الجسم.

HTTP
HTTP/1.1 429 Too Many Requests
ratelimit-limit: 600
ratelimit-remaining: 0
ratelimit-reset: 37
retry-after: 37

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Please retry later.",
    "request_id": "req_...",
    "details": { "bucket": "messages.send", "retry_after_s": 37 }
  }
}
Headerالوصف
RateLimit-Limitالسقف لهذا الدلو وهذه النافذة.
RateLimit-Remainingكم طلبا بقي في النافذة الحالية. وصفر عند الرفض.
RateLimit-Resetثوان حتى تُصفَّر النافذة.
Retry-Afterثوان الانتظار. موجود عند الرفض فقط. التزم به.
  • كل القيم بالـ ثواني لا طوابع زمنية.
  • تغيب هذه الـ headers حين يكون تحديد المعدل مطفأ في البيئة. عامل غيابها انعدامَ معلومة لا حصةً بلا حد.
  • المحدِّد يخفق مفتوحا: إن تعذّر مخزنه سُمح بالطلبات. فلا تعتمد عليه آلية صحّة أبدا.
  • الرمز PROVIDER_RATE_LIMITED شيء آخر: مزوّد واتساب الأعلى يخنق القناة، ولا header يخبرك متى يتوقف.

ماذا تعيد

أعد المحاولة بتباعد أسّي وعشوائية، وأرسل دائما Idempotency-Key مع أي كتابة حتى لا تكرر إعادة المحاولة شيئا.

الرمزما ينبغي فعله
RATE_LIMITEDانتظر مدة Retry-After ثم أعد. ولا تعد قبلها.
PROVIDER_RATE_LIMITEDتباعد أكثر — المزوّد الأعلى يخنق، ولا header يخبرك متى يتوقف.
SERVICE_UNAVAILABLEأعد بتباعد. تبعية متوقفة مؤقتا.
INTERNAL_ERRORأعد بتباعد. وإن استمر فاذكر قيمة request_id.
PROVIDER_REJECTEDلا تعد بغير تفكير. المزوّد رفض الرسالة؛ افحصها أولا.
VALIDATION_ERRORلا تعد أبدا. أصلح الطلب.
IDEMPOTENCY_CONFLICTلا تعد كما هو أبدا. إما الجسم خطأ وإما المفتاح.