9. API Documentation
This is the complete HTTP API reference for the Notification Framework's ERP-facing surface. Every
controller under Shumoul.Api\Controllers\v1\Notifications\ is documented, plus the legacy
MultiTenancyApi notification stack for completeness and migration awareness.
Base URL: https://{tenant-subdomain}.{shumoul-domain}/api/v{version}/{Controller} — API version is
currently 1 for every controller documented here.
9.0 Conventions used by every endpoint below
Authentication & Authorization
Every endpoint requires a valid JWT bearer token (Authorization: Bearer {token}), obtained from the
platform's auth endpoints (see docs/BACKEND_CRITICAL_MODULES.md). Beyond authentication, every action
additionally requires a specific permission via [MustHavePermission("Permissions.X.Y")] — see the
Permission column per endpoint below and Chapter 14 — Permissions for the full
catalog. Exception: NotificationHistoryController.SendTestEmailAsync has no [MustHavePermission]
attribute — any authenticated user can call it. This is flagged explicitly in
§9.12 as a known gap, not documented as intended behavior.
Standard headers
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
Accept-Language: ar-SA (or en-US — drives bilingual Name/FName field selection and template language)
Response envelope — Result<T>
Every endpoint except DataTable endpoints and the legacy NotificationHistoryController returns:
{
"succeeded": true,
"message": "Optional human-readable message",
"data": { "...": "the actual T payload documented per endpoint" }
}
On failure:
{
"succeeded": false,
"message": "Entity of type 'AppNotificationTemplate' with id '...' was not found.",
"data": null
}
DataTable endpoints — request/response shape
Every POST .../GetDataTable endpoint accepts a DtParameters body (server-side DataTables.net contract)
and returns the unwrapped DtResult<T> directly (not wrapped in Result<T> — this is a deliberate,
platform-wide convention, see docs/BACKEND_DEVELOPMENT_STANDARDS.md):
Request (DtParameters):
{
"draw": 1,
"start": 0,
"length": 25,
"search": { "value": "", "regex": false },
"order": [ { "column": 0, "dir": "desc" } ],
"columns": [ { "data": "createdOn", "name": "", "searchable": true, "orderable": true } ]
}
Response (DtResult<T>):
{
"draw": 1,
"recordsTotal": 240,
"recordsFiltered": 12,
"data": [ { "...": "one T row per array element" } ]
}
Bulk action endpoints — DeleteDto
Delete, Restore, Active, Deactive, Requeue, Cancel, RetryNow all accept a JSON array body of:
[ { "id": "5f1a3b2c-0000-0000-0000-000000000001" }, { "id": "5f1a3b2c-0000-0000-0000-000000000002" } ]
Delete additionally accepts ?restore=false (default) or ?restore=true as a query string flag on the
same route — restoring a soft-deleted record uses DELETE .../Delete?restore=true, not a separate verb,
except where a controller exposes a dedicated PUT .../Restore route (noted per-controller below).
Common error codes
| HTTP status | Meaning |
|---|---|
401 Unauthorized | Missing/expired/invalid JWT |
403 Forbidden | Valid JWT, but the caller's role lacks the required permission |
404 Not Found | Entity ID does not exist (surfaced as succeeded: false inside a 200 OK Result<T> body per platform convention — see docs/BACKEND_DEVELOPMENT_STANDARDS.md) |
400 Bad Request | FluentValidation failure on an Edit DTO — see §20.2 for which DTOs have validators today (most delivery-engine DTOs currently have no server-side validator — flagged per-controller) |
Angular / Flutter / Backend notes convention
Each endpoint below carries three short notes:
- Angular — when/how a typical Angular service should call it, caching/refresh expectations.
- Flutter — the mobile-client equivalent, with platform-specific notes (e.g. device token registration).
- Backend — what actually executes server-side, without exposing private implementation details.
9.1 Controller index
| # | Controller | Route | GroupName | File |
|---|---|---|---|---|
| 9.1 | AppNotificationController | AppNotification | notifications | app-notifications.md |
| 9.2 | AppNotificationTemplateController | AppNotificationTemplate | notifications | app-notification-templates.md |
| 9.3 | DeviceTokenController | DeviceToken | notifications | device-tokens.md |
| 9.4 | NotificationEventConfigurationsController | NotificationEventConfigurations | notifications | notification-event-configurations.md |
| 9.5 | NotificationDeliveryPoliciesController | NotificationDeliveryPolicies | notifications | notification-delivery-policies.md |
| 9.6 | NotificationRetryQueueController | NotificationRetryQueue | notifications | notification-retry-queue.md |
| 9.7 | NotificationDeadLettersController | NotificationDeadLetters | notifications | notification-dead-letters.md |
| 9.8 | NotificationAnalyticsController | NotificationAnalytics | notifications | notification-analytics.md |
| 9.9 | NotificationCampaignController | NotificationCampaign | notifications.campaigns | notification-campaigns.md |
| 9.10 | NotificationCampaignExecutionController | NotificationCampaignExecution | notifications.campaigns | notification-campaign-execution.md |
| 9.11 | NotificationDeliveryReceiptController | NotificationDeliveryReceipt | notifications.receipts | notification-delivery-receipts.md |
| 9.12 | NotificationHistoryController ⚠ legacy, blocked cleanup | NotificationHistory | identity | notification-history-legacy.md |
| 9.13 | Legacy MultiTenancyApi stack (5 controllers + hub) | api/notifications, api/Notifications/*, api/UserNotifications | MultiTenancy | legacy-multitenancy-stack.md |
12 active framework controllers (91 actions) + 5 legacy MultiTenancyApi controllers (29 actions) + 1 legacy SignalR hub — 120 individually documented HTTP actions in total. See each file's own endpoint count in its heading.