curriculum

Curriculum & Video

Course sections and lessons, lesson video links and their playback tokens, per-student course access grants, and progress tracking.

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

PATCH /api/v1/assignments/{lessonId}

Update an assignment’s own fields (instructions, due date, scoring, submission kinds). Lesson-shared fields (title, section, drip gate) go through `PATCH /lessons/:id`.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
instructionsMd
enum: "" | string | null—
dueAt
string (date-time) | null—
maxScore
number0–1000
allowLate
boolean—
submissionKinds
array<enum: "text" | "file" | "link">—

مثال

json
{
  "instructionsMd": "",
  "dueAt": "2026-03-02T09:00:00.000Z",
  "maxScore": 0,
  "allowLate": true,
  "submissionKinds": [
    "text"
  ]
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/assignments/3d477cf4-3d47-7d47-8477-3d477cf43d47" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "instructionsMd": "",
    "dueAt": "2026-03-02T09:00:00.000Z",
    "maxScore": 0,
    "allowLate": true,
    "submissionKinds": [
      "text"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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/assignments/{lessonId}/publish-to-gradebook

Publish every currently-graded submission into the gradebook as a `homework` exam per group (ق-33) — one click, upserts on repeat.

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

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

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/assignments/3d477cf4-3d47-7d47-8477-3d477cf43d47/publish-to-gradebook" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
publishedمطلوب
array<object>—
skippedمطلوب
array<object>—
json
{
  "published": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
      "examId": "6c140414-6c14-7c14-8140-6c1404146c14",
      "score": 1
    }
  ],
  "skipped": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "reason": "no_group"
    }
  ]
}
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/assignments/{lessonId}/submissions

List an assignment’s submissions (cursor-paginated, optional status filter).

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
status
queryenum: "submitted" | "late" | "returned" | "graded"—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/assignments/3d477cf4-3d47-7d47-8477-3d477cf43d47/submissions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "assignmentId": "c41b0f8d-c41b-741b-81b0-c41b0f8dc41b",
      "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "submittedAt": "2026-03-02T09:00:00.000Z",
      "textMd": "string",
      "link": "string",
      "files": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "originalName": "string",
          "mimeType": "string",
          "sizeBytes": 0,
          "downloadUrl": "string",
          "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
        }
      ],
      "status": "submitted",
      "score": 1,
      "maxScore": 1,
      "feedbackMd": "string",
      "gradedByUserId": "71e16c27-71e1-71e1-8e16-71e16c2771e1",
      "gradedByName": "string",
      "gradedAt": "2026-03-02T09:00:00.000Z",
      "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/assignments/{lessonId}/submissions/{submissionId}/grade

Grade a submission (score ≤ the assignment’s max score, optional feedback). Emits `assignment.graded`.

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

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

محتوى الطلب

الاسمالنوعالقيود
scoreمطلوب
number≥0
feedbackMd
enum: "" | string | null—

مثال

json
{
  "score": 0,
  "feedbackMd": ""
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/assignments/3d477cf4-3d47-7d47-8477-3d477cf43d47/submissions/a396314c-a396-7396-8963-a396314ca396/grade" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "score": 0,
    "feedbackMd": ""
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
assignmentIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
submittedAtمطلوب
string (date-time)—
textMdمطلوب
string | null≥1 chars
linkمطلوب
string | null—
filesمطلوب
array<SubmissionFile>—
statusمطلوب
enum: "submitted" | "late" | "returned" | "graded"—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
feedbackMdمطلوب
string | null≥1 chars
gradedByUserIdمطلوب
string (uuid) | null—
gradedByNameمطلوب
string | null≥1 chars
gradedAtمطلوب
string (date-time) | null—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "assignmentId": "c41b0f8d-c41b-741b-81b0-c41b0f8dc41b",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "textMd": "string",
  "link": "string",
  "files": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "status": "submitted",
  "score": 1,
  "maxScore": 1,
  "feedbackMd": "string",
  "gradedByUserId": "71e16c27-71e1-71e1-8e16-71e16c2771e1",
  "gradedByName": "string",
  "gradedAt": "2026-03-02T09:00:00.000Z",
  "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/assignments/{lessonId}/submissions/{submissionId}/return

Send a submission back for revision (clears any earlier grade).

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

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

محتوى الطلب

الاسمالنوعالقيود
feedbackMd
enum: "" | string | null—

مثال

json
{
  "feedbackMd": ""
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/assignments/3d477cf4-3d47-7d47-8477-3d477cf43d47/submissions/a396314c-a396-7396-8963-a396314ca396/return" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "feedbackMd": ""
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
assignmentIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
submittedAtمطلوب
string (date-time)—
textMdمطلوب
string | null≥1 chars
linkمطلوب
string | null—
filesمطلوب
array<SubmissionFile>—
statusمطلوب
enum: "submitted" | "late" | "returned" | "graded"—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
feedbackMdمطلوب
string | null≥1 chars
gradedByUserIdمطلوب
string (uuid) | null—
gradedByNameمطلوب
string | null≥1 chars
gradedAtمطلوب
string (date-time) | null—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "assignmentId": "c41b0f8d-c41b-741b-81b0-c41b0f8dc41b",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "textMd": "string",
  "link": "string",
  "files": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "status": "submitted",
  "score": 1,
  "maxScore": 1,
  "feedbackMd": "string",
  "gradedByUserId": "71e16c27-71e1-71e1-8e16-71e16c2771e1",
  "gradedByName": "string",
  "gradedAt": "2026-03-02T09:00:00.000Z",
  "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/course-enrollments/{id}

Revoke a self-paced course grant. Emits `course_enrollment.dropped`.

يتطلّب المصادقةالصلاحيةenrollments.write

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

الاسمالموضعالنوعالقيود
idمطلوب
pathstring—
reason
querystring1–500 chars

مثال بأمر curl

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

الاستجابات

204The course enrollment was dropped.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/courses/{courseId}/assignments

Create an assignment unit: a lesson of kind "assignment" plus its instructions/due-date/scoring, in one transaction.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
sectionId
string (uuid)—
titleمطلوب
string1–200 chars
summary
enum: "" | string | null—
availableFrom
string (date-time) | null—
availableAfterDays
integer | null0–365
estimatedMinutes
integer | null1–600
instructionsMd
enum: "" | string | null—
dueAt
string (date-time) | null—
maxScoreمطلوب
number0–1000
allowLate
booleandefault: false
submissionKindsمطلوب
array<enum: "text" | "file" | "link">—
audienceGroupIds
array<string (uuid)> | null—

مثال

json
{
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": 0,
  "estimatedMinutes": 1,
  "instructionsMd": "",
  "dueAt": "2026-03-02T09:00:00.000Z",
  "maxScore": 0,
  "allowLate": false,
  "submissionKinds": [
    "text"
  ],
  "audienceGroupIds": [
    "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
  ]
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/assignments" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
    "title": "Midterm Exam",
    "summary": "",
    "availableFrom": "2026-03-02T09:00:00.000Z",
    "availableAfterDays": 0,
    "estimatedMinutes": 1,
    "instructionsMd": "",
    "dueAt": "2026-03-02T09:00:00.000Z",
    "maxScore": 0,
    "allowLate": false,
    "submissionKinds": [
      "text"
    ],
    "audienceGroupIds": [
      "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
    ]
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/courses/{courseId}/audience-groups

List the groups a unit of this course may be restricted to (id and name only, cursor-paginated) — for the «لمن هذا الدرس؟» selector; needs `curriculum.write` or `curriculum.quizzes.manage` (whoever may set an audience), not the groups permission.

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

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

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

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/audience-groups" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "name": "Algebra I"
    }
  ],
  "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/courses/{courseId}/curriculum/summary

Authoring dashboard tile: section/lesson/published/video counts for one course.

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

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

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

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/curriculum/summary" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
courseIdمطلوب
string (uuid)—
sectionCountمطلوب
integer0–9007199254740991
lessonCountمطلوب
integer0–9007199254740991
publishedLessonCountمطلوب
integer0–9007199254740991
videoLessonCountمطلوب
integer0–9007199254740991
json
{
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionCount": 0,
  "lessonCount": 0,
  "publishedLessonCount": 0,
  "videoLessonCount": 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/courses/{courseId}/enrollments

List a course’s self-paced enrollments (cursor-paginated, optional status filter).

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

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

الاسمالموضعالنوعالقيود
courseIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
status
queryenum: "pending" | "active" | "completed" | "dropped"—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/enrollments" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "status": "pending",
      "grantedAt": "2026-03-02T09:00:00.000Z",
      "endedAt": "2026-03-02T09:00:00.000Z",
      "priceMinor": 12000,
      "currency": "ILS",
      "grantedByUserId": "fc4e27b3-fc4e-7c4e-84e2-fc4e27b3fc4e",
      "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/courses/{courseId}/enrollments

Grant a student access to a self-paced course. Idempotent, price snapshotted from the course fee, emits `course_enrollment.created`.

يتطلّب المصادقةالصلاحيةenrollments.write

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

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

محتوى الطلب

الاسمالنوعالقيود
studentIdمطلوب
string (uuid)—
priceMinor
integer0–9007199254740991
currency
enum: "ILS" | "USD" | "EUR"—

مثال

json
{
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "priceMinor": 12000,
  "currency": "ILS"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/enrollments" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
    "priceMinor": 12000,
    "currency": "ILS"
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
statusمطلوب
enum: "pending" | "active" | "completed" | "dropped"—
grantedAtمطلوب
string (date-time)—
endedAtمطلوب
string (date-time) | null—
priceMinorمطلوب
integer | null-9007199254740991–9007199254740991
currencyمطلوب
enum: "ILS" | "USD" | "EUR" | null | null—
grantedByUserIdمطلوب
string (uuid) | null—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "status": "pending",
  "grantedAt": "2026-03-02T09:00:00.000Z",
  "endedAt": "2026-03-02T09:00:00.000Z",
  "priceMinor": 12000,
  "currency": "ILS",
  "grantedByUserId": "fc4e27b3-fc4e-7c4e-84e2-fc4e27b3fc4e",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/courses/{courseId}/lessons

List a course’s lessons (cursor-paginated, optional section/status filter).

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

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

الاسمالموضعالنوعالقيود
courseIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
sectionId
querystring (uuid)—
status
queryenum: "draft" | "published"—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/lessons" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "title": "Midterm Exam",
      "summary": "string",
      "contentMd": "string",
      "kind": "lesson",
      "status": "draft",
      "publishedAt": "2026-03-02T09:00:00.000Z",
      "availableFrom": "2026-03-02T09:00:00.000Z",
      "availableAfterDays": -9007199254740991,
      "estimatedMinutes": -9007199254740991,
      "sortOrder": -9007199254740991,
      "video": "value",
      "assignment": "value",
      "quiz": "value",
      "audience": {
        "restricted": true,
        "groups": [
          {
            "id": "37386ae0-3738-7738-8386-37386ae03738",
            "name": "Algebra I"
          }
        ],
        "hidden": true
      },
      "reminderMode": "inherit",
      "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/courses/{courseId}/lessons

Create a lesson. Omit `sectionId` to use/auto-create the course’s default section.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
sectionId
string (uuid)—
titleمطلوب
string1–200 chars
summary
enum: "" | string | null—
contentMd
enum: "" | string | null—
availableFrom
string (date-time) | null—
availableAfterDays
integer | null0–365
estimatedMinutes
integer | null1–600
audienceGroupIds
array<string (uuid)> | null—

مثال

json
{
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "",
  "contentMd": "",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": 0,
  "estimatedMinutes": 1,
  "audienceGroupIds": [
    "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
  ]
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/lessons" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
    "title": "Midterm Exam",
    "summary": "",
    "contentMd": "",
    "availableFrom": "2026-03-02T09:00:00.000Z",
    "availableAfterDays": 0,
    "estimatedMinutes": 1,
    "audienceGroupIds": [
      "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
    ]
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/courses/{courseId}/progress

Teacher progress matrix: published units × students who may reach the course, cursor-paginated on students (max 100).

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

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

الاسمالموضعالنوعالقيود
courseIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
search
querystring1–200 chars

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/progress" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
courseIdمطلوب
string (uuid)—
unitsمطلوب
array<ProgressMatrixUnit>—
studentsمطلوب
array<ProgressMatrixStudent>—
cellsمطلوب
object—
nextCursorمطلوب
string | null—
json
{
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "units": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "title": "Midterm Exam",
      "kind": "lesson",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "sectionTitle": "string",
      "sortOrder": -9007199254740991,
      "completedCount": 0
    }
  ],
  "students": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "fullName": "Ada Lovelace",
      "groupIds": [
        "b0a20d96-b0a2-70a2-8a20-b0a20d96b0a2"
      ],
      "source": "course_enrollment",
      "completedCount": 0,
      "percent": 0
    }
  ],
  "cells": {},
  "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/courses/{courseId}/progress/students/{studentId}

One student's unit-by-unit progress for a course, row-scoped like the matrix.

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

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

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

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/progress/students/a4a70332-a4a7-74a7-8a70-a4a70332a4a7" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
courseIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
fullNameمطلوب
string≥1 chars
completedCountمطلوب
integer0–9007199254740991
percentمطلوب
integer0–100
unitsمطلوب
array<StudentProgressUnit>—
json
{
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "fullName": "Ada Lovelace",
  "completedCount": 0,
  "percent": 0,
  "units": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "title": "Midterm Exam",
      "kind": "lesson",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "sectionTitle": "string",
      "sortOrder": -9007199254740991,
      "status": "not_started",
      "completedAt": "2026-03-02T09:00:00.000Z",
      "lastSeenAt": "2026-03-02T09:00:00.000Z",
      "assignment": "value",
      "quiz": "value"
    }
  ]
}
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/courses/{courseId}/quizzes

Create a quiz unit: a lesson of kind "quiz" plus its settings, in one transaction. No questions yet.

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

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

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

محتوى الطلب

الاسمالنوعالقيود
sectionId
string (uuid)—
titleمطلوب
string1–200 chars
summary
enum: "" | string | null—
availableFrom
string (date-time) | null—
availableAfterDays
integer | null0–365
estimatedMinutes
integer | null1–600
timeLimitMinutes
integer | null1–600
attemptsAllowed
integer1–20 · default: 1
shuffle
booleandefault: false
showAnswersAfter
enum: "never" | "after_submit" | "after_due"default: "after_submit"
passScore
number | null≤100000
dueAt
string (date-time) | null—
audienceGroupIds
array<string (uuid)> | null—

مثال

json
{
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": 0,
  "estimatedMinutes": 1,
  "timeLimitMinutes": 1,
  "attemptsAllowed": 1,
  "shuffle": false,
  "showAnswersAfter": "after_submit",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z",
  "audienceGroupIds": [
    "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
  ]
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/quizzes" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
    "title": "Midterm Exam",
    "summary": "",
    "availableFrom": "2026-03-02T09:00:00.000Z",
    "availableAfterDays": 0,
    "estimatedMinutes": 1,
    "timeLimitMinutes": 1,
    "attemptsAllowed": 1,
    "shuffle": false,
    "showAnswersAfter": "after_submit",
    "passScore": 1,
    "dueAt": "2026-03-02T09:00:00.000Z",
    "audienceGroupIds": [
      "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
    ]
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/courses/{courseId}/sections

List a course’s sections (cursor-paginated, authoring order).

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

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

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

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/sections" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "title": "Midterm Exam",
      "description": "A short, human-readable description.",
      "sortOrder": -9007199254740991,
      "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/courses/{courseId}/sections

Create a section.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
titleمطلوب
string1–200 chars
description
string | string—

مثال

json
{
  "title": "Midterm Exam",
  "description": "A short, human-readable description."
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/sections" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "title": "Midterm Exam",
    "description": "A short, human-readable description."
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
descriptionمطلوب
string | null≥1 chars
sortOrderمطلوب
integer-9007199254740991–9007199254740991
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "title": "Midterm Exam",
  "description": "A short, human-readable description.",
  "sortOrder": -9007199254740991,
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/courses/{courseId}/sections/order

Reorder every section of a course in one call (whole-list, unpaginated response envelope).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
sectionIdsمطلوب
array<string (uuid)>—

مثال

json
{
  "sectionIds": [
    "72a7f6d6-72a7-72a7-8a7f-72a7f6d672a7"
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/sections/order" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "sectionIds": [
      "72a7f6d6-72a7-72a7-8a7f-72a7f6d672a7"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "title": "Midterm Exam",
      "description": "A short, human-readable description.",
      "sortOrder": -9007199254740991,
      "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

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/curriculum/usage

This tenant’s plan usage for the curriculum feature (quota meter).

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
videoCoursesمطلوب
object—
lessonsPerCourseمطلوب
object—
json
{
  "videoCourses": {
    "used": 0,
    "limit": -1
  },
  "lessonsPerCourse": {
    "limit": -1
  }
}
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/lesson-files/{id}

Delete a lesson file: removes the row, then the stored object. Audited.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

مثال بأمر curl

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

الاستجابات

204The file was deleted.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/lesson-files/{id}

Rename a lesson file (it keeps its extension), change its description or who may see it.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
originalName
string1–255 chars
description
enum: "" | string | null—
visibility
enum: "learners" | "staff"—

مثال

json
{
  "originalName": "string",
  "description": "",
  "visibility": "learners"
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/lesson-files/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "originalName": "string",
    "description": "",
    "visibility": "learners"
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
originalNameمطلوب
string≥1 chars
mimeTypeمطلوب
string≥1 chars
sizeBytesمطلوب
integer0–9007199254740991
descriptionمطلوب
string | null≥1 chars
visibilityمطلوب
enum: "learners" | "staff"—
sortOrderمطلوب
integer-9007199254740991–9007199254740991
createdAtمطلوب
string (date-time)—
downloadUrlمطلوب
string—
downloadUrlExpiresAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": 0,
  "description": "A short, human-readable description.",
  "visibility": "learners",
  "sortOrder": -9007199254740991,
  "createdAt": "2026-03-02T09:00:00.000Z",
  "downloadUrl": "string",
  "downloadUrlExpiresAt": "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/lessons/{id}

Delete a lesson (cascades its video and progress rows).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

مثال بأمر curl

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

الاستجابات

204The lesson was deleted.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/lessons/{id}

Get one lesson (author view — draft content and video included).

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

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

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

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/lessons/{id}

Update a lesson.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
sectionId
string (uuid)—
title
string1–200 chars
summary
enum: "" | string | null—
contentMd
enum: "" | string | null—
availableFrom
string (date-time) | null—
availableAfterDays
integer | null0–365
estimatedMinutes
integer | null1–600
audienceGroupIds
array<string (uuid)> | null—
reminderMode
enum: "inherit" | "on" | "off"—

مثال

json
{
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "",
  "contentMd": "",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": 0,
  "estimatedMinutes": 1,
  "audienceGroupIds": [
    "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
  ],
  "reminderMode": "inherit"
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/lessons/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
    "title": "Midterm Exam",
    "summary": "",
    "contentMd": "",
    "availableFrom": "2026-03-02T09:00:00.000Z",
    "availableAfterDays": 0,
    "estimatedMinutes": 1,
    "audienceGroupIds": [
      "1efa96cc-1efa-7efa-8fa9-1efa96cc1efa"
    ],
    "reminderMode": "inherit"
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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/lessons/{id}/publish

Publish a lesson (emits `lesson.published`). Refused if it has neither content nor a video.

يتطلّب المصادقةالصلاحيةcurriculum.publish

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

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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/lessons/{id}/unpublish

Unpublish a lesson back to draft.

يتطلّب المصادقةالصلاحيةcurriculum.publish

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

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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/lessons/{id}/video

Remove a lesson’s video (idempotent).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

مثال بأمر curl

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

الاستجابات

204The video was removed (or was already absent).

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/lessons/{id}/video

Set (or replace) a lesson’s video source. Only the parsed (provider, externalRef) is ever stored — never the raw URL.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
urlمطلوب
string1–2048 chars
title
string1–200 chars
durationSeconds
integer1–86400

مثال

json
{
  "url": "https://example.com/webhooks/institflow",
  "title": "Midterm Exam",
  "durationSeconds": 1
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/lessons/37386ae0-3738-7738-8386-37386ae03738/video" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "url": "https://example.com/webhooks/institflow",
    "title": "Midterm Exam",
    "durationSeconds": 1
  }'

الاستجابات

200
الاسمالنوعالقيود
providerمطلوب
enum: "youtube"—
externalRefمطلوب
string≥1 chars
canonicalUrlمطلوب
string—
embedUrlمطلوب
string—
titleمطلوب
string | null≥1 chars
thumbnailUrlمطلوب
string | null—
durationSecondsمطلوب
integer | null1–9007199254740991
verifiedAtمطلوب
string (date-time) | null—
capabilitiesمطلوب
object—
json
{
  "provider": "youtube",
  "externalRef": "string",
  "canonicalUrl": "string",
  "embedUrl": "string",
  "title": "Midterm Exam",
  "thumbnailUrl": "string",
  "durationSeconds": 1,
  "verifiedAt": "2026-03-02T09:00:00.000Z",
  "capabilities": {
    "progressTracking": true,
    "derivedThumbnail": true,
    "serverMetadata": true,
    "thirdPartyAds": 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/lessons/{id}/video/verify

Stamp `verifiedAt` — the author confirms the video actually plays.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
providerمطلوب
enum: "youtube"—
externalRefمطلوب
string≥1 chars
canonicalUrlمطلوب
string—
embedUrlمطلوب
string—
titleمطلوب
string | null≥1 chars
thumbnailUrlمطلوب
string | null—
durationSecondsمطلوب
integer | null1–9007199254740991
verifiedAtمطلوب
string (date-time) | null—
capabilitiesمطلوب
object—
json
{
  "provider": "youtube",
  "externalRef": "string",
  "canonicalUrl": "string",
  "embedUrl": "string",
  "title": "Midterm Exam",
  "thumbnailUrl": "string",
  "durationSeconds": 1,
  "verifiedAt": "2026-03-02T09:00:00.000Z",
  "capabilities": {
    "progressTracking": true,
    "derivedThumbnail": true,
    "serverMetadata": true,
    "thirdPartyAds": 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/lessons/{lessonId}/files

List a lesson’s files for authors and teachers: every visibility, with a short-lived signed download URL each (whole list, `nextCursor` is always null).

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

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

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

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/files" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<LessonFile>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "description": "A short, human-readable description.",
      "visibility": "learners",
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "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/lessons/{lessonId}/files

Register an uploaded lesson file. The stored object’s first bytes are checked against its type; a mismatch deletes the object and refuses the file.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
originalNameمطلوب
string1–255 chars
mimeTypeمطلوب
string1–127 chars
sizeBytesمطلوب
integer1–20971520
fileId
string (uuid)—
storageKeyمطلوب
string1–1024 chars
sha256مطلوب
string—
description
string | string—
visibility
enum: "learners" | "staff"—

مثال

json
{
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": 1,
  "fileId": "0daca32e-0dac-7dac-8aca-0daca32e0dac",
  "storageKey": "string",
  "sha256": "string",
  "description": "A short, human-readable description.",
  "visibility": "learners"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/files" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "originalName": "string",
    "mimeType": "string",
    "sizeBytes": 1,
    "fileId": "0daca32e-0dac-7dac-8aca-0daca32e0dac",
    "storageKey": "string",
    "sha256": "string",
    "description": "A short, human-readable description.",
    "visibility": "learners"
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
originalNameمطلوب
string≥1 chars
mimeTypeمطلوب
string≥1 chars
sizeBytesمطلوب
integer0–9007199254740991
descriptionمطلوب
string | null≥1 chars
visibilityمطلوب
enum: "learners" | "staff"—
sortOrderمطلوب
integer-9007199254740991–9007199254740991
createdAtمطلوب
string (date-time)—
downloadUrlمطلوب
string—
downloadUrlExpiresAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": 0,
  "description": "A short, human-readable description.",
  "visibility": "learners",
  "sortOrder": -9007199254740991,
  "createdAt": "2026-03-02T09:00:00.000Z",
  "downloadUrl": "string",
  "downloadUrlExpiresAt": "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/lessons/{lessonId}/files/order

Reorder every file of a lesson in one call (whole list, `nextCursor` is always null).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
fileIdsمطلوب
array<string (uuid)>—

مثال

json
{
  "fileIds": [
    "e3c52b67-e3c5-73c5-8c52-e3c52b67e3c5"
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/files/order" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "fileIds": [
      "e3c52b67-e3c5-73c5-8c52-e3c52b67e3c5"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<LessonFile>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "description": "A short, human-readable description.",
      "visibility": "learners",
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

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/lessons/{lessonId}/files/upload-url

Get a signed URL to upload a lesson file (PUT the object to `uploadUrl` with the same `Content-Type`). Refused up front for a type that is not allowed, a file over 20 MiB, or when the server has no space left (`STORAGE_FULL`).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
originalNameمطلوب
string1–255 chars
mimeTypeمطلوب
string1–127 chars
sizeBytesمطلوب
integer1–20971520

مثال

json
{
  "originalName": "string",
  "mimeType": "string",
  "sizeBytes": 1
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/files/upload-url" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "originalName": "string",
    "mimeType": "string",
    "sizeBytes": 1
  }'

الاستجابات

201
الاسمالنوعالقيود
storageKeyمطلوب
string—
uploadUrlمطلوب
string—
expiresAtمطلوب
string (date-time)—
json
{
  "storageKey": "string",
  "uploadUrl": "string",
  "expiresAt": "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/lessons/{lessonId}/task

Remove the task under a video lesson. A task that has submissions is refused with 409 (carrying the counts) until `confirmDeleteSubmissions=true` is sent; graded work is never deleted silently.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
confirmDeleteSubmissions
queryenum: "true" | "false"—

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/task" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

204The task was removed.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/lessons/{lessonId}/task

Create or replace the task under a video lesson (instructions, due date, max score, accepted submission kinds). Refused for assignment and quiz units.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
instructionsMdمطلوب
string1–20000 chars
dueAt
string (date-time) | null—
maxScoreمطلوب
number0–1000
allowLate
booleandefault: false
submissionKindsمطلوب
array<enum: "text" | "file" | "link">—

مثال

json
{
  "instructionsMd": "string",
  "dueAt": "2026-03-02T09:00:00.000Z",
  "maxScore": 0,
  "allowLate": false,
  "submissionKinds": [
    "text"
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/task" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "instructionsMd": "string",
    "dueAt": "2026-03-02T09:00:00.000Z",
    "maxScore": 0,
    "allowLate": false,
    "submissionKinds": [
      "text"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/me/courses

Own courses with progress (student), or a linked child’s via `?studentId` (guardian). Published, unlocked lessons only.

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

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

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

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<MyCourseResponse>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "name": "Algebra I",
      "deliveryMode": "group",
      "lessonCount": 0,
      "completedCount": 0,
      "progressPercent": 0,
      "lastLesson": "value",
      "coverThumbnailUrl": "string"
    }
  ],
  "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/me/courses/{courseId}/lessons

Published lessons of one accessible course, in presentation order. A locked lesson is listed but its body, video and attachments are withheld.

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

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

الاسمالموضعالنوعالقيود
courseIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/courses/d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4/lessons" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<MyLessonListItem>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "sectionTitle": "string",
      "title": "Midterm Exam",
      "summary": "string",
      "kind": "lesson",
      "estimatedMinutes": -9007199254740991,
      "hasVideo": true,
      "locked": true,
      "availableAt": "2026-03-02T09:00:00.000Z",
      "progress": "value"
    }
  ],
  "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/me/lessons/{lessonId}

One published, accessible lesson: body, video embed, attachments and its neighbours.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
sectionTitleمطلوب
string≥1 chars
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
hasVideoمطلوب
boolean—
lockedمطلوب
boolean—
availableAtمطلوب
string (date-time) | null—
progressمطلوب
unknown | null—
contentMdمطلوب
string | null≥1 chars
attachmentsمطلوب
array<MyLessonAttachment>—
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
previousLessonIdمطلوب
string (uuid) | null—
nextLessonIdمطلوب
string (uuid) | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "sectionTitle": "string",
  "title": "Midterm Exam",
  "summary": "string",
  "kind": "lesson",
  "estimatedMinutes": -9007199254740991,
  "hasVideo": true,
  "locked": true,
  "availableAt": "2026-03-02T09:00:00.000Z",
  "progress": "value",
  "contentMd": "string",
  "attachments": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "description": "A short, human-readable description.",
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "previousLessonId": "8830a901-8830-7830-830a-8830a9018830",
  "nextLessonId": "289c6ac1-289c-789c-89c6-289c6ac1289c"
}
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/me/lessons/{lessonId}/progress

Record lesson progress (self-reported, non-authoritative). Idempotent: `lesson.completed` is emitted once, on the transition only.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
studentId
querystring (uuid)—

محتوى الطلب

الاسمالنوعالقيود
positionSecondsمطلوب
integer0–86400
watchedSeconds
integer0–86400
completed
boolean—

مثال

json
{
  "positionSeconds": 0,
  "watchedSeconds": 0,
  "completed": true
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/progress" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "positionSeconds": 0,
    "watchedSeconds": 0,
    "completed": true
  }'

الاستجابات

200
الاسمالنوعالقيود
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
statusمطلوب
enum: "in_progress" | "completed"—
lastPositionSecondsمطلوب
integer0–9007199254740991
watchedSecondsمطلوب
integer0–9007199254740991
firstStartedAtمطلوب
string (date-time)—
lastSeenAtمطلوب
string (date-time)—
completedAtمطلوب
string (date-time) | null—
json
{
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "status": "in_progress",
  "lastPositionSeconds": 0,
  "watchedSeconds": 0,
  "firstStartedAt": "2026-03-02T09:00:00.000Z",
  "lastSeenAt": "2026-03-02T09:00:00.000Z",
  "completedAt": "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/me/lessons/{lessonId}/quiz-attempts

My attempts at this quiz, most recent first, with scores; per-answer detail per `showAnswersAfter`.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/quiz-attempts" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "attemptNumber": -9007199254740991,
      "status": "in_progress",
      "startedAt": "2026-03-02T09:00:00.000Z",
      "submittedAt": "2026-03-02T09:00:00.000Z",
      "deadlineAt": "2026-03-02T09:00:00.000Z",
      "score": 1,
      "maxScore": 1,
      "passed": true,
      "questions": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "kind": "single",
          "promptMd": "string",
          "options": [
            {
              "id": "37386ae0-3738-7738-8386-37386ae03738",
              "textMd": "string"
            }
          ],
          "points": 0
        }
      ],
      "answers": [
        {
          "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
          "answer": "string",
          "isCorrect": true,
          "pointsAwarded": 1,
          "needsGrading": true,
          "feedbackMd": "string",
          "correctAnswer": "string"
        }
      ]
    }
  ],
  "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/lessons/{lessonId}/quiz-attempts

Start a new attempt (or resume the current in-progress one). Refused when attempts are exhausted or the quiz is closed past its due date. Questions are returned without `correct`, shuffled per attempt when the quiz shuffles.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/quiz-attempts" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
quizIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
attemptNumberمطلوب
integer-9007199254740991–9007199254740991
statusمطلوب
enum: "in_progress" | "submitted" | "expired"—
startedAtمطلوب
string (date-time)—
submittedAtمطلوب
string (date-time) | null—
deadlineAtمطلوب
string (date-time) | null—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
passedمطلوب
boolean | null—
questionsمطلوب
array<QuizAttemptQuestion>—
answersمطلوب
array<QuizAttemptAnswer> | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "attemptNumber": -9007199254740991,
  "status": "in_progress",
  "startedAt": "2026-03-02T09:00:00.000Z",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "deadlineAt": "2026-03-02T09:00:00.000Z",
  "score": 1,
  "maxScore": 1,
  "passed": true,
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "points": 0
    }
  ],
  "answers": [
    {
      "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
      "answer": "string",
      "isCorrect": true,
      "pointsAwarded": 1,
      "needsGrading": true,
      "feedbackMd": "string",
      "correctAnswer": "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/me/lessons/{lessonId}/quiz-attempts/{attemptId}

Read one of my attempts.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
attemptIdمطلوب
pathstring—
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/quiz-attempts/ca174553-ca17-7a17-8174-ca174553ca17" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
quizIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
attemptNumberمطلوب
integer-9007199254740991–9007199254740991
statusمطلوب
enum: "in_progress" | "submitted" | "expired"—
startedAtمطلوب
string (date-time)—
submittedAtمطلوب
string (date-time) | null—
deadlineAtمطلوب
string (date-time) | null—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
passedمطلوب
boolean | null—
questionsمطلوب
array<QuizAttemptQuestion>—
answersمطلوب
array<QuizAttemptAnswer> | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "attemptNumber": -9007199254740991,
  "status": "in_progress",
  "startedAt": "2026-03-02T09:00:00.000Z",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "deadlineAt": "2026-03-02T09:00:00.000Z",
  "score": 1,
  "maxScore": 1,
  "passed": true,
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "points": 0
    }
  ],
  "answers": [
    {
      "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
      "answer": "string",
      "isCorrect": true,
      "pointsAwarded": 1,
      "needsGrading": true,
      "feedbackMd": "string",
      "correctAnswer": "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/me/lessons/{lessonId}/quiz-attempts/{attemptId}/answers/{questionId}

Upsert one answer. Refused after submit or past the attempt’s deadline.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
attemptIdمطلوب
pathstring—
questionIdمطلوب
pathstring—
studentId
querystring (uuid)—

محتوى الطلب

الاسمالنوعالقيود
answerمطلوب
string | array<string> | boolean | null—

مثال

json
{
  "answer": "string"
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/quiz-attempts/ca174553-ca17-7a17-8174-ca174553ca17/answers/53cf0780-53cf-73cf-8cf0-53cf078053cf" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "answer": "string"
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
quizIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
attemptNumberمطلوب
integer-9007199254740991–9007199254740991
statusمطلوب
enum: "in_progress" | "submitted" | "expired"—
startedAtمطلوب
string (date-time)—
submittedAtمطلوب
string (date-time) | null—
deadlineAtمطلوب
string (date-time) | null—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
passedمطلوب
boolean | null—
questionsمطلوب
array<QuizAttemptQuestion>—
answersمطلوب
array<QuizAttemptAnswer> | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "attemptNumber": -9007199254740991,
  "status": "in_progress",
  "startedAt": "2026-03-02T09:00:00.000Z",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "deadlineAt": "2026-03-02T09:00:00.000Z",
  "score": 1,
  "maxScore": 1,
  "passed": true,
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "points": 0
    }
  ],
  "answers": [
    {
      "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
      "answer": "string",
      "isCorrect": true,
      "pointsAwarded": 1,
      "needsGrading": true,
      "feedbackMd": "string",
      "correctAnswer": "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/me/lessons/{lessonId}/quiz-attempts/{attemptId}/submit

Submit the attempt: auto-grades every closed question, computes score/passed, and stamps lesson_progress completion per §3.6. Refused past the attempt’s deadline.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
attemptIdمطلوب
pathstring—
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/quiz-attempts/ca174553-ca17-7a17-8174-ca174553ca17/submit" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
quizIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
attemptNumberمطلوب
integer-9007199254740991–9007199254740991
statusمطلوب
enum: "in_progress" | "submitted" | "expired"—
startedAtمطلوب
string (date-time)—
submittedAtمطلوب
string (date-time) | null—
deadlineAtمطلوب
string (date-time) | null—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
passedمطلوب
boolean | null—
questionsمطلوب
array<QuizAttemptQuestion>—
answersمطلوب
array<QuizAttemptAnswer> | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "attemptNumber": -9007199254740991,
  "status": "in_progress",
  "startedAt": "2026-03-02T09:00:00.000Z",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "deadlineAt": "2026-03-02T09:00:00.000Z",
  "score": 1,
  "maxScore": 1,
  "passed": true,
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "points": 0
    }
  ],
  "answers": [
    {
      "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
      "answer": "string",
      "isCorrect": true,
      "pointsAwarded": 1,
      "needsGrading": true,
      "feedbackMd": "string",
      "correctAnswer": "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/me/lessons/{lessonId}/submission

Submit or resubmit an assignment (self-scoped upload for any attached files, `entityType: "assignment_submission"`, `entityId: <lessonId>`, before this call). Refused once graded until the teacher returns it.

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

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
studentId
querystring (uuid)—

محتوى الطلب

الاسمالنوعالقيود
textMd
enum: "" | string | null—
link
enum: "" | string | null—

مثال

json
{
  "textMd": "",
  "link": ""
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/me/lessons/3d477cf4-3d47-7d47-8477-3d477cf43d47/submission" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "textMd": "",
    "link": ""
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
assignmentIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
submittedAtمطلوب
string (date-time)—
textMdمطلوب
string | null≥1 chars
linkمطلوب
string | null—
filesمطلوب
array<SubmissionFile>—
statusمطلوب
enum: "submitted" | "late" | "returned" | "graded"—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
feedbackMdمطلوب
string | null≥1 chars
gradedByUserIdمطلوب
string (uuid) | null—
gradedByNameمطلوب
string | null≥1 chars
gradedAtمطلوب
string (date-time) | null—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "assignmentId": "c41b0f8d-c41b-741b-81b0-c41b0f8dc41b",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "textMd": "string",
  "link": "string",
  "files": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "originalName": "string",
      "mimeType": "string",
      "sizeBytes": 0,
      "downloadUrl": "string",
      "downloadUrlExpiresAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "status": "submitted",
  "score": 1,
  "maxScore": 1,
  "feedbackMd": "string",
  "gradedByUserId": "71e16c27-71e1-71e1-8e16-71e16c2771e1",
  "gradedByName": "string",
  "gradedAt": "2026-03-02T09:00:00.000Z",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/me/next-up

What to do next: due assignments (ascending due date, overdue flagged) then unstarted/in-progress units, capped at 10.

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

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

الاسمالموضعالنوعالقيود
studentId
querystring (uuid)—

مثال بأمر curl

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

الاستجابات

200
الاسمالنوعالقيود
studentIdمطلوب
string (uuid)—
itemsمطلوب
array<NextUpItem>—
json
{
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "items": [
    {
      "kind": "assignment_due",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "courseName": "string",
      "unitId": "6d6cc9ea-6d6c-7d6c-86cc-6d6cc9ea6d6c",
      "unitTitle": "string",
      "unitKind": "lesson",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "sectionTitle": "string",
      "dueAt": "2026-03-02T09:00:00.000Z",
      "overdue": 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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PATCH /api/v1/quizzes/{lessonId}

Update a quiz’s own settings (time limit, attempts allowed, shuffle, show-answers-after, pass score, due date). Lesson-shared fields go through `PATCH /lessons/:id`.

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

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

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

محتوى الطلب

الاسمالنوعالقيود
timeLimitMinutes
integer | null1–600
attemptsAllowed
integer1–20
shuffle
boolean—
showAnswersAfter
enum: "never" | "after_submit" | "after_due"—
passScore
number | null≤100000
dueAt
string (date-time) | null—

مثال

json
{
  "timeLimitMinutes": 1,
  "attemptsAllowed": 1,
  "shuffle": true,
  "showAnswersAfter": "never",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z"
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "timeLimitMinutes": 1,
    "attemptsAllowed": 1,
    "shuffle": true,
    "showAnswersAfter": "never",
    "passScore": 1,
    "dueAt": "2026-03-02T09:00:00.000Z"
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
sectionIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
summaryمطلوب
string | null≥1 chars
contentMdمطلوب
string | null≥1 chars
kindمطلوب
enum: "lesson" | "assignment" | "quiz"—
statusمطلوب
enum: "draft" | "published"—
publishedAtمطلوب
string (date-time) | null—
availableFromمطلوب
string (date-time) | null—
availableAfterDaysمطلوب
integer | null-9007199254740991–9007199254740991
estimatedMinutesمطلوب
integer | null-9007199254740991–9007199254740991
sortOrderمطلوب
integer-9007199254740991–9007199254740991
videoمطلوب
unknown | null—
assignmentمطلوب
unknown | null—
quizمطلوب
unknown | null—
audienceمطلوب
LessonAudience—
reminderModeمطلوب
enum: "inherit" | "on" | "off"—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
  "title": "Midterm Exam",
  "summary": "string",
  "contentMd": "string",
  "kind": "lesson",
  "status": "draft",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "availableFrom": "2026-03-02T09:00:00.000Z",
  "availableAfterDays": -9007199254740991,
  "estimatedMinutes": -9007199254740991,
  "sortOrder": -9007199254740991,
  "video": "value",
  "assignment": "value",
  "quiz": "value",
  "audience": {
    "restricted": true,
    "groups": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "name": "Algebra I"
      }
    ],
    "hidden": true
  },
  "reminderMode": "inherit",
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/quizzes/{lessonId}/attempts

List a quiz’s attempts (cursor-paginated, optional student/status filters).

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
studentId
querystring (uuid)—
status
queryenum: "in_progress" | "submitted"—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/attempts" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "attemptNumber": -9007199254740991,
      "status": "in_progress",
      "startedAt": "2026-03-02T09:00:00.000Z",
      "submittedAt": "2026-03-02T09:00:00.000Z",
      "deadlineAt": "2026-03-02T09:00:00.000Z",
      "score": 1,
      "maxScore": 1,
      "passed": true,
      "questions": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "kind": "single",
          "promptMd": "string",
          "options": [
            {
              "id": "37386ae0-3738-7738-8386-37386ae03738",
              "textMd": "string"
            }
          ],
          "points": 0
        }
      ],
      "answers": [
        {
          "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
          "answer": "string",
          "isCorrect": true,
          "pointsAwarded": 1,
          "needsGrading": true,
          "feedbackMd": "string",
          "correctAnswer": "string"
        }
      ]
    }
  ],
  "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/quizzes/{lessonId}/attempts/{attemptId}/answers/{questionId}/grade

Grade a short-answer (`short_text`) answer (points ≤ the question’s own points). Finalises the attempt’s score/passed once nothing is left ungraded. Emits `quiz.graded` on finalisation.

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

الاسمالموضعالنوعالقيود
lessonIdمطلوب
pathstring—
attemptIdمطلوب
pathstring—
questionIdمطلوب
pathstring—

محتوى الطلب

الاسمالنوعالقيود
pointsAwardedمطلوب
number≥0
feedbackMd
enum: "" | string | null—

مثال

json
{
  "pointsAwarded": 0,
  "feedbackMd": ""
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/attempts/ca174553-ca17-7a17-8174-ca174553ca17/answers/53cf0780-53cf-73cf-8cf0-53cf078053cf/grade" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "pointsAwarded": 0,
    "feedbackMd": ""
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
quizIdمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
studentIdمطلوب
string (uuid)—
attemptNumberمطلوب
integer-9007199254740991–9007199254740991
statusمطلوب
enum: "in_progress" | "submitted" | "expired"—
startedAtمطلوب
string (date-time)—
submittedAtمطلوب
string (date-time) | null—
deadlineAtمطلوب
string (date-time) | null—
scoreمطلوب
number | null—
maxScoreمطلوب
number—
passedمطلوب
boolean | null—
questionsمطلوب
array<QuizAttemptQuestion>—
answersمطلوب
array<QuizAttemptAnswer> | null—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
  "attemptNumber": -9007199254740991,
  "status": "in_progress",
  "startedAt": "2026-03-02T09:00:00.000Z",
  "submittedAt": "2026-03-02T09:00:00.000Z",
  "deadlineAt": "2026-03-02T09:00:00.000Z",
  "score": 1,
  "maxScore": 1,
  "passed": true,
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "points": 0
    }
  ],
  "answers": [
    {
      "questionId": "53cf0780-53cf-73cf-8cf0-53cf078053cf",
      "answer": "string",
      "isCorrect": true,
      "pointsAwarded": 1,
      "needsGrading": true,
      "feedbackMd": "string",
      "correctAnswer": "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/quizzes/{lessonId}/publish-to-gradebook

Publish each student’s best fully-graded attempt into the gradebook as a `quiz` exam per group — one click, upserts on repeat.

يتطلّب المصادقةالصلاحيةcurriculum.assignments.grade

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

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

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/publish-to-gradebook" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
publishedمطلوب
array<object>—
skippedمطلوب
array<object>—
json
{
  "published": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "groupId": "6dc7fce6-6dc7-7dc7-8c7f-6dc7fce66dc7",
      "examId": "6c140414-6c14-7c14-8140-6c1404146c14",
      "score": 1
    }
  ],
  "skipped": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "reason": "no_group"
    }
  ]
}
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/quizzes/{lessonId}/questions

Add a question to a quiz. Returns the whole quiz (questions included).

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

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

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

محتوى الطلب

الاسمالنوعالقيود
kindمطلوب
enum: "single" | "multiple" | "true_false" | "short_text"—
promptMdمطلوب
string1–5000 chars
options
array<object>—
correct
string | array<string> | boolean | null—
pointsمطلوب
number0–1000

مثال

json
{
  "kind": "single",
  "promptMd": "string",
  "options": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "textMd": "string"
    }
  ],
  "correct": "string",
  "points": 0
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/questions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "kind": "single",
    "promptMd": "string",
    "options": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "textMd": "string"
      }
    ],
    "correct": "string",
    "points": 0
  }'

الاستجابات

201
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
timeLimitMinutesمطلوب
integer | null-9007199254740991–9007199254740991
attemptsAllowedمطلوب
integer0–9007199254740991
shuffleمطلوب
boolean—
showAnswersAfterمطلوب
enum: "never" | "after_submit" | "after_due"—
passScoreمطلوب
number | null—
dueAtمطلوب
string (date-time) | null—
publishedAtمطلوب
string (date-time) | null—
questionsمطلوب
array<QuizQuestion>—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "timeLimitMinutes": -9007199254740991,
  "attemptsAllowed": 0,
  "shuffle": true,
  "showAnswersAfter": "never",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "correct": "string",
      "points": 0,
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "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/quizzes/{lessonId}/questions/{questionId}

Delete a question. Returns the whole quiz (questions included).

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

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

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

مثال بأمر curl

curl
curl -X DELETE "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/questions/53cf0780-53cf-73cf-8cf0-53cf078053cf" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
timeLimitMinutesمطلوب
integer | null-9007199254740991–9007199254740991
attemptsAllowedمطلوب
integer0–9007199254740991
shuffleمطلوب
boolean—
showAnswersAfterمطلوب
enum: "never" | "after_submit" | "after_due"—
passScoreمطلوب
number | null—
dueAtمطلوب
string (date-time) | null—
publishedAtمطلوب
string (date-time) | null—
questionsمطلوب
array<QuizQuestion>—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "timeLimitMinutes": -9007199254740991,
  "attemptsAllowed": 0,
  "shuffle": true,
  "showAnswersAfter": "never",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "correct": "string",
      "points": 0,
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PATCH /api/v1/quizzes/{lessonId}/questions/{questionId}

Update a question. Returns the whole quiz (questions included).

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

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

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

محتوى الطلب

الاسمالنوعالقيود
kind
enum: "single" | "multiple" | "true_false" | "short_text"—
promptMd
string1–5000 chars
options
array<object>—
correct
string | array<string> | boolean | null—
points
number0–1000

مثال

json
{
  "kind": "single",
  "promptMd": "string",
  "options": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "textMd": "string"
    }
  ],
  "correct": "string",
  "points": 0
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/questions/53cf0780-53cf-73cf-8cf0-53cf078053cf" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "kind": "single",
    "promptMd": "string",
    "options": [
      {
        "id": "37386ae0-3738-7738-8386-37386ae03738",
        "textMd": "string"
      }
    ],
    "correct": "string",
    "points": 0
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
timeLimitMinutesمطلوب
integer | null-9007199254740991–9007199254740991
attemptsAllowedمطلوب
integer0–9007199254740991
shuffleمطلوب
boolean—
showAnswersAfterمطلوب
enum: "never" | "after_submit" | "after_due"—
passScoreمطلوب
number | null—
dueAtمطلوب
string (date-time) | null—
publishedAtمطلوب
string (date-time) | null—
questionsمطلوب
array<QuizQuestion>—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "timeLimitMinutes": -9007199254740991,
  "attemptsAllowed": 0,
  "shuffle": true,
  "showAnswersAfter": "never",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "correct": "string",
      "points": 0,
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/quizzes/{lessonId}/questions/order

Whole-list reorder of a quiz’s questions. Returns the whole quiz (questions included).

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

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

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

محتوى الطلب

الاسمالنوعالقيود
questionIdsمطلوب
array<string (uuid)>—

مثال

json
{
  "questionIds": [
    "e1e98389-e1e9-71e9-8e98-e1e98389e1e9"
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/quizzes/3d477cf4-3d47-7d47-8477-3d477cf43d47/questions/order" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "questionIds": [
      "e1e98389-e1e9-71e9-8e98-e1e98389e1e9"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
lessonIdمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
timeLimitMinutesمطلوب
integer | null-9007199254740991–9007199254740991
attemptsAllowedمطلوب
integer0–9007199254740991
shuffleمطلوب
boolean—
showAnswersAfterمطلوب
enum: "never" | "after_submit" | "after_due"—
passScoreمطلوب
number | null—
dueAtمطلوب
string (date-time) | null—
publishedAtمطلوب
string (date-time) | null—
questionsمطلوب
array<QuizQuestion>—
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "lessonId": "3d477cf4-3d47-7d47-8477-3d477cf43d47",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "timeLimitMinutes": -9007199254740991,
  "attemptsAllowed": 0,
  "shuffle": true,
  "showAnswersAfter": "never",
  "passScore": 1,
  "dueAt": "2026-03-02T09:00:00.000Z",
  "publishedAt": "2026-03-02T09:00:00.000Z",
  "questions": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "quizId": "a5ed7659-a5ed-75ed-8ed7-a5ed7659a5ed",
      "kind": "single",
      "promptMd": "string",
      "options": [
        {
          "id": "37386ae0-3738-7738-8386-37386ae03738",
          "textMd": "string"
        }
      ],
      "correct": "string",
      "points": 0,
      "sortOrder": -9007199254740991,
      "createdAt": "2026-03-02T09:00:00.000Z",
      "updatedAt": "2026-03-02T09:00:00.000Z"
    }
  ],
  "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/sections/{id}

Delete a section. Fails with 409 if it still has lessons.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

مثال بأمر curl

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

الاستجابات

204The section was deleted.

لا يحدّد ملف OpenAPI الخاص بالواجهة مخطّطًا مكتوبًا لهذه الاستجابة بعد — الاستجابة لا تزال JSON صالحًا، لكنها غير موثّقة هنا.

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/sections/{id}

Update a section.

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
title
string1–200 chars
description
enum: "" | string | null—

مثال

json
{
  "title": "Midterm Exam",
  "description": ""
}

مثال بأمر curl

curl
curl -X PATCH "https://your-institute.example/api/v1/sections/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "title": "Midterm Exam",
    "description": ""
  }'

الاستجابات

200
الاسمالنوعالقيود
idمطلوب
string (uuid)—
courseIdمطلوب
string (uuid)—
titleمطلوب
string≥1 chars
descriptionمطلوب
string | null≥1 chars
sortOrderمطلوب
integer-9007199254740991–9007199254740991
createdAtمطلوب
string (date-time)—
updatedAtمطلوب
string (date-time)—
json
{
  "id": "37386ae0-3738-7738-8386-37386ae03738",
  "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
  "title": "Midterm Exam",
  "description": "A short, human-readable description.",
  "sortOrder": -9007199254740991,
  "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

PUT /api/v1/sections/{sectionId}/lessons/order

Reorder every lesson of a section in one call (whole-list, unpaginated response envelope).

يتطلّب المصادقةالصلاحيةcurriculum.write

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

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

محتوى الطلب

الاسمالنوعالقيود
lessonIdsمطلوب
array<string (uuid)>—

مثال

json
{
  "lessonIds": [
    "fe890885-fe89-7e89-8890-fe890885fe89"
  ]
}

مثال بأمر curl

curl
curl -X PUT "https://your-institute.example/api/v1/sections/c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab/lessons/order" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "lessonIds": [
      "fe890885-fe89-7e89-8890-fe890885fe89"
    ]
  }'

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "sectionId": "c1ab4be1-c1ab-71ab-8ab4-c1ab4be1c1ab",
      "title": "Midterm Exam",
      "summary": "string",
      "contentMd": "string",
      "kind": "lesson",
      "status": "draft",
      "publishedAt": "2026-03-02T09:00:00.000Z",
      "availableFrom": "2026-03-02T09:00:00.000Z",
      "availableAfterDays": -9007199254740991,
      "estimatedMinutes": -9007199254740991,
      "sortOrder": -9007199254740991,
      "video": "value",
      "assignment": "value",
      "quiz": "value",
      "audience": {
        "restricted": true,
        "groups": [
          {
            "id": "37386ae0-3738-7738-8386-37386ae03738",
            "name": "Algebra I"
          }
        ],
        "hidden": true
      },
      "reminderMode": "inherit",
      "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

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/students/{studentId}/course-enrollments

List one student’s self-paced course enrollments (cursor-paginated).

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

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

الاسمالموضعالنوعالقيود
studentIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
status
queryenum: "pending" | "active" | "completed" | "dropped"—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/students/a4a70332-a4a7-74a7-8a70-a4a70332a4a7/course-enrollments" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "id": "37386ae0-3738-7738-8386-37386ae03738",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "status": "pending",
      "grantedAt": "2026-03-02T09:00:00.000Z",
      "endedAt": "2026-03-02T09:00:00.000Z",
      "priceMinor": 12000,
      "currency": "ILS",
      "grantedByUserId": "fc4e27b3-fc4e-7c4e-84e2-fc4e27b3fc4e",
      "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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.

GET /api/v1/students/{studentId}/course-progress

One student’s per-course curriculum progress (cursor-paginated, row-scoped).

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

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

الاسمالموضعالنوعالقيود
studentIdمطلوب
pathstring—
cursor
querystring—
limit
queryinteger1–100 · default: 25
studentId
querystring (uuid)—

مثال بأمر curl

curl
curl -X GET "https://your-institute.example/api/v1/students/a4a70332-a4a7-74a7-8a70-a4a70332a4a7/course-progress" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"

الاستجابات

200
الاسمالنوعالقيود
dataمطلوب
array<object>—
nextCursorمطلوب
string | null—
json
{
  "data": [
    {
      "studentId": "a4a70332-a4a7-74a7-8a70-a4a70332a4a7",
      "courseId": "d0e4743a-d0e4-70e4-8e47-d0e4743ad0e4",
      "courseName": "string",
      "lessonCount": 0,
      "completedCount": 0,
      "progressPercent": 0,
      "lastLessonId": "b9705f30-b970-7970-8705-b9705f30b970",
      "lastSeenAt": "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/video-sources/resolve

Parse and (best-effort, YouTube only) enrich a pasted video URL, without saving it anywhere.

يتطلّب المصادقةالصلاحيةcurriculum.write

محتوى الطلب

الاسمالنوعالقيود
urlمطلوب
string1–2048 chars

مثال

json
{
  "url": "https://example.com/webhooks/institflow"
}

مثال بأمر curl

curl
curl -X POST "https://your-institute.example/api/v1/video-sources/resolve" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "url": "https://example.com/webhooks/institflow"
  }'

الاستجابات

200
الاسمالنوعالقيود
providerمطلوب
enum: "youtube"—
externalRefمطلوب
string≥1 chars
canonicalUrlمطلوب
string—
embedUrlمطلوب
string—
thumbnailUrlمطلوب
string | null—
titleمطلوب
string | null≥1 chars
durationSecondsمطلوب
integer | null1–9007199254740991
capabilitiesمطلوب
object—
warningsمطلوب
array<enum: "metadata_unavailable" | "privacy_must_be_unlisted">—
json
{
  "provider": "youtube",
  "externalRef": "string",
  "canonicalUrl": "string",
  "embedUrl": "string",
  "thumbnailUrl": "string",
  "title": "Midterm Exam",
  "durationSeconds": 1,
  "capabilities": {
    "progressTracking": true,
    "derivedThumbnail": true,
    "serverMetadata": true
  },
  "warnings": [
    "metadata_unavailable"
  ]
}
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? } }`. جميع الرموز مذكورة في دليل الاصطلاحات.