Skip to main content

API Contracts

:::info Source Sourced from services/enrollment-service/API_CONTRACTS.md in the documentation repo. :::

1. Endpoints

POST /api/v1/enrollments (admin)
GET /api/v1/enrollments/{id}
GET /api/v1/enrollments ?filter[userId]=&filter[courseId]=&filter[state]=active
PATCH /api/v1/enrollments/{id} (admin; metadata only)
POST /api/v1/enrollments/{id}/revoke
GET /api/v1/users/{uid}/enrollments
GET /api/v1/courses/{cid}/enrollments (admin; pagination)
POST /api/v1/self-enroll body: { courseId }
POST /api/v1/enrollments/bulk (admin bulk create; async)

2. Request/Response

Create

POST /api/v1/enrollments
{
"userId": "u_01H...",
"courseId": "crs_01H...",
"courseVersionId": "cv_01H...",
"source": { "kind": "manual", "ref": "admin-batch-123" },
"expiresAt": "2027-01-01T00:00:00Z"
}
Response:
{
"data": {
"id": "enr_01H...",
"state": "active",
"source": { ... },
"enrolledAt": "...",
"expiresAt": "...",
"attemptCounter": 0
}
}

3. Error Model

  • resource.not_found (course / user)
  • resource.conflict (enrollment exists for same source.ref)
  • authz.forbidden
  • enrollment.license_exhausted
  • enrollment.course_version.withdrawn

4. Pagination

Cursor; page[size] max 200.

5. Rate Limits

  • Admin bulk: 1 per minute per tenant; up to 50k rows.
  • Self-enroll: 10/min per user.

6. Security

  • enrollment:write (admin) for POST/PATCH.
  • enrollment:self for self-enroll.
  • enrollment:read for learners reading own.
  • enrollment:admin for cross-user queries.

7. Idempotency

Idempotency-Key required on writes. Dedup on (tenantId, userId, courseId, source.ref).

8. SLOs

  • Create p95 < 500ms.
  • List p95 < 300ms (cached).
  • Bulk create 50k rows p95 < 5 min.
  • API availability 99.99%.