Reports
Partially available (
LMS-572). The Completions Report (GET /api/v1/reports/completions) and Enrollments Report (GET /api/v1/reports/enrollments) are live (read scope). Still planned — not yet available (return404today): the Compliance, User Activity, and Course Performance reports and the async export job endpoints (POST /api/v1/reports/export,GET /api/v1/reports/export/{job_id}). The User Activity report’stotal_loginsis gated on a per-session login-event store that is not yet built.
The Reports API provides access to aggregated learning data across your tenant. All report endpoints return paginated data. For large data sets, use the async export endpoints.
Endpoints
Completions Report
GET /api/v1/reports/completionsReturns a list of course completions with optional filters.
Authentication required: read scope
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Default: 1 |
per_page | integer | No | Default: 50, max: 200 |
course_id | UUID | No | Filter to a specific course |
user_id | UUID | No | Filter to a specific user |
group_id | UUID | No | Filter to users in a specific group |
completed_after | ISO 8601 | No | Filter completions after this timestamp |
completed_before | ISO 8601 | No | Filter completions before this timestamp |
pass_fail | string | No | pass or fail |
sort_by | string | No | completed_at, score. Default: completed_at |
sort_order | string | No | asc or desc. Default: desc |
Example Request
curl "https://{your-subdomain}.embaylms.com/api/v1/reports/completions?completed_after=2026-01-01T00:00:00Z" \
-H "Authorization: Bearer ems_live_0000000000000000000000000000"Example Response
{
"data": [
{
"enrollment_id": "d6e5f4a3-7b8c-9012-defa-123456789012",
"user_id": "a3f2c1d0-4e5b-6789-abcd-ef0123456789",
"course_id": "e7f6a5b4-8c9d-0123-efab-234567890123",
"course_title": "WHMIS 2015",
"completed_at": "2026-03-15T11:30:00Z",
"score": 92,
"pass_fail": "pass",
"time_spent_seconds": 1820,
"certificate_id": "f8a7b6c5-9d0e-1234-fabc-345678901234"
}
],
"meta": { "page": 1, "per_page": 50, "total": 1480 },
"error": null
}Enrollments Report
GET /api/v1/reports/enrollmentsReturns enrollment activity over a time period.
Authentication required: read scope
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Default: 1 |
per_page | integer | No | Default: 50, max: 200 |
course_id | UUID | No | Filter to a specific course |
group_id | UUID | No | Filter to a specific group |
status | string | No | active, completed, dropped, expired, waitlisted, pending_approval |
enrolled_after | ISO 8601 | No | Filter enrollments created after this timestamp |
enrolled_before | ISO 8601 | No | Filter enrollments created before this timestamp |
Example Response
{
"data": [
{
"enrollment_id": "d6e5f4a3-7b8c-9012-defa-123456789012",
"user_id": "a3f2c1d0-4e5b-6789-abcd-ef0123456789",
"course_id": "e7f6a5b4-8c9d-0123-efab-234567890123",
"course_title": "Workplace Safety Fundamentals",
"status": "active",
"enrolled_at": "2026-04-01T08:00:00Z",
"due_date": "2026-05-01T00:00:00Z",
"days_overdue": 35
}
],
"meta": { "page": 1, "per_page": 50, "total": 23 },
"error": null
}Compliance Report
GET /api/v1/reports/complianceReturns compliance status per user per required course. A user is compliant when they have a current, passing completion for each required course in their assigned groups.
Authentication required: read scope
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Default: 1 |
per_page | integer | No | Default: 50, max: 200 |
group_id | UUID | No | Filter to a specific group |
course_id | UUID | No | Filter to a specific required course |
status | string | No | compliant, non_compliant, expiring_soon (within 30 days) |
as_of | ISO 8601 | No | Compliance snapshot at a specific date. Default: now |
Example Response
{
"data": [
{
"user_id": "a3f2c1d0-4e5b-6789-abcd-ef0123456789",
"course_id": "e7f6a5b4-8c9d-0123-efab-234567890123",
"course_title": "WHMIS 2015",
"compliance_status": "non_compliant",
"last_completion_date": null,
"certificate_expires_at": null,
"days_until_expiry": null
}
],
"meta": { "page": 1, "per_page": 50, "total": 47 },
"error": null
}User Activity Report
GET /api/v1/reports/users/activityReturns user login and learning activity metrics over a time period.
Authentication required: read scope
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Default: 1 |
per_page | integer | No | Default: 50, max: 200 |
group_id | UUID | No | Filter to a specific group |
active_after | ISO 8601 | No | Include users with activity after this date |
active_before | ISO 8601 | No | Include users with activity before this date |
include_inactive | boolean | No | Include users with no activity in the period. Default: false |
Example Response
{
"data": [
{
"user_id": "a3f2c1d0-4e5b-6789-abcd-ef0123456789",
"last_login_at": "2026-06-04T14:22:11Z",
"total_logins": 12,
"total_time_spent_seconds": 18200,
"courses_started": 3,
"courses_completed": 2,
"period_start": "2026-05-01T00:00:00Z",
"period_end": "2026-06-05T00:00:00Z"
}
],
"meta": { "page": 1, "per_page": 50, "total": 218 },
"error": null
}Course Performance Report
GET /api/v1/reports/courses/performanceReturns performance metrics per course including completion rates, average scores, and average time to complete.
Authentication required: read scope
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Default: 1 |
per_page | integer | No | Default: 50, max: 200 |
course_id | UUID | No | Filter to a specific course |
category | string | No | Filter by course category |
period_start | ISO 8601 | No | Start of the reporting period |
period_end | ISO 8601 | No | End of the reporting period |
Example Response
{
"data": [
{
"course_id": "e7f6a5b4-8c9d-0123-efab-234567890123",
"course_title": "WHMIS 2015",
"total_enrollments": 312,
"completions": 287,
"completion_rate_percent": 92,
"average_score": 84.3,
"pass_rate_percent": 96,
"average_time_to_complete_seconds": 1950,
"drop_off_rate_percent": 8
}
],
"meta": { "page": 1, "per_page": 50, "total": 22 },
"error": null
}Queue Export Job
POST /api/v1/reports/exportQueues an asynchronous export job. Use this for data sets larger than 1,000 rows. Returns a job_id to poll for status.
Authentication required: read scope
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
report_type | string | Yes | completions, enrollments, compliance, user_activity, course_performance |
format | string | No | csv (default) or xlsx |
filters | object | No | Same filter parameters as the corresponding GET endpoint |
notify_email | string | No | Email address to notify when the export is ready |
Example Response
{
"data": {
"job_id": "7a8b9c0d-1e2f-3456-bcde-456789012345",
"status": "queued",
"report_type": "compliance",
"format": "csv",
"created_at": "2026-06-05T11:00:00Z",
"estimated_completion_seconds": 30
},
"meta": null,
"error": null
}HTTP Status: 202 Accepted
Get Export Job Status
GET /api/v1/reports/export/{job_id}Polls an async export job. When complete, a pre-signed S3 download URL is returned valid for 15 minutes.
Authentication required: read scope
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
job_id | UUID | Yes | Job UUID returned by POST /reports/export |
Example Response — Completed
{
"data": {
"job_id": "7a8b9c0d-1e2f-3456-bcde-456789012345",
"status": "completed",
"progress_percent": 100,
"row_count": 1482,
"file_size_bytes": 245760,
"created_at": "2026-06-05T11:00:00Z",
"completed_at": "2026-06-05T11:00:42Z",
"download_url": "https://exports.embaylms.com/tenant-acme/exports/compliance-2026-06-05.csv?X-Amz-Signature=abc123...",
"download_url_expires_at": "2026-06-05T11:15:42Z"
},
"meta": null,
"error": null
}Job status values: queued, processing, completed, failed
Poll every 5-10 seconds. If status is failed, create a new export job to retry.