6. API Reference
This is the complete HTTP API surface for WhatsApp Integration inside Shumoul.Saas.Api — 74 endpoints
across 9 controllers. Every endpoint below was verified directly against the current controller and
service source code; nothing here is inferred or invented.
Base URL: https://{tenant-subdomain}.{shumoul-domain}/api/v{version}/{route} — API version is
currently 1 for every controller documented here.
6.0 Conventions Used By Every Endpoint Below
Authentication & Authorization
Every endpoint requires a valid JWT bearer token (Authorization: Bearer {token}) except
WhatsAppWebhookController's two actions, which are [AllowAnonymous] because Meta calls them without any
Shumoul auth token — signature validation is the substitute security control there (see
§8 Webhooks). Every other action additionally requires a specific permission via
[MustHavePermission("Permissions.X.Y")].
Standard headers
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
Accept-Language: ar-SA (or en-US — drives bilingual field selection and template language)
Response envelope — Result<T>
Every endpoint except DataTable endpoints and WhatsAppController's manual test endpoints returns:
{ "succeeded": true, "message": null, "data": { "...": "the T payload documented per endpoint" } }
On failure:
{ "succeeded": false, "message": "Human-readable error", "data": null }
DataTable endpoints
POST GetConversations and POST GetMessages accept a DtParameters body and return the unwrapped
DtResult<T> directly:
{ "draw": 1, "start": 0, "length": 25, "search": {"value": "", "regex": false},
"order": [{"column": 0, "dir": "desc"}], "columns": [{"data": "lastMessageAt", "name": "", "searchable": true, "orderable": true}] }
{ "draw": 1, "recordsTotal": 240, "recordsFiltered": 12, "data": [ "...one row per T" ] }
Two permission families
PermissionConstants.WhatsApp.*— used only byWhatsAppController's manual test endpoints.PermissionConstants.WhatsAppInbox.*— used throughout Inbox, Note, SavedReply, Tag, and Timeline controllers.
Controller Index
| # | Controller | Route prefix | Endpoints |
|---|---|---|---|
| 1 | WhatsAppWebhookController | api/v1/notifications | 2 |
| 2 | WhatsAppController | api/v1/WhatsApp | 4 |
| 3 | WhatsAppInboxController | api/v1/whatsapp/inbox | 28 |
| 4 | WhatsAppNoteController | api/v1/whatsapp/notes | 4 |
| 5 | WhatsAppSavedReplyController | api/v1/whatsapp/saved-replies | 9 |
| 6 | WhatsAppTagController | api/v1/whatsapp/tags | 7 |
| 7 | WhatsAppTimelineController | api/v1/whatsapp/timeline | 1 |
| 8 | CommunicationController | api/v1/Communication | 12 |
| 9 | CommunicationDiagnosticsController | api/v1/Communication | 7 |
| Total | 74 |
Meta API call surface — only three code paths make outbound HTTP calls to Meta, referenced throughout this reference as "Calls Meta API":
WhatsAppCloudApiClientviaIWhatsAppService— the platform's own WhatsApp number.TenantWhatsAppSender.SendTemplateAsync— a tenant's own WhatsApp Business number.TenantWhatsAppSender.TestConnectionAsync— a direct business-account lookup, not exposed byIWhatsAppService.
6.1 Certification Addendum (Phase 2.2)
The fields below apply uniformly across all 74 endpoints unless an endpoint's own page states otherwise — stated once here rather than repeated 74 times, per endpoint pages already covering what's unique (business-specific error cases, side effects, and Angular/Flutter notes).
HTTP Status Codes
| Code | Meaning | Applies to |
|---|---|---|
200 | Success — Result<T>.SuccessAsync, a DtResult<T>, a raw test-endpoint DTO, or a binary/text file stream | Every successful call |
400 | Validation/business-rule failure (ValidationException), or a malformed request body | Any endpoint with server-side business rules (e.g. window-expiry checks, system-tag protection) |
401 | Missing or invalid JWT bearer token | Every endpoint except WhatsAppWebhookController's two actions |
403 | Authenticated but lacking the required [MustHavePermission] permission; or, for the webhook POST action only, an invalid X-Hub-Signature-256 | Every permissioned endpoint; webhook POST specifically |
404 | Entity not found (EntityNotFoundException) — e.g. an unknown conversationId/noteId/tagId route parameter | Any endpoint taking an entity ID route parameter |
500 | Unhandled exception — should be rare; every action follows the platform's standard Result<T>/exception-middleware pattern | Any endpoint, on an unexpected failure |
Validation Rules
No WhatsApp or Communication-module request DTO has a dedicated FluentValidation validator — confirmed
by inspecting Shumoul.Application/Validators/ (78 validator files exist platform-wide; none reference any
WhatsApp/Communication DTO). Validation is limited to:
- ASP.NET Core model binding (a malformed JSON body or an unparsable route
Guidreturns400automatically). - Inline service-layer checks, called out per endpoint where they exist (e.g. the 24-hour reply-window check
on
SendReply, theIsSystemtag-protection check onUpdateTag/DeleteTag,ValidateSettings's configuration checks).
Business Rules — Where to Find Them
Endpoint-specific business rules are documented as Error cases on each endpoint's own entry in §6.2–6.9. Cross-cutting business rules that apply platform-wide are documented in §11 Templates (template approval, 24-hour window) and §10 Inbox/Conversation (conversation lifecycle rules).
Runtime Flow
Every endpoint's underlying runtime flow is diagrammed in §23 Sequence Diagrams and §5 Runtime Flows — cross-referenced per endpoint where the flow isn't a single-step CRUD operation.
Related Background Jobs
None, for every one of the 74 endpoints. Every endpoint in this reference performs a synchronous,
immediate action (a direct Meta API call, or a direct database read/write) — none of them enqueue a
Hangfire job or any Background Jobs Framework pipeline. The only background process anywhere in the
WhatsApp/Communication surface is the Notification Framework's generic, channel-agnostic retry pipeline
(notification-retry-processor-pipeline, every 2 minutes) — and it is reached only via the separate,
not-in-this-reference generic Notification Framework dispatch API, never directly by any of these 74
endpoints. See §23.9 Background Retry.
Related SignalR Events
Only WhatsAppInboxController's conversation-lifecycle actions broadcast a SignalR event — see the "Side
effects" note on each such endpoint in §6.3, and the full event catalog in
§7 SignalR. No other controller in this reference touches
SignalR.
Related Meta Cloud API Endpoint
| This system's endpoint pattern | Meta Graph API endpoint called |
|---|---|
Any SendText*/SendReply action | POST /{version}/{phoneNumberId}/messages (text) |
Any SendTemplate*/Send/WhatsApp/Send/Document action | POST /{version}/{phoneNumberId}/messages (template) |
GetMediaInfo, Media (download) | GET /{version}/{mediaId} then GET {signed CDN url} |
Test/WhatsApp, TestConnectionAsync-based diagnostics | GET /{version}/{businessAccountId}?fields=id,name |
webhook (GET/POST), all Notes/Tags/SavedReplies/Timeline/Conversations-metadata endpoints | None — these are ERP-internal only and never call Meta |
