notifications

Notifications

Templates, preferences, send/retry, provider credentials, push device registration, and usage.

34 نقاط النهاية

GET /api/v1/me/notifications

The caller’s own in-app notification inbox, newest first (cursor-paginated).

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
cursor
querystring—
limit
queryinteger1–100 · default: 25
unreadOnly
queryenum: "true" | "false"default: "false"

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/notifications" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "templateKey": "string",
      "locale": "ar",
      "title": "Midterm Exam",
      "body": "string",
      "payload": {},
      "readAt": "2026-03-02T09:00:00.000Z",
      "createdAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/me/notifications/{id}/read

Mark one of the caller’s own inbox entries as read (idempotent).

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/me/notifications/37386ae0-3738-7738-8386-37386ae03738/read" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
okمطلوب
enum: true—
updatedمطلوب
integer0–9007199254740991
json
{
  "ok": true,
  "updated": 0
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/me/notifications/read-all

Mark every unread inbox entry of the caller’s own as read.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/me/notifications/read-all" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
okمطلوب
enum: true—
updatedمطلوب
integer0–9007199254740991
json
{
  "ok": true,
  "updated": 0
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/me/notifications/unread-count

How many of the caller’s own inbox entries are still unread.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/notifications/unread-count" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
unreadمطلوب
integer0–9007199254740991
json
{
  "unread": 0
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-preferences

The caller's own per-channel notification preferences.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-preferences" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
preferencesمطلوب
array<object>—
json
{
  "preferences": [
    {
      "channel": "push",
      "enabled": true,
      "digestMode": "immediate"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/notification-preferences

Sets one or more of the caller's own per-channel notification preferences.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
preferencesمطلوب
array<object>—

مثال

json
{
  "preferences": [
    {
      "channel": "push",
      "enabled": true,
      "digestMode": "immediate"
    }
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/notification-preferences" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "preferences": [
      {
        "channel": "push",
        "enabled": true,
        "digestMode": "immediate"
      }
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
preferencesمطلوب
array<object>—
json
{
  "preferences": [
    {
      "channel": "push",
      "enabled": true,
      "digestMode": "immediate"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-rules

The effective rule of every notification type, in the registry order, cursor-paginated (the whole catalogue fits one page). Each entry carries what the type allows, its locks, the Institflow default and the version to echo as `expectedVersion`.

يتطلّب المصادقةالصلاحيةnotifications.read

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
cursor
querystring—
limit
queryinteger1–100 · default: 25

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-rules" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "typeKey": "string",
      "category": "attendance",
      "trigger": {
        "kind": "event",
        "event": "string",
        "anchor": "string"
      },
      "subject": "string",
      "recipientKinds": [
        "students"
      ],
      "staffPermission": "string",
      "defaultStaffAudience": "none",
      "scopes": [
        "course"
      ],
      "guardianGrouping": "per_child",
      "urgencyChoice": true,
      "locks": {
        "enabled": true,
        "minimumStaff": true,
        "userCanMute": true,
        "emailOn": true
      },
      "reminder": {
        "maxLeads": -9007199254740991,
        "supportsItemMode": true,
        "supportsEnrolmentRelative": true
      },
      "legacySettingKey": "string",
      "rule": {
        "enabled": true,
        "students": true,
        "teachers": true,
        "guardians": "none",
        "staff": {
          "mode": "default",
          "roleIds": [
            "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
          ]
        },
        "memberIds": [
          "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
        ],
        "channels": {
          "push": true,
          "email": "ada.lovelace@example.com",
          "sms": true,
          "whatsapp": true
        },
        "urgency": "immediate",
        "reminder": {
          "leads": [
            "value"
          ],
          "respectQuietHours": true,
          "includeEnrolmentRelative": true
        },
        "scope": {
          "mode": "all",
          "courseIds": [
            "8e692f22-8e69-7e69-8692-8e692f228e69"
          ],
          "groupIds": [
            "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
          ]
        },
        "userCanMute": true
      },
      "defaults": {
        "enabled": true,
        "students": true,
        "teachers": true,
        "guardians": "none",
        "staff": {
          "mode": "default",
          "roleIds": [
            "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
          ]
        },
        "memberIds": [
          "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
        ],
        "channels": {
          "push": true,
          "email": "ada.lovelace@example.com",
          "sms": true,
          "whatsapp": true
        },
        "urgency": "immediate",
        "reminder": {
          "leads": [
            "value"
          ],
          "respectQuietHours": true,
          "includeEnrolmentRelative": true
        },
        "scope": {
          "mode": "all",
          "courseIds": [
            "8e692f22-8e69-7e69-8692-8e692f228e69"
          ],
          "groupIds": [
            "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
          ]
        },
        "userCanMute": true
      },
      "customisedFields": [
        "string"
      ],
      "version": -9007199254740991,
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-rules/{typeKey}

One type: the effective rule, the institute's own override, the locks and — per channel — whether it can deliver, who bills it and at what price.

يتطلّب المصادقةالصلاحيةnotifications.read

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
typeKeyمطلوب
pathstring—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-rules/string" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
typeKeyمطلوب
string—
categoryمطلوب
enum: "attendance" | "billing" | "learning" | "reminders" | "institute"—
triggerمطلوب
object—
subjectمطلوب
string—
recipientKindsمطلوب
array<enum: "students" | "guardians" | "teachers" | "staff" | "members">—
staffPermissionمطلوب
string | null—
defaultStaffAudienceمطلوب
enum: "none" | "permission_holders" | "owners_managers"—
scopesمطلوب
array<enum: "course" | "group">—
guardianGroupingمطلوب
enum: "per_child" | "per_subject"—
urgencyChoiceمطلوب
boolean—
locksمطلوب
object—
reminderمطلوب
object | null—
legacySettingKeyمطلوب
string | null—
ruleمطلوب
object—
defaultsمطلوب
object—
customisedFieldsمطلوب
array<string>—
versionمطلوب
integer-9007199254740991–9007199254740991
updatedAtمطلوب
string (date-time) | null—
overrideمطلوب
object | null—
channelStatesمطلوب
array<object>—
json
{
  "typeKey": "string",
  "category": "attendance",
  "trigger": {
    "kind": "event",
    "event": "string",
    "anchor": "string"
  },
  "subject": "string",
  "recipientKinds": [
    "students"
  ],
  "staffPermission": "string",
  "defaultStaffAudience": "none",
  "scopes": [
    "course"
  ],
  "guardianGrouping": "per_child",
  "urgencyChoice": true,
  "locks": {
    "enabled": true,
    "minimumStaff": true,
    "userCanMute": true,
    "emailOn": true
  },
  "reminder": {
    "maxLeads": -9007199254740991,
    "supportsItemMode": true,
    "supportsEnrolmentRelative": true
  },
  "legacySettingKey": "string",
  "rule": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "defaults": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "customisedFields": [
    "string"
  ],
  "version": -9007199254740991,
  "updatedAt": "2026-03-02T09:00:00.000Z",
  "override": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "channelStates": [
    {
      "channel": "push",
      "status": "own",
      "reason": "Requested by guardian.",
      "deliverable": true,
      "billing": "free",
      "unitPriceUnits": -9007199254740991
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/notification-rules/{typeKey}

Replaces the institute's override of one type (a field left out is the Institflow default again). `expectedVersion` guards against a concurrent edit (409 `VERSION_CONFLICT`). A change that raises what the institute pays for — a paid channel switched on, recipients, lead times or scope added to a type with a paid channel — is refused with 422 `VALIDATION_ERROR` and `details.reason = "cost_confirmation_required"` plus the estimate, unless `confirmCost` is `true`. A channel this install cannot deliver cannot be switched on (403 `FEATURE_DISABLED`).

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
typeKeyمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
ruleمطلوب
object—
expectedVersion
integer0–9007199254740991
confirmCost
boolean—

مثال

json
{
  "rule": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "expectedVersion": 0,
  "confirmCost": true
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/notification-rules/string" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "rule": {
      "enabled": true,
      "students": true,
      "teachers": true,
      "guardians": "none",
      "staff": {
        "mode": "default",
        "roleIds": [
          "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
        ]
      },
      "memberIds": [
        "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
      ],
      "channels": {
        "push": true,
        "email": "ada.lovelace@example.com",
        "sms": true,
        "whatsapp": true
      },
      "urgency": "immediate",
      "reminder": {
        "leads": [
          "value"
        ],
        "respectQuietHours": true,
        "includeEnrolmentRelative": true
      },
      "scope": {
        "mode": "all",
        "courseIds": [
          "8e692f22-8e69-7e69-8692-8e692f228e69"
        ],
        "groupIds": [
          "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
        ]
      },
      "userCanMute": true
    },
    "expectedVersion": 0,
    "confirmCost": true
  }'

الاستجابات

200
الاسمالنوعالقيود
typeKeyمطلوب
string—
categoryمطلوب
enum: "attendance" | "billing" | "learning" | "reminders" | "institute"—
triggerمطلوب
object—
subjectمطلوب
string—
recipientKindsمطلوب
array<enum: "students" | "guardians" | "teachers" | "staff" | "members">—
staffPermissionمطلوب
string | null—
defaultStaffAudienceمطلوب
enum: "none" | "permission_holders" | "owners_managers"—
scopesمطلوب
array<enum: "course" | "group">—
guardianGroupingمطلوب
enum: "per_child" | "per_subject"—
urgencyChoiceمطلوب
boolean—
locksمطلوب
object—
reminderمطلوب
object | null—
legacySettingKeyمطلوب
string | null—
ruleمطلوب
object—
defaultsمطلوب
object—
customisedFieldsمطلوب
array<string>—
versionمطلوب
integer-9007199254740991–9007199254740991
updatedAtمطلوب
string (date-time) | null—
overrideمطلوب
object | null—
channelStatesمطلوب
array<object>—
json
{
  "typeKey": "string",
  "category": "attendance",
  "trigger": {
    "kind": "event",
    "event": "string",
    "anchor": "string"
  },
  "subject": "string",
  "recipientKinds": [
    "students"
  ],
  "staffPermission": "string",
  "defaultStaffAudience": "none",
  "scopes": [
    "course"
  ],
  "guardianGrouping": "per_child",
  "urgencyChoice": true,
  "locks": {
    "enabled": true,
    "minimumStaff": true,
    "userCanMute": true,
    "emailOn": true
  },
  "reminder": {
    "maxLeads": -9007199254740991,
    "supportsItemMode": true,
    "supportsEnrolmentRelative": true
  },
  "legacySettingKey": "string",
  "rule": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "defaults": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "customisedFields": [
    "string"
  ],
  "version": -9007199254740991,
  "updatedAt": "2026-03-02T09:00:00.000Z",
  "override": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "channelStates": [
    {
      "channel": "push",
      "status": "own",
      "reason": "Requested by guardian.",
      "deliverable": true,
      "billing": "free",
      "unitPriceUnits": -9007199254740991
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notification-rules/{typeKey}/preview

Changes nothing: the monthly cost estimate (a range, in credit units), how many people the rule would reach by kind, whether saving it needs `confirmCost`, and warnings. Without a body it describes the current rule.

يتطلّب المصادقةالصلاحيةnotifications.read

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
typeKeyمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
rule
object—

مثال

json
{
  "rule": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  }
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notification-rules/string/preview" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "rule": {
      "enabled": true,
      "students": true,
      "teachers": true,
      "guardians": "none",
      "staff": {
        "mode": "default",
        "roleIds": [
          "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
        ]
      },
      "memberIds": [
        "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
      ],
      "channels": {
        "push": true,
        "email": "ada.lovelace@example.com",
        "sms": true,
        "whatsapp": true
      },
      "urgency": "immediate",
      "reminder": {
        "leads": [
          "value"
        ],
        "respectQuietHours": true,
        "includeEnrolmentRelative": true
      },
      "scope": {
        "mode": "all",
        "courseIds": [
          "8e692f22-8e69-7e69-8692-8e692f228e69"
        ],
        "groupIds": [
          "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
        ]
      },
      "userCanMute": true
    }
  }'

الاستجابات

200
الاسمالنوعالقيود
effectiveمطلوب
object—
requiresCostConfirmationمطلوب
boolean—
estimateمطلوب
object—
recipientsمطلوب
object—
warningsمطلوب
array<object>—
json
{
  "effective": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "requiresCostConfirmation": true,
  "estimate": {
    "basis": "history",
    "recipientsPerMonth": -9007199254740991,
    "channels": [
      {
        "channel": "push",
        "billing": "free",
        "messagesLow": -9007199254740991,
        "messagesHigh": -9007199254740991,
        "costLowUnits": -9007199254740991,
        "costHighUnits": -9007199254740991
      }
    ],
    "totalLowUnits": -9007199254740991,
    "totalHighUnits": -9007199254740991
  },
  "recipients": {
    "students": -9007199254740991,
    "guardians": -9007199254740991,
    "teachers": -9007199254740991,
    "staff": -9007199254740991,
    "members": -9007199254740991
  },
  "warnings": [
    {
      "code": "string",
      "detail": "string"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notification-rules/{typeKey}/reset

Deletes the override the institute made: the type goes back to the Institflow default. Going back can switch the type or a paid channel on again; that answers 422 with the estimate until the request carries `confirmCost: true`, exactly like a save.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
typeKeyمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
expectedVersion
integer0–9007199254740991
confirmCost
boolean—

مثال

json
{
  "expectedVersion": 0,
  "confirmCost": true
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notification-rules/string/reset" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "expectedVersion": 0,
    "confirmCost": true
  }'

الاستجابات

200
الاسمالنوعالقيود
typeKeyمطلوب
string—
categoryمطلوب
enum: "attendance" | "billing" | "learning" | "reminders" | "institute"—
triggerمطلوب
object—
subjectمطلوب
string—
recipientKindsمطلوب
array<enum: "students" | "guardians" | "teachers" | "staff" | "members">—
staffPermissionمطلوب
string | null—
defaultStaffAudienceمطلوب
enum: "none" | "permission_holders" | "owners_managers"—
scopesمطلوب
array<enum: "course" | "group">—
guardianGroupingمطلوب
enum: "per_child" | "per_subject"—
urgencyChoiceمطلوب
boolean—
locksمطلوب
object—
reminderمطلوب
object | null—
legacySettingKeyمطلوب
string | null—
ruleمطلوب
object—
defaultsمطلوب
object—
customisedFieldsمطلوب
array<string>—
versionمطلوب
integer-9007199254740991–9007199254740991
updatedAtمطلوب
string (date-time) | null—
overrideمطلوب
object | null—
channelStatesمطلوب
array<object>—
json
{
  "typeKey": "string",
  "category": "attendance",
  "trigger": {
    "kind": "event",
    "event": "string",
    "anchor": "string"
  },
  "subject": "string",
  "recipientKinds": [
    "students"
  ],
  "staffPermission": "string",
  "defaultStaffAudience": "none",
  "scopes": [
    "course"
  ],
  "guardianGrouping": "per_child",
  "urgencyChoice": true,
  "locks": {
    "enabled": true,
    "minimumStaff": true,
    "userCanMute": true,
    "emailOn": true
  },
  "reminder": {
    "maxLeads": -9007199254740991,
    "supportsItemMode": true,
    "supportsEnrolmentRelative": true
  },
  "legacySettingKey": "string",
  "rule": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "defaults": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "customisedFields": [
    "string"
  ],
  "version": -9007199254740991,
  "updatedAt": "2026-03-02T09:00:00.000Z",
  "override": {
    "enabled": true,
    "students": true,
    "teachers": true,
    "guardians": "none",
    "staff": {
      "mode": "default",
      "roleIds": [
        "9ded041d-9ded-7ded-8ed0-9ded041d9ded"
      ]
    },
    "memberIds": [
      "b34e3ee7-b34e-734e-84e3-b34e3ee7b34e"
    ],
    "channels": {
      "push": true,
      "email": "ada.lovelace@example.com",
      "sms": true,
      "whatsapp": true
    },
    "urgency": "immediate",
    "reminder": {
      "leads": [
        "value"
      ],
      "respectQuietHours": true,
      "includeEnrolmentRelative": true
    },
    "scope": {
      "mode": "all",
      "courseIds": [
        "8e692f22-8e69-7e69-8692-8e692f228e69"
      ],
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ]
    },
    "userCanMute": true
  },
  "channelStates": [
    {
      "channel": "push",
      "status": "own",
      "reason": "Requested by guardian.",
      "deliverable": true,
      "billing": "free",
      "unitPriceUnits": -9007199254740991
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-spend

This month's notification usage per channel and, when the install is on the Institflow messaging relay, the credit balance and overdraft limit as last synced.

يتطلّب المصادقةالصلاحيةnotifications.manage

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-spend" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
periodمطلوب
string—
relayمطلوب
object | null—
usageمطلوب
array<object>—
json
{
  "period": "string",
  "relay": {
    "balanceUnits": -9007199254740991,
    "overdraftUnits": -9007199254740991,
    "status": "active"
  },
  "usage": [
    {
      "channel": "string",
      "count": -9007199254740991,
      "costMinor": -9007199254740991
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-templates

Tenant overrides merged with platform defaults.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
cursor
querystring—
limit
queryinteger1–100 · default: 25

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-templates" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "key": "string",
      "channel": "push",
      "locale": "ar",
      "subject": "string",
      "body": "string",
      "providerTemplateName": "string",
      "isActive": true,
      "isPlatformDefault": true,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notification-templates

Creates a tenant override for a template key/channel/locale.

يتطلّب المصادقةالصلاحيةnotifications.manage

محتوى الطلب

الاسمالنوعالقيود
keyمطلوب
string1–150 chars
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
localeمطلوب
enum: "ar" | "en" | "he"—
subject
string1–300 chars
bodyمطلوب
string1–5000 chars
providerTemplateName
string1–150 chars
isActive
booleandefault: true

مثال

json
{
  "key": "string",
  "channel": "push",
  "locale": "ar",
  "subject": "string",
  "body": "string",
  "providerTemplateName": "string",
  "isActive": true
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notification-templates" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "key": "string",
    "channel": "push",
    "locale": "ar",
    "subject": "string",
    "body": "string",
    "providerTemplateName": "string",
    "isActive": true
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
keyمطلوب
string—
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
localeمطلوب
enum: "ar" | "en" | "he"—
subjectمطلوب
string | null≥1 chars
bodyمطلوب
string—
providerTemplateNameمطلوب
string | null≥1 chars
isActiveمطلوب
boolean—
isPlatformDefaultمطلوب
boolean—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "key": "string",
  "channel": "push",
  "locale": "ar",
  "subject": "string",
  "body": "string",
  "providerTemplateName": "string",
  "isActive": true,
  "isPlatformDefault": true,
  "createdAt": "2026-03-02T09:00:00.000Z",
  "updatedAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

DELETE /api/v1/notification-templates/{id}

Deletes a tenant override.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/notification-templates/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PATCH /api/v1/notification-templates/{id}

Updates a tenant override (never a platform default row).

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
subject
string1–300 chars
body
string1–5000 chars
providerTemplateName
string1–150 chars
isActive
booleandefault: true

مثال

json
{
  "subject": "string",
  "body": "string",
  "providerTemplateName": "string",
  "isActive": true
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/notification-templates/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "subject": "string",
    "body": "string",
    "providerTemplateName": "string",
    "isActive": true
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
keyمطلوب
string—
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
localeمطلوب
enum: "ar" | "en" | "he"—
subjectمطلوب
string | null≥1 chars
bodyمطلوب
string—
providerTemplateNameمطلوب
string | null≥1 chars
isActiveمطلوب
boolean—
isPlatformDefaultمطلوب
boolean—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "key": "string",
  "channel": "push",
  "locale": "ar",
  "subject": "string",
  "body": "string",
  "providerTemplateName": "string",
  "isActive": true,
  "isPlatformDefault": true,
  "createdAt": "2026-03-02T09:00:00.000Z",
  "updatedAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notification-templates/{id}/test

Renders this template against a fixed sample payload and sends it, through the tenant's real provider for its channel, to the calling user's own contact address. Never sends to anyone else.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notification-templates/37386ae0-3738-7738-8386-37386ae03738/test" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

201
الاسمالنوعالقيود
okمطلوب
enum: true—
sentToمطلوب
string—
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
json
{
  "ok": true,
  "sentTo": "string",
  "channel": "push"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-type-preferences

The caller's own per-type notification switches (class reminder, work-due reminder, new lesson). A type never switched off is on.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-type-preferences" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
preferencesمطلوب
array<object>—
json
{
  "preferences": [
    {
      "typeKey": "student.absent",
      "enabled": true,
      "canMute": true
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/notification-type-preferences

Switches one or more of the caller's own notification types on or off.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
preferencesمطلوب
array<object>—

مثال

json
{
  "preferences": [
    {
      "typeKey": "student.absent",
      "enabled": true
    }
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/notification-type-preferences" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "preferences": [
      {
        "typeKey": "student.absent",
        "enabled": true
      }
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
preferencesمطلوب
array<object>—
json
{
  "preferences": [
    {
      "typeKey": "student.absent",
      "enabled": true,
      "canMute": true
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notification-usage

Per-channel usage/cost counters for a billing period (default: the current month).

يتطلّب المصادقةالصلاحيةnotifications.read

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notification-usage" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
periodمطلوب
string—
usageمطلوب
array<object>—
json
{
  "period": "string",
  "usage": [
    {
      "channel": "push",
      "count": -9007199254740991,
      "costMinor": -9007199254740991
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/notifications

List the outbox log, cursor-paginated, filterable by status/channel/recipient.

يتطلّب المصادقةالصلاحيةnotifications.read

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
cursor
querystring—
limit
queryinteger1–100 · default: 25
status
queryenum: "queued" | "sending" | "sent" | "delivered" | "failed" | "skipped"—
channel
queryenum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
recipientUserId
querystring (uuid)—
recipientGuardianId
querystring (uuid)—
recipientStudentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/notifications" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "channel": "push",
      "status": "queued",
      "toAddress": "string",
      "templateKey": "string",
      "locale": "ar",
      "provider": "string",
      "providerMessageId": "wamid.HBgLMTU1NTU1MTIzNDU=",
      "error": "string",
      "costMinor": -9007199254740991,
      "recipientUserId": "86999436-8699-7699-8999-869994368699",
      "recipientGuardianId": "f98e9636-f98e-798e-88e9-f98e9636f98e",
      "recipientStudentId": "69fd1416-69fd-79fd-8fd1-69fd141669fd",
      "scheduledFor": "2026-03-02T09:00:00.000Z",
      "sentAt": "2026-03-02T09:00:00.000Z",
      "deliveredAt": "2026-03-02T09:00:00.000Z",
      "attempts": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "nextCursor": null
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notifications/{id}/retry

Re-queues a failed or skipped notification row.

يتطلّب المصادقةالصلاحيةnotifications.send

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notifications/37386ae0-3738-7738-8386-37386ae03738/retry" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
statusمطلوب
enum: "queued" | "sending" | "sent" | "delivered" | "failed" | "skipped"—
toAddressمطلوب
string—
templateKeyمطلوب
string—
localeمطلوب
enum: "ar" | "en" | "he"—
providerمطلوب
string—
providerMessageIdمطلوب
string | null≥1 chars
errorمطلوب
string | null≥1 chars
costMinorمطلوب
integer | null-9007199254740991–9007199254740991
recipientUserIdمطلوب
string (uuid) | null—
recipientGuardianIdمطلوب
string (uuid) | null—
recipientStudentIdمطلوب
string (uuid) | null—
scheduledForمطلوب
string (date-time) | null—
sentAtمطلوب
string (date-time) | null—
deliveredAtمطلوب
string (date-time) | null—
attemptsمطلوب
integer-9007199254740991–9007199254740991
createdAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "channel": "push",
  "status": "queued",
  "toAddress": "string",
  "templateKey": "string",
  "locale": "ar",
  "provider": "string",
  "providerMessageId": "wamid.HBgLMTU1NTU1MTIzNDU=",
  "error": "string",
  "costMinor": -9007199254740991,
  "recipientUserId": "86999436-8699-7699-8999-869994368699",
  "recipientGuardianId": "f98e9636-f98e-798e-88e9-f98e9636f98e",
  "recipientStudentId": "69fd1416-69fd-79fd-8fd1-69fd141669fd",
  "scheduledFor": "2026-03-02T09:00:00.000Z",
  "sentAt": "2026-03-02T09:00:00.000Z",
  "deliveredAt": "2026-03-02T09:00:00.000Z",
  "attempts": -9007199254740991,
  "createdAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/notifications/send

Manual broadcast to a group/branch/explicit student list. `dryRun` returns recipient count + quota impact without sending. Naming `channels` explicitly with `sms`/`whatsapp` this tenant is not approved for (`sms_notifications`/`whatsapp_notifications` not effective) is rejected with 422 `VALIDATION_ERROR` rather than silently sending a smaller broadcast; leaving `channels` unset falls through the tenant ladder instead, which skips an unapproved channel silently and still reaches the in-app inbox.

يتطلّب المصادقةالصلاحيةnotifications.send

محتوى الطلب

الاسمالنوعالقيود
templateKey
string1–150 chars
subject
string1–300 chars
body
string1–5000 chars
channels
array<enum: "push" | "whatsapp" | "email" | "sms" | "in_app">—
audienceمطلوب
object—
payload
objectdefault: {}
urgency
enum: "immediate" | "digest"default: "immediate"
dryRun
booleandefault: false

مثال

json
{
  "templateKey": "string",
  "subject": "string",
  "body": "string",
  "channels": [
    "push"
  ],
  "audience": {
    "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
    "branchId": "390b8975-390b-790b-80b8-390b8975390b",
    "studentIds": [
      "af05d28a-af05-7f05-805d-af05d28aaf05"
    ],
    "recipients": "both"
  },
  "payload": {},
  "urgency": "immediate",
  "dryRun": false
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/notifications/send" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "templateKey": "string",
    "subject": "string",
    "body": "string",
    "channels": [
      "push"
    ],
    "audience": {
      "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
      "branchId": "390b8975-390b-790b-80b8-390b8975390b",
      "studentIds": [
        "af05d28a-af05-7f05-805d-af05d28aaf05"
      ],
      "recipients": "both"
    },
    "payload": {},
    "urgency": "immediate",
    "dryRun": false
  }'

الاستجابات

201
الاسمالنوعالقيود
dryRunمطلوب
boolean—
recipientCountمطلوب
integer-9007199254740991–9007199254740991
queuedمطلوب
integer-9007199254740991–9007199254740991
skippedمطلوب
integer-9007199254740991–9007199254740991
notificationIdsمطلوب
array<string (uuid)>—
channelCountsمطلوب
object—
quotaImpactمطلوب
object—
json
{
  "dryRun": true,
  "recipientCount": -9007199254740991,
  "queued": -9007199254740991,
  "skipped": -9007199254740991,
  "notificationIds": [
    "6de4da18-6de4-7de4-8e4d-6de4da186de4"
  ],
  "channelCounts": {},
  "quotaImpact": {}
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/provider-credentials

Lists configured provider credentials — provider id + verified_at only, never secrets.

يتطلّب المصادقةالصلاحيةnotifications.manage

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/provider-credentials" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
json
{
  "data": [
    {
      "channel": "push",
      "provider": "string",
      "isActive": true,
      "verifiedAt": "2026-03-02T09:00:00.000Z"
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

DELETE /api/v1/provider-credentials/{channel}

Removes the stored provider credentials for a channel.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
channelمطلوب
pathstring—

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/provider-credentials/string" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/provider-credentials/{channel}

Sets (envelope-encrypted) provider credentials for a channel. Never echoes the secret back. 403 FEATURE_DISABLED for `sms`/`whatsapp` (platform/licence-approved per tenant, no platform sender exists for either in 1.0.0) or for `email`/`push` when the matching `byo_email_provider`/`byo_push_provider` flag is not granted — the platform SMTP/Expo sender keeps working either way.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
channelمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
providerمطلوب
string1–50 chars
configمطلوب
object—

مثال

json
{
  "provider": "string",
  "config": {}
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/provider-credentials/string" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "provider": "string",
    "config": {}
  }'

الاستجابات

200
الاسمالنوعالقيود
channelمطلوب
enum: "push" | "whatsapp" | "email" | "sms" | "in_app"—
providerمطلوب
string—
isActiveمطلوب
boolean—
verifiedAtمطلوب
string (date-time) | null—
json
{
  "channel": "push",
  "provider": "string",
  "isActive": true,
  "verifiedAt": "2026-03-02T09:00:00.000Z"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/provider-credentials/{channel}/test

Sends a real test message on this channel to the caller's own contact address. Same 403 FEATURE_DISABLED gating as PUT applies here — testing a channel this tenant has not been approved for (or, for email/push, a stored override without byo_email_provider/byo_push_provider) is rejected before anything is sent.

يتطلّب المصادقةالصلاحيةnotifications.manage

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
channelمطلوب
pathstring—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/provider-credentials/string/test" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

201
الاسمالنوعالقيود
okمطلوب
enum: true—
sentToمطلوب
string—
json
{
  "ok": true,
  "sentTo": "string"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/provider-credentials/status

Per-channel deliverability for this tenant right now — 'own' (approved tenant credentials active), 'platform' (no tenant override, but email/push/in_app always send through Institflow's own sender), or 'unavailable' (sms/whatsapp with no approved, configured tenant credential — the only case nothing sends). No permission required and carries no secret: every screen that plans a send (the broadcast wizard, the invoices reminder banner, the onboarding checklist) reads this instead of guessing from the credentials list.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/provider-credentials/status" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
json
{
  "data": [
    {
      "channel": "push",
      "status": "own",
      "reason": "Requested by guardian."
    }
  ]
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

DELETE /api/v1/push-devices

Unregisters the caller's own push device token.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
tokenمطلوب
string1–4096 chars

مثال

json
{
  "token": "string"
}

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/push-devices" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "token": "string"
  }'

الاستجابات

200
الاسمالنوعالقيود
okمطلوب
enum: true—
json
{
  "ok": true
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/push-devices

Registers (or refreshes) the caller's own push device token.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
platformمطلوب
enum: "ios" | "android" | "web"—
tokenمطلوب
string1–4096 chars

مثال

json
{
  "platform": "ios",
  "token": "string"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/push-devices" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "platform": "ios",
    "token": "string"
  }'

الاستجابات

201
الاسمالنوعالقيود
okمطلوب
enum: true—
json
{
  "ok": true
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/web-push/config

Whether this server can send browser push and, if so, the public key to subscribe with. `enabled: false` means the page should offer no browser-notification controls.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/web-push/config" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
enabledمطلوب
boolean—
publicKeyمطلوب
string | null—
json
{
  "enabled": true,
  "publicKey": "string"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

DELETE /api/v1/web-push/subscriptions

Removes the caller's own browser push subscription for an endpoint (idempotent).

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
endpointمطلوب
string0–2048 chars

مثال

json
{
  "endpoint": "string"
}

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/web-push/subscriptions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "endpoint": "string"
  }'

الاستجابات

200
الاسمالنوعالقيود
okمطلوب
enum: true—
json
{
  "ok": true
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/web-push/subscriptions

Registers (or refreshes) the caller's browser push subscription (`PushSubscription.toJSON()`). Refused with a feature-disabled error while the server has no push transport.

يتطلّب المصادقةالصلاحيةلا صلاحية إضافية

محتوى الطلب

الاسمالنوعالقيود
endpointمطلوب
string0–2048 chars
keysمطلوب
object—
userAgent
string0–200 chars

مثال

json
{
  "endpoint": "string",
  "keys": {
    "p256dh": "string",
    "auth": "string"
  },
  "userAgent": "string"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/web-push/subscriptions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "endpoint": "string",
    "keys": {
      "p256dh": "string",
      "auth": "string"
    },
    "userAgent": "string"
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738"
}
400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

402The tenant’s subscription or license is locked (`PAYMENT_REQUIRED`, `SUBSCRIPTION_SUSPENDED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

428An API-key caller must send an `Idempotency-Key` header (`IDEMPOTENCY_KEY_REQUIRED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

POST /api/v1/webhooks/providers/{provider}

Inbound delivery-status webhook from a notification provider (Meta/Twilio). Signature-verified.

بدون مصادقةالصلاحيةعامة

معطيات المسار والاستعلام

الاسمالموضعالنوعالقيود
providerمطلوب
pathstring—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/webhooks/providers/string" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

400The request could not be read at all — unparseable body, unusable content type, oversized payload (`MALFORMED_REQUEST`). Never a schema failure: those are 422.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

401Missing, expired or invalid credentials (`UNAUTHORIZED`, `TOKEN_INVALID`, `SESSION_REVOKED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

403Authenticated, but not allowed (`FORBIDDEN`, `FEATURE_DISABLED`, `QUOTA_EXCEEDED`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

404No such resource, or it is not visible to this tenant (`NOT_FOUND`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

409Conflicts with current state (`CONFLICT`, `VERSION_CONFLICT`, `IDEMPOTENCY_KEY_REUSED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

422The request was read but its content is not acceptable: body/query/path/header failed schema validation (`VALIDATION_ERROR`, with `details.issues`), or a domain rule rejected a well-formed value (`VIDEO_URL_INVALID`, …).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

429Rate limit exceeded — see the `RateLimit-*` and `Retry-After` headers (`RATE_LIMITED`).

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

500Unexpected server error (`INTERNAL_ERROR`). Never carries a stack trace or SQL.

تُعيد مغلّف الخطأ المشترك `ErrorEnvelope` — `{ error: { code, message, requestId, details? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.