{"openapi":"3.1.0","info":{"title":"Nabaa Platform API — منصّة نبأ","version":"2.0.0","summary":"Unified CX, messaging, ticketing & CRM API for Riyadah platforms.","description":"## English\n\nThe **Nabaa Platform API** is the unified, Arabic-first customer-experience\nand communications gateway for the Riyadah ecosystem. A single set of API\ncredentials lets you send **SMS** (Taqnyat), **WhatsApp Business** messages\n(Meta Cloud API), manage **contacts/CRM**, drive **live-chat** sessions,\nregister **push devices**, and subscribe to signed **webhooks** for the full\nmessage lifecycle.\n\nAll endpoints are tenant-scoped: every request is authenticated with an\n`X-API-Key` + `X-API-Secret` pair that resolves to exactly one client\n(tenant). You never see another tenant's data.\n\n## العربية\n\nمنصّة **نبأ** هي بوّابة تجربة العملاء والاتصالات الموحّدة لمنظومة رياضة،\nعربيّة أوّلًا. تتيح لك مجموعة واحدة من بيانات الاعتماد إرسال **الرسائل النصّية**،\nورسائل **واتساب للأعمال**، وإدارة **جهات الاتصال/إدارة العلاقات**، وتشغيل\nجلسات **الدردشة الحيّة**، وتسجيل **أجهزة الإشعارات**، والاشتراك في\n**Webhooks** موقّعة لتتبّع دورة حياة الرسالة بالكامل.\n\nكل المسارات معزولة لكل مستأجر: كل طلب يُصادَق عليه بزوج\n`X-API-Key` + `X-API-Secret` يحدّد عميلًا (مستأجرًا) واحدًا فقط.","termsOfService":"https://nabaa.riyadah.cloud/terms","contact":{"name":"Riyadah — فريق نبأ","url":"https://nabaa.riyadah.cloud","email":"support@riyadah.org.sa"},"license":{"name":"Proprietary — Riyadah","url":"https://nabaa.riyadah.cloud/terms"}},"externalDocs":{"description":"Developer portal & guides — بوّابة المطوّرين","url":"https://nabaa.riyadah.cloud/developers"},"servers":[{"url":"https://api.nabaa.riyadah.cloud","description":"Production — الإنتاج"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"SMS","description":"إرسال الرسائل النصّية عبر تقنيات — Send SMS / OTP / bulk."},{"name":"WhatsApp","description":"رسائل واتساب للأعمال عبر Meta — templates, free-session text, invoices, reminders."},{"name":"Contacts","description":"جهات الاتصال والمجموعات — CRM contacts & groups."},{"name":"Live Chat","description":"جلسات الدردشة الحيّة — embeddable widget + agent routes."},{"name":"Webhooks","description":"نقاط نهاية Webhook الموقّعة — signed event subscriptions."},{"name":"Push","description":"تسجيل أجهزة الإشعارات — Web Push & Expo device registry."},{"name":"Messaging v1","description":"المراسلة الموحّدة (الإصدار 1) — stable versioned SMS + WhatsApp send & cross-channel message log under /api/v1/messaging."},{"name":"Organizations","description":"إدارة المنظّمات (الحسابات) — control-plane: orgs own many platforms (ApiClients). Admin-guarded (AdminAuthGuard), NOT a tenant API-key surface."},{"name":"System","description":"صحّة النظام وبيانات الفهرس — health & catalog."}],"paths":{"/api/sms/send":{"post":{"tags":["SMS"],"operationId":"sendSms","summary":"Send a single SMS — إرسال رسالة واحدة","description":"Sends one SMS to a Saudi/international number. The provider is selected automatically by destination.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendSmsRequest"},"examples":{"notification":{"summary":"Notification","value":{"phone":"0501234567","message":"تم تأكيد طلبك بنجاح","messageType":"NOTIFICATION"}}}}}},"responses":{"200":{"description":"Send result — نتيجة الإرسال","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"},"examples":{"ok":{"value":{"success":true,"message":"تم الإرسال بنجاح","logId":"cl9x0a1b2c3d4e5f6","messageId":"taqnyat-7f3a2b"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/sms/otp":{"post":{"tags":["SMS"],"operationId":"sendOtp","summary":"Send an OTP — إرسال رمز تحقّق","description":"Delivers a one-time passcode, optionally via a named template.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendOtpRequest"},"examples":{"default":{"value":{"phone":"0501234567","code":"482913"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/sms/bulk":{"post":{"tags":["SMS"],"operationId":"sendBulkSms","summary":"Send bulk SMS — إرسال رسائل جماعية","description":"Queues the same message to many numbers as a campaign. Returns a campaignId you can poll via /api/sms/logs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBulkSmsRequest"},"examples":{"default":{"value":{"phones":["0501234567","0559876543"],"message":"عرض خاص لعملائنا الكرام","campaignName":"عرض رمضان"}}}}}},"responses":{"200":{"description":"Queued result — تم وضع الرسائل في قائمة الإرسال","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkQueuedResult"},"examples":{"ok":{"value":{"success":true,"message":"تم إضافة 2 رسالة للإرسال","campaignId":"camp_8821"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/sms/logs":{"get":{"tags":["SMS"],"operationId":"listSmsLogs","summary":"List your SMS logs — سجلّ الرسائل","description":"Returns the authenticated tenant's SMS delivery log, filterable by type/status/phone/date.","parameters":[{"$ref":"#/components/parameters/MessageTypeFilter"},{"$ref":"#/components/parameters/StatusFilter"},{"name":"phone","in":"query","schema":{"type":"string"},"description":"Filter by recipient number."},{"$ref":"#/components/parameters/FromDate"},{"$ref":"#/components/parameters/ToDate"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"SMS log entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SmsLog"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/whatsapp/send":{"post":{"tags":["WhatsApp"],"operationId":"sendWhatsappTemplate","summary":"Send a WhatsApp template message — إرسال قالب واتساب","description":"Sends a business-initiated message using a Meta-approved template. Use {{1}},{{2}}… placeholders via `params`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWhatsappRequest"},"examples":{"template":{"value":{"phone":"0501234567","templateName":"order_confirmation","params":["أحمد","#A-2031"],"language":"ar","messageType":"NOTIFICATION"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/whatsapp/text":{"post":{"tags":["WhatsApp"],"operationId":"sendWhatsappText","summary":"Send a free-session text/media message — رسالة جلسة حرّة","description":"Sends free text or media WITHOUT a template, only valid inside the 24-hour customer-service window.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWhatsappTextRequest"},"examples":{"text":{"value":{"phone":"0501234567","message":"شكرًا لتواصلك معنا 👋"}},"media":{"value":{"phone":"0501234567","mediaUrl":"https://cdn.example.com/receipt.pdf","mediaType":"document"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/whatsapp/invoice":{"post":{"tags":["WhatsApp"],"operationId":"sendWhatsappInvoice","summary":"Send an invoice — إرسال فاتورة","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWhatsappInvoiceRequest"},"examples":{"default":{"value":{"phone":"0501234567","customerName":"أحمد","invoiceNumber":"INV-2031","amount":"450.00","dueDate":"2026-07-01"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/whatsapp/reminder":{"post":{"tags":["WhatsApp"],"operationId":"sendWhatsappReminder","summary":"Send a reminder — إرسال تذكير","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWhatsappReminderRequest"},"examples":{"default":{"value":{"phone":"0501234567","customerName":"أحمد","reminderText":"موعدك غدًا الساعة 10 صباحًا"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/whatsapp/bulk":{"post":{"tags":["WhatsApp"],"operationId":"sendBulkWhatsapp","summary":"Send bulk WhatsApp template — إرسال قوالب جماعية","description":"Queues a template to many numbers as a campaign (≈200ms between sends to respect Meta limits).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendBulkWhatsappRequest"},"examples":{"default":{"value":{"phones":["0501234567","0559876543"],"templateName":"eid_greeting","params":["عميلنا العزيز"],"language":"ar","campaignName":"تهنئة العيد"}}}}}},"responses":{"200":{"description":"Queued result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkQueuedResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/whatsapp/templates":{"get":{"tags":["WhatsApp"],"operationId":"listWhatsappTemplates","summary":"List available templates — القوالب المتاحة","description":"Returns the Meta-approved templates available to your tenant for sending.","responses":{"200":{"description":"Templates","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WhatsappTemplate"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/whatsapp/logs":{"get":{"tags":["WhatsApp"],"operationId":"listWhatsappLogs","summary":"List your WhatsApp logs — سجلّ واتساب","parameters":[{"$ref":"#/components/parameters/MessageTypeFilter"},{"$ref":"#/components/parameters/StatusFilter"},{"name":"phone","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/FromDate"},{"$ref":"#/components/parameters/ToDate"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"WhatsApp log entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WhatsappLog"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/whatsapp/media/{mediaId}":{"get":{"tags":["WhatsApp"],"operationId":"getWhatsappMedia","summary":"Download inbound media — تنزيل وسائط واردة","description":"Streams an inbound media object by its Meta media ID (ownership verified against your tenant).","parameters":[{"name":"mediaId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Raw media bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/messaging/sms":{"post":{"tags":["Messaging v1"],"operationId":"v1SendSms","summary":"Send a single SMS (v1) — إرسال رسالة نصّية","description":"Sends one SMS. Versioned, normalised wrapper over the SMS service: the request uses `to`/`message`/`type`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1SendSmsRequest"},"examples":{"notification":{"value":{"to":"0501234567","message":"تم تأكيد طلبك بنجاح","type":"NOTIFICATION"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/messaging/sms/bulk":{"post":{"tags":["Messaging v1"],"operationId":"v1SendBulkSms","summary":"Send bulk SMS (v1) — إرسال رسائل جماعية","description":"Queues the same message to many numbers as a campaign. Returns a campaignId you can poll via GET /api/v1/messaging/messages.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1SendBulkSmsRequest"},"examples":{"default":{"value":{"to":["0501234567","0559876543"],"message":"عرض خاص لعملائنا الكرام","campaignName":"عرض رمضان"}}}}}},"responses":{"200":{"description":"Queued result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkQueuedResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/messaging/whatsapp":{"post":{"tags":["Messaging v1"],"operationId":"v1SendWhatsapp","summary":"Send a WhatsApp template (v1) — إرسال قالب واتساب","description":"Sends a business-initiated message using a Meta-approved template. Normalised wrapper: `to`/`templateName`/`params`/`type`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1SendWhatsappRequest"},"examples":{"template":{"value":{"to":"0501234567","templateName":"order_confirmation","params":["أحمد","#A-2031"],"language":"ar","type":"NOTIFICATION"}}}}}},"responses":{"200":{"description":"Send result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResult"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/messaging/messages":{"get":{"tags":["Messaging v1"],"operationId":"v1ListMessages","summary":"List recent messages (v1) — سجلّ الرسائل الموحّد","description":"Returns the authenticated tenant's recent messages across BOTH channels in one log, filterable by channel/type/status/phone/date.","parameters":[{"name":"channel","in":"query","schema":{"type":"string","enum":["sms","whatsapp"]},"description":"Restrict to one channel; omit for both."},{"$ref":"#/components/parameters/MessageTypeFilter"},{"$ref":"#/components/parameters/StatusFilter"},{"name":"phone","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/FromDate"},{"$ref":"#/components/parameters/ToDate"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200},"description":"Max items (1–200)."},{"$ref":"#/components/parameters/Offset"}],"responses":{"200":{"description":"Unified message log entries","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/V1Message"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/contacts":{"get":{"tags":["Contacts"],"operationId":"listContacts","summary":"List contacts — جهات الاتصال","parameters":[{"name":"search","in":"query","schema":{"type":"string"},"description":"Free-text search."},{"name":"groupId","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1}}],"responses":{"200":{"description":"Paginated contacts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Contacts"],"operationId":"createContact","summary":"Create a contact — إنشاء جهة اتصال","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInput"},"examples":{"default":{"value":{"name":"أحمد العتيبي","phone":"0501234567","email":"a@example.com"}}}}}},"responses":{"201":{"description":"Created contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/contacts/{id}":{"get":{"tags":["Contacts"],"operationId":"getContact","summary":"Get a contact — جلب جهة اتصال","parameters":[{"$ref":"#/components/parameters/ContactId"}],"responses":{"200":{"description":"Contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Contacts"],"operationId":"updateContact","summary":"Update a contact — تحديث جهة اتصال","parameters":[{"$ref":"#/components/parameters/ContactId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInput"}}}},"responses":{"200":{"description":"Updated contact","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Contacts"],"operationId":"deleteContact","summary":"Delete a contact — حذف جهة اتصال","parameters":[{"$ref":"#/components/parameters/ContactId"}],"responses":{"200":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/contacts/groups":{"get":{"tags":["Contacts"],"operationId":"listContactGroups","summary":"List groups — المجموعات","responses":{"200":{"description":"Groups","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContactGroup"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Contacts"],"operationId":"createContactGroup","summary":"Create a group — إنشاء مجموعة","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Group name — اسم المجموعة"}}},"examples":{"default":{"value":{"name":"عملاء VIP"}}}}}},"responses":{"201":{"description":"Created group","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactGroup"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/contacts/import":{"post":{"tags":["Contacts"],"operationId":"importContacts","summary":"Bulk-import contacts — استيراد جهات اتصال","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contacts"],"properties":{"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactInput"}}}},"examples":{"default":{"value":{"contacts":[{"name":"سارة","phone":"0551112222"},{"name":"خالد","phone":"0553334444"}]}}}}}},"responses":{"201":{"description":"Import result"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/livechat/public/session":{"post":{"tags":["Live Chat"],"operationId":"createLivechatSession","summary":"Open/resume a widget session — فتح جلسة (عام)","description":"PUBLIC route used by the embeddable widget on behalf of an anonymous visitor. No API key. Tenant is verified against the body's `clientId`. Rate-limited.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"},"examples":{"default":{"value":{"clientId":"cl_tenant123","visitorName":"زائر","visitorEmail":"v@example.com"}}}}}},"responses":{"201":{"description":"Session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveChatSession"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/livechat/public/session/{id}/message":{"post":{"tags":["Live Chat"],"operationId":"postVisitorMessage","summary":"Visitor posts a message — رسالة زائر (عام)","description":"PUBLIC route. The visitor sends a message into the session (may trigger an FAQ-bot auto-reply).","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorMessageRequest"},"examples":{"default":{"value":{"clientId":"cl_tenant123","body":"كيف أستعيد كلمة المرور؟"}}}}}},"responses":{"201":{"description":"Message accepted"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/livechat/public/session/{id}/messages":{"get":{"tags":["Live Chat"],"operationId":"listVisitorMessages","summary":"Fetch transcript — نص الجلسة (عام)","description":"PUBLIC route. Returns the transcript for the widget. `clientId` verifies tenant ownership.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"clientId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Messages","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiveChatMessage"}}}}}}}},"/api/livechat/sessions":{"get":{"tags":["Live Chat"],"operationId":"listLivechatSessions","summary":"List sessions (agent) — جلسات الوكيل","parameters":[{"$ref":"#/components/parameters/StatusFilter"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Sessions","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiveChatSession"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/livechat/sessions/{id}/reply":{"post":{"tags":["Live Chat"],"operationId":"replyLivechatSession","summary":"Agent reply — ردّ الوكيل","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentReplyRequest"},"examples":{"default":{"value":{"body":"يسعدني مساعدتك! إليك الخطوات…","agentName":"منى"}}}}}},"responses":{"201":{"description":"Reply sent"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/livechat/sessions/{id}/close":{"post":{"tags":["Live Chat"],"operationId":"closeLivechatSession","summary":"Close session — إغلاق الجلسة","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"agentName":{"type":"string"}}}}}},"responses":{"201":{"description":"Session closed"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/livechat/sessions/{id}/escalate":{"post":{"tags":["Live Chat"],"operationId":"escalateLivechatSession","summary":"Escalate to a ticket — تصعيد لتذكرة","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EscalateSessionRequest"},"examples":{"default":{"value":{"title":"مشكلة في الدفع","priority":"high"}}}}}},"responses":{"201":{"description":"Ticket created from session"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/me/endpoints":{"get":{"tags":["Webhooks"],"operationId":"listMyWebhookEndpoints","summary":"List my webhook endpoints — نقاط النهاية","responses":{"200":{"description":"Endpoints (secret masked)","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Webhooks"],"operationId":"createMyWebhookEndpoint","summary":"Register a webhook endpoint — تسجيل نقطة نهاية","description":"Registers an HTTPS URL to receive signed events. The signing secret (`whsec_…`) is returned ONCE in this response.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"},"examples":{"allEvents":{"summary":"Subscribe to all","value":{"url":"https://example.com/hooks/nabaa"}},"filtered":{"summary":"Selected events","value":{"url":"https://example.com/hooks/nabaa","events":["message.delivered","inbound.received"]}}}}}},"responses":{"201":{"description":"Endpoint created — secret returned once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointWithSecret"},"examples":{"ok":{"value":{"id":"whk_4f9","clientId":"cl_tenant123","url":"https://example.com/hooks/nabaa","events":["message.delivered"],"active":true,"secret":"whsec_8f3a2b1c...redacted","createdAt":"2026-06-23T10:00:00.000Z","updatedAt":"2026-06-23T10:00:00.000Z"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/me/endpoints/{id}":{"patch":{"tags":["Webhooks"],"operationId":"updateMyWebhookEndpoint","summary":"Update an endpoint — تحديث نقطة نهاية","parameters":[{"$ref":"#/components/parameters/WebhookId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointRequest"},"examples":{"default":{"value":{"active":false}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"delete":{"tags":["Webhooks"],"operationId":"deleteMyWebhookEndpoint","summary":"Delete an endpoint — حذف نقطة نهاية","parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"Deleted"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/me/endpoints/{id}/rotate-secret":{"post":{"tags":["Webhooks"],"operationId":"rotateMyWebhookSecret","summary":"Rotate signing secret — تدوير المفتاح","description":"Generates a NEW signing secret and returns it once. Both old and new are accepted briefly to let you migrate without dropped events.","parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"New secret returned once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointWithSecret"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/me/endpoints/{id}/deliveries":{"get":{"tags":["Webhooks"],"operationId":"listMyWebhookDeliveries","summary":"Recent deliveries — سجلّ التسليم","parameters":[{"$ref":"#/components/parameters/WebhookId"},{"name":"take","in":"query","schema":{"type":"integer"},"description":"How many recent deliveries to return."}],"responses":{"200":{"description":"Delivery attempts","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/push/register":{"post":{"tags":["Push"],"operationId":"registerPushDevice","summary":"Register a push device — تسجيل جهاز إشعارات","description":"Registers/refreshes a Web Push subscription or an Expo (iOS/Android) device token.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceRequest"},"examples":{"expo":{"summary":"Expo (mobile)","value":{"platform":"ios","userId":"agent_12","token":"ExponentPushToken[xxxx]"}},"web":{"summary":"Web Push","value":{"platform":"web","endpoint":"https://fcm.googleapis.com/fcm/send/abc","keys":{"p256dh":"BPx...","auth":"k9..."}}}}}}},"responses":{"200":{"description":"Device registered"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/push/unregister":{"post":{"tags":["Push"],"operationId":"unregisterPushDevice","summary":"Unregister a device — إلغاء تسجيل جهاز","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"Device token or Web Push endpoint."}}}}}},"responses":{"200":{"description":"Device removed"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/push/vapid-public-key":{"get":{"tags":["Push"],"operationId":"getVapidPublicKey","summary":"Get VAPID public key — مفتاح VAPID العام","description":"Returns the public VAPID key the browser passes as `applicationServerKey` to `pushManager.subscribe()`.","responses":{"200":{"description":"VAPID public key","content":{"application/json":{"schema":{"type":"object","properties":{"publicKey":{"type":"string"}}},"examples":{"ok":{"value":{"publicKey":"BPx...redacted"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/organizations":{"get":{"tags":["Organizations"],"operationId":"listOrganizations","summary":"List organizations — قائمة المنظّمات","description":"Admin-only. Returns every organization with its owned-platform count.","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"responses":{"200":{"description":"Organizations","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Organization"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Organizations"],"operationId":"createOrganization","summary":"Create an organization — إنشاء منظّمة","description":"Admin-only. Creates a new SaaS account (organization).","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationRequest"},"examples":{"default":{"value":{"slug":"riyadah","name":"جمعية ريادة"}}}}}},"responses":{"201":{"description":"Created organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"An organization with that slug already exists — slug مكرّر","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/organizations/{id}":{"get":{"tags":["Organizations"],"operationId":"getOrganization","summary":"Get an organization — جلب منظّمة","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"responses":{"200":{"description":"Organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{id}/platforms":{"get":{"tags":["Organizations"],"operationId":"listOrganizationPlatforms","summary":"List owned platforms — منصّات المنظّمة","description":"Admin-only. Lists the platforms (ApiClients) owned by this organization.","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"responses":{"200":{"description":"Owned platforms","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationPlatform"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{id}/usage":{"get":{"tags":["Organizations"],"operationId":"getOrganizationUsage","summary":"Org usage roll-up — استهلاك المنظّمة","description":"Admin-only. Aggregated usage across every platform owned by the organization (platform count, SMS, contacts, tickets, per-platform breakdown).","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"responses":{"200":{"description":"Aggregated usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUsage"},"examples":{"ok":{"value":{"platforms":28,"sms":154203,"contacts":90211,"tickets":4120,"byPlatform":[{"id":"cl_cx360","name":"cx360","displayName":"CX360"}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{orgId}/billing/subscription":{"get":{"tags":["Organizations"],"operationId":"getOrganizationSubscription","summary":"Org subscription — اشتراك المنظّمة","description":"Admin-only. The organization-level subscription (account subscribes as a whole).","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Subscription (or null if never subscribed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgSubscription"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{orgId}/billing/subscribe":{"post":{"tags":["Organizations"],"operationId":"subscribeOrganization","summary":"Subscribe the org to a plan — اشتراك المنظّمة في خطة","description":"Admin-only. Subscribes the whole account to a plan by code.","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeOrgRequest"},"examples":{"default":{"value":{"planCode":"GROWTH","cycle":"MONTHLY"}}}}}},"responses":{"201":{"description":"Org subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgSubscription"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{orgId}/billing/wallet":{"get":{"tags":["Organizations"],"operationId":"getOrganizationWallet","summary":"Org wallet — محفظة المنظّمة","description":"Admin-only. The shared, account-level prepaid wallet.","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Wallet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgWallet"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/organizations/{orgId}/billing/entitlements":{"get":{"tags":["Organizations"],"operationId":"getOrganizationEntitlements","summary":"Org entitlements — استحقاقات المنظّمة","description":"Admin-only. The modules/features available under the account's current plan.","security":[{"AdminSecretAuth":[]},{"AdminBearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/OrgId"}],"responses":{"200":{"description":"Entitlements","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgEntitlement"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/health":{"get":{"tags":["System"],"operationId":"healthCheck","summary":"Health check — فحص الصحّة","security":[],"responses":{"200":{"description":"Service health","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"},"examples":{"ok":{"value":{"status":"ok","timestamp":"2026-06-23T10:00:00.000Z","service":"Nabaa Platform","version":"2.0.0","database":"ok","redis":"ok"}}}}}}}}},"/api/openapi.json":{"get":{"tags":["System"],"operationId":"getOpenApiSpec","summary":"This OpenAPI document — هذا المستند","security":[],"responses":{"200":{"description":"The OpenAPI 3.1 document","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"webhooks":{"message.lifecycle":{"post":{"summary":"Outbound webhook event — حدث صادر","description":"Nabaa POSTs signed events to every endpoint you registered for the matching event type.\n\nSignature headers (verify before trusting the body):\n- `webhook-id` — unique event id.\n- `webhook-timestamp` — unix epoch SECONDS.\n- `webhook-signature` — space-separated `v1,<base64-hmac-sha256>` values\n  over `${id}.${timestamp}.${rawBody}` using the part of your secret AFTER `whsec_`.\n\nReject timestamps outside your tolerance window (replay defense). See @riyadah/nabaa-client `verifyWebhook`.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"examples":{"delivered":{"value":{"id":"evt_8f3a2b","type":"message.delivered","createdAt":"2026-06-23T10:00:01.000Z","data":{"channel":"sms","logId":"cl9x0a1b2c","phone":"0501234567","status":"DELIVERED"}}}}}}},"responses":{"2XX":{"description":"Return any 2xx to acknowledge. Non-2xx / timeout triggers retry with backoff."}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your client API key. MUST be sent together with the `X-API-Secret` header (see ApiSecretAuth). مفتاح العميل — يُرسَل دائمًا مع X-API-Secret."},"ApiSecretAuth":{"type":"apiKey","in":"header","name":"X-API-Secret","description":"Your client secret, paired with X-API-Key. Supports zero-downtime rotation (old + new accepted during migration). السرّ المرافق لمفتاح العميل."},"AdminSecretAuth":{"type":"apiKey","in":"header","name":"X-Admin-Secret","description":"Platform admin secret (control-plane). Authorises the Organizations routes. سرّ مشرف المنصّة — للمسارات الإدارية فقط."},"AdminBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Admin JWT (from POST /api/auth/login). Alternative to X-Admin-Secret on the control-plane Organizations routes. رمز JWT لمشرف لوحة التحكّم."},"OAuth2":{"type":"oauth2","description":"OAuth2 authorization-code flow for portal-issued, scoped access tokens. تدفّق رمز التفويض لإصدار رموز وصول محدّدة النطاق.","flows":{"authorizationCode":{"authorizationUrl":"https://api.nabaa.riyadah.cloud/api/oauth/authorize","tokenUrl":"https://api.nabaa.riyadah.cloud/api/oauth/token","refreshUrl":"https://api.nabaa.riyadah.cloud/api/oauth/token","scopes":{"sms:send":"Send SMS messages — إرسال رسائل نصّية","whatsapp:send":"Send WhatsApp messages — إرسال رسائل واتساب","contacts:read":"Read contacts — قراءة جهات الاتصال","contacts:write":"Create/update contacts — تعديل جهات الاتصال","livechat:agent":"Operate live-chat as an agent — تشغيل الدردشة كوكيل","webhooks:manage":"Manage webhook endpoints — إدارة Webhooks"}}}}},"parameters":{"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1},"description":"Max items to return."},"Offset":{"name":"offset","in":"query","schema":{"type":"integer","minimum":0},"description":"Items to skip (pagination)."},"FromDate":{"name":"fromDate","in":"query","schema":{"type":"string","format":"date-time"}},"ToDate":{"name":"toDate","in":"query","schema":{"type":"string","format":"date-time"}},"StatusFilter":{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by message/session status."},"MessageTypeFilter":{"name":"messageType","in":"query","schema":{"type":"string"}},"ContactId":{"name":"id","in":"path","required":true,"schema":{"type":"string"}},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"string"}},"OrganizationId":{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Organization id — معرّف المنظّمة."},"OrgId":{"name":"orgId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization id — معرّف المنظّمة (مسارات الفوترة)."}},"responses":{"Unauthorized":{"description":"Missing/invalid API key or secret — مفتاح أو سرّ غير صالح","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found — غير موجود","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limit / quota exceeded — تجاوز الحدّ المسموح","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","description":"Standard error envelope (AllExceptionsFilter).","properties":{"success":{"type":"boolean","const":false},"statusCode":{"type":"integer","example":401},"message":{"type":"string","example":"API Key غير صالح"},"timestamp":{"type":"string","format":"date-time"},"path":{"type":"string","example":"/api/sms/send"}}},"SendResult":{"type":"object","description":"Result of a single send.","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"Arabic status message."},"logId":{"type":"string","description":"Local log row id (when sent)."},"messageId":{"type":"string","description":"Provider/Meta message id."}},"required":["success","message"]},"BulkQueuedResult":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"campaignId":{"type":"string"}},"required":["success"]},"SmsMessageType":{"type":"string","enum":["OTP","NOTIFICATION","MARKETING","ALERT","CAMPAIGN"]},"SendSmsRequest":{"type":"object","required":["phone","message"],"properties":{"phone":{"type":"string","description":"Recipient number (KSA local or E.164).","example":"0501234567"},"message":{"type":"string","description":"Message text."},"messageType":{"allOf":[{"$ref":"#/components/schemas/SmsMessageType"}],"default":"NOTIFICATION"},"metadata":{"type":"object","additionalProperties":true,"description":"Arbitrary metadata echoed into the log."}}},"SendOtpRequest":{"type":"object","required":["phone","code"],"properties":{"phone":{"type":"string","example":"0501234567"},"code":{"type":"string","description":"The OTP code to deliver.","example":"482913"},"template":{"type":"string","description":"Optional named OTP template."}}},"SendBulkSmsRequest":{"type":"object","required":["phones","message"],"properties":{"phones":{"type":"array","items":{"type":"string"},"description":"Recipient numbers."},"message":{"type":"string"},"messageType":{"allOf":[{"$ref":"#/components/schemas/SmsMessageType"}],"default":"NOTIFICATION"},"campaignName":{"type":"string"}}},"SmsLog":{"type":"object","properties":{"id":{"type":"string"},"phone":{"type":"string"},"message":{"type":"string"},"messageType":{"$ref":"#/components/schemas/SmsMessageType"},"status":{"type":"string","enum":["PENDING","QUEUED","SENT","DELIVERED","FAILED","REJECTED"]},"providerMsgId":{"type":"string"},"cost":{"type":"number"},"sentAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"WhatsappMessageType":{"type":"string","enum":["NOTIFICATION","INVOICE","REMINDER","ANNOUNCEMENT","OTP","CAMPAIGN"]},"WhatsappHeader":{"type":"object","description":"Optional template header (text or media).","required":["type"],"properties":{"type":{"type":"string","enum":["text","image","document","video"]},"text":{"type":"string"},"link":{"type":"string","format":"uri"},"filename":{"type":"string"}}},"WhatsappButton":{"type":"object","required":["subType","index","text"],"properties":{"subType":{"type":"string","enum":["url","quick_reply","copy_code"]},"index":{"type":"integer"},"text":{"type":"string"}}},"SendWhatsappRequest":{"type":"object","required":["phone","templateName"],"properties":{"phone":{"type":"string","example":"0501234567"},"templateName":{"type":"string","description":"Meta-approved template name."},"params":{"type":"array","items":{"type":"string"},"description":"Body placeholder values ({{1}},{{2}}…)."},"messageType":{"allOf":[{"$ref":"#/components/schemas/WhatsappMessageType"}],"default":"NOTIFICATION"},"language":{"type":"string","default":"ar"},"metadata":{"type":"object","additionalProperties":true},"header":{"$ref":"#/components/schemas/WhatsappHeader"},"buttons":{"type":"array","items":{"$ref":"#/components/schemas/WhatsappButton"}}}},"SendWhatsappTextRequest":{"type":"object","required":["phone"],"description":"Free-session message (24h window). Provide `message` and/or media.","properties":{"phone":{"type":"string","example":"0501234567"},"message":{"type":"string"},"mediaUrl":{"type":"string","format":"uri"},"mediaType":{"type":"string","description":"e.g. image, document, video, audio."},"messageType":{"allOf":[{"$ref":"#/components/schemas/WhatsappMessageType"}],"default":"NOTIFICATION"}}},"SendWhatsappInvoiceRequest":{"type":"object","required":["phone","customerName","invoiceNumber","amount"],"properties":{"phone":{"type":"string"},"customerName":{"type":"string"},"invoiceNumber":{"type":"string"},"amount":{"type":"string","description":"Amount as a string (currency-formatted upstream)."},"dueDate":{"type":"string"},"documentUrl":{"type":"string","format":"uri"}}},"SendWhatsappReminderRequest":{"type":"object","required":["phone","customerName","reminderText"],"properties":{"phone":{"type":"string"},"customerName":{"type":"string"},"reminderText":{"type":"string"},"actionUrl":{"type":"string","format":"uri"}}},"SendBulkWhatsappRequest":{"type":"object","required":["phones","templateName"],"properties":{"phones":{"type":"array","items":{"type":"string"}},"templateName":{"type":"string"},"params":{"type":"array","items":{"type":"string"}},"language":{"type":"string","default":"ar"},"campaignName":{"type":"string"}}},"WhatsappTemplate":{"type":"object","properties":{"name":{"type":"string"},"language":{"type":"string","example":"ar"},"category":{"type":"string","enum":["UTILITY","MARKETING","AUTHENTICATION"]},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED","DISABLED"]},"bodyText":{"type":"string"},"parameterCount":{"type":"integer"}}},"WhatsappLog":{"type":"object","properties":{"id":{"type":"string"},"phone":{"type":"string"},"messageType":{"$ref":"#/components/schemas/WhatsappMessageType"},"status":{"type":"string","enum":["PENDING","QUEUED","SENT","DELIVERED","READ","FAILED","REJECTED"]},"waMessageId":{"type":"string"},"readAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"V1SendSmsRequest":{"type":"object","required":["to","message"],"description":"Normalised single-SMS request for /api/v1/messaging/sms.","properties":{"to":{"type":"string","description":"Recipient number (KSA local or E.164).","example":"0501234567"},"message":{"type":"string","description":"Message text."},"type":{"allOf":[{"$ref":"#/components/schemas/SmsMessageType"}],"default":"NOTIFICATION"},"metadata":{"type":"object","additionalProperties":true,"description":"Arbitrary metadata echoed into the message log."}}},"V1SendBulkSmsRequest":{"type":"object","required":["to","message"],"description":"Normalised bulk-SMS request for /api/v1/messaging/sms/bulk.","properties":{"to":{"type":"array","items":{"type":"string"},"description":"Recipient numbers."},"message":{"type":"string"},"campaignName":{"type":"string"}}},"V1SendWhatsappRequest":{"type":"object","required":["to","templateName"],"description":"Normalised WhatsApp template request for /api/v1/messaging/whatsapp.","properties":{"to":{"type":"string","example":"0501234567"},"templateName":{"type":"string","description":"Meta-approved template name."},"params":{"type":"array","items":{"type":"string"},"description":"Body placeholder values ({{1}},{{2}}…)."},"language":{"type":"string","default":"ar"},"type":{"allOf":[{"$ref":"#/components/schemas/WhatsappMessageType"}],"default":"NOTIFICATION"},"metadata":{"type":"object","additionalProperties":true},"header":{"$ref":"#/components/schemas/WhatsappHeader"},"buttons":{"type":"array","items":{"$ref":"#/components/schemas/WhatsappButton"}}}},"V1Message":{"type":"object","description":"A unified message-log entry (either channel) from /api/v1/messaging/messages.","properties":{"id":{"type":"string"},"channel":{"type":"string","enum":["sms","whatsapp"]},"phone":{"type":"string"},"messageType":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"ContactInput":{"type":"object","description":"Create/update payload. All fields optional on update.","properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string","format":"email"},"company":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}},"Contact":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"}}},"ContactPage":{"type":"object","description":"Paginated contact list.","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"}}},"ContactGroup":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"memberCount":{"type":"integer"}}},"CreateSessionRequest":{"type":"object","required":["clientId"],"description":"Visitor opens/resumes a widget session. `clientId` identifies the tenant.","properties":{"clientId":{"type":"string"},"visitorName":{"type":"string"},"visitorEmail":{"type":"string","format":"email"},"sessionId":{"type":"string","description":"Provide to resume an existing session."}}},"VisitorMessageRequest":{"type":"object","required":["clientId","body"],"properties":{"clientId":{"type":"string"},"body":{"type":"string"}}},"AgentReplyRequest":{"type":"object","required":["body"],"properties":{"body":{"type":"string"},"agentName":{"type":"string"}}},"EscalateSessionRequest":{"type":"object","properties":{"title":{"type":"string"},"priority":{"type":"string"},"category":{"type":"string"}}},"LiveChatSession":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","example":"open"},"visitorName":{"type":"string","nullable":true},"assignedAgent":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"LiveChatMessage":{"type":"object","properties":{"id":{"type":"string"},"author":{"type":"string","enum":["visitor","agent","bot"]},"body":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"WebhookEventType":{"type":"string","enum":["message.sent","message.delivered","message.opened","message.clicked","message.bounced","message.complained","inbound.received"]},"CreateWebhookEndpointRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS endpoint (https required)."},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"description":"Subscribed event types. Empty/omitted = subscribe to ALL events.","uniqueItems":true}}},"UpdateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"uniqueItems":true},"active":{"type":"boolean"}}},"WebhookEndpoint":{"type":"object","description":"Endpoint view — the secret is always masked here.","properties":{"id":{"type":"string"},"clientId":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"active":{"type":"boolean"},"secretMasked":{"type":"string","example":"whsec_••••••••"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookEndpointWithSecret":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpoint"},{"type":"object","properties":{"secret":{"type":"string","description":"Signing secret (whsec_…). Shown ONCE — store it securely."}}}]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"eventType":{"type":"string"},"responseStatus":{"type":"integer","nullable":true},"success":{"type":"boolean"},"attempts":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}},"WebhookEvent":{"type":"object","description":"The JSON body Nabaa POSTs to your endpoint.","properties":{"id":{"type":"string"},"type":{"$ref":"#/components/schemas/WebhookEventType"},"createdAt":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":true}},"required":["id","type","data"]},"RegisterDeviceRequest":{"type":"object","required":["platform"],"description":"platform=web requires `endpoint` + `keys`; platform=ios/android requires `token` (ExpoPushToken).","properties":{"platform":{"type":"string","enum":["web","ios","android"]},"userId":{"type":"string","description":"Owning agent/user (optional for tenant-level devices)."},"token":{"type":"string","description":"ExpoPushToken (mobile)."},"endpoint":{"type":"string","format":"uri","description":"Web Push subscription endpoint (web only)."},"keys":{"type":"object","description":"Web Push encryption keys (web only).","properties":{"p256dh":{"type":"string"},"auth":{"type":"string"}},"required":["p256dh","auth"]}}},"CreateOrganizationRequest":{"type":"object","required":["slug","name"],"description":"Create-organization payload (admin).","properties":{"slug":{"type":"string","description":"URL-safe unique identifier — معرّف فريد.","example":"riyadah"},"name":{"type":"string","description":"Display name — اسم المنظّمة.","example":"جمعية ريادة"}}},"Organization":{"type":"object","description":"A SaaS account that owns one or more platforms (ApiClients).","properties":{"id":{"type":"string"},"slug":{"type":"string","example":"riyadah"},"name":{"type":"string","example":"جمعية ريادة"},"isActive":{"type":"boolean"},"_count":{"type":"object","description":"Aggregate counts (when included).","properties":{"apiClients":{"type":"integer"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"OrganizationPlatform":{"type":"object","description":"A platform (ApiClient) owned by an organization.","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string","nullable":true},"isActive":{"type":"boolean"},"whatsappEnabled":{"type":"boolean"},"tenantType":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"OrganizationUsage":{"type":"object","description":"Aggregated usage roll-up across every platform owned by the organization.","properties":{"platforms":{"type":"integer","description":"Number of owned platforms."},"sms":{"type":"integer","description":"Total SMS logged across owned platforms."},"contacts":{"type":"integer","description":"Total contacts across owned platforms."},"tickets":{"type":"integer","description":"Total tickets across owned platforms."},"byPlatform":{"type":"array","description":"Per-platform breakdown.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string","nullable":true}}}}}},"SubscribeOrgRequest":{"type":"object","required":["planCode"],"description":"Subscribe the whole organization to a plan by code (admin).","properties":{"planCode":{"type":"string","description":"Plan code (e.g. FREE/STARTER/GROWTH/SCALE).","example":"GROWTH"},"cycle":{"type":"string","enum":["MONTHLY","ANNUAL"],"description":"Billing cadence. Defaults to MONTHLY."}}},"OrgSubscription":{"type":"object","nullable":true,"description":"The organization-level subscription (carries `organizationId`), or null if the account never subscribed. Includes the plan + its entitlements.","properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"status":{"type":"string","enum":["TRIALING","ACTIVE","PAST_DUE","CANCELED","PAUSED"]},"billingCycle":{"type":"string","enum":["MONTHLY","ANNUAL"]},"seats":{"type":"integer"},"currency":{"type":"string","example":"SAR"},"currentPeriodStart":{"type":"string","format":"date-time"},"currentPeriodEnd":{"type":"string","format":"date-time"},"trialEndsAt":{"type":"string","format":"date-time","nullable":true},"cancelAtPeriodEnd":{"type":"boolean"},"plan":{"type":"object","additionalProperties":true,"description":"The subscribed plan (with entitlements)."},"createdAt":{"type":"string","format":"date-time"}}},"OrgWallet":{"type":"object","description":"The shared, account-level prepaid wallet.","properties":{"id":{"type":"string"},"organizationId":{"type":"string","nullable":true},"balance":{"type":"string","description":"Decimal money serialized as a string.","example":"1500.00"},"currency":{"type":"string","example":"SAR"},"updatedAt":{"type":"string","format":"date-time"}}},"OrgEntitlement":{"type":"object","description":"One module/feature available under the account's current plan.","properties":{"moduleKey":{"type":"string","example":"whatsapp"},"enabled":{"type":"boolean"},"limit":{"type":"integer","nullable":true}}},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"timestamp":{"type":"string","format":"date-time"},"service":{"type":"string"},"version":{"type":"string"},"database":{"type":"string"},"redis":{"type":"string"}}}}}}