Skip to content

REST API Reference

LearnDash Dashboard exposes two REST API namespaces:

  • ldd_report/v1 — User statistics
  • ld-dashboard/v2 — Reports, charts, and private messaging

Base URL: {site_url}/wp-json/


All endpoints require a logged-in WordPress session. Use cookie-based authentication with the X-WP-Nonce header.

// Get nonce from localized data
const nonce = ldReportData.nonce; // or ld_dashboard_public_js.nonce
fetch( '/wp-json/ld-dashboard/v2/reports', {
headers: {
'X-WP-Nonce': nonce,
'Content-Type': 'application/json',
},
credentials: 'same-origin',
} );

The nonce is generated with wp_create_nonce( 'wp_rest' ).


Namespace: ld-dashboard/v2

Messaging requires the enable-private-messaging setting to be enabled. All messaging endpoints require the user to be logged in.


Retrieve conversations (inbox) for the current user.

Permission: Logged in

Parameters:

Parameter Type Default Description
page int 1 Page number
per_page int 20 Conversations per page (max 50)

Response:

{
"conversations": [
{
"thread_id": 42,
"subject": "Question about Lesson 3",
"course_id": 100,
"course_name": "Introduction to PHP",
"other_user": {
"id": 5,
"name": "Jane Smith",
"avatar": "https://example.com/avatar.jpg"
},
"last_message": "Thanks for the clarification!",
"last_message_at": "2026-02-20 14:32:00",
"unread_count": 2
}
],
"total": 15,
"pages": 1
}

Send a new message or reply to an existing thread.

Permission: Logged in

Body parameters:

Parameter Type Required Description
recipient_id int Yes WordPress user ID of the recipient
course_id int Yes Course ID for context (required for new threads)
subject string Yes* Subject line (*required for new threads only)
message string Yes Message body (HTML allowed via wp_kses_post)
parent_id int No Thread ID to reply to (omit for new conversations)

Messaging rules:

  • Admins can message anyone.
  • Instructors can message students enrolled in their courses and co-instructors.
  • Group leaders can message members of their groups.
  • Students can only message instructors of their enrolled courses.

Response (201):

{
"id": 57,
"message": "Message sent successfully.",
"thread_id": 42
}

Error (403):

{
"code": "rest_forbidden",
"message": "You cannot message this user. You must share a course relationship.",
"data": { "status": 403 }
}

Get all messages in a thread.

Permission: Must be the sender or recipient of the thread

URL parameters:

Parameter Type Description
id int Thread ID (root message ID)

Response:

{
"thread_id": 42,
"subject": "Question about Lesson 3",
"course_id": 100,
"course_name": "Introduction to PHP",
"other_user": {
"id": 5,
"name": "Jane Smith",
"avatar": "https://example.com/avatar.jpg"
},
"messages": [
{
"id": 42,
"sender_id": 5,
"sender": {
"id": 5,
"name": "Jane Smith",
"avatar": "https://example.com/avatar.jpg"
},
"message": "<p>Hi, I have a question...</p>",
"read_at": null,
"created_at": "2026-02-20 12:00:00",
"is_mine": false
}
]
}

Soft-delete a thread for the current user.

Permission: Must be the sender or recipient

Deletion is user-specific: the other participant still sees the conversation. The row is permanently deleted only when both users have deleted it.

Response (200):

{
"deleted": true
}

Mark all messages in a thread as read for the current user.

Permission: Must be the sender or recipient

Response (200):

{
"success": true
}

Get the total unread message count for the current user.

Permission: Logged in

Response:

{
"count": 3
}

Get eligible message recipients for the current user.

Permission: Logged in

Parameters:

Parameter Type Default Description
course_id int 0 Filter recipients by course context
search string "" Search by display name, login, or email

Response:

[
{
"id": 12,
"name": "John Doe",
"email": "john@example.com",
"avatar": "https://example.com/avatar.jpg",
"role": "Instructor"
}
]

Namespace: ld-dashboard/v2

Report endpoints require the user to pass LD_Dashboard_REST_Permissions::check(). Administrators, instructors, and group leaders have access. Students are automatically scoped to their own data.


List all reports and charts available to the current user.

Permission: Administrator, instructor, or group leader

Response:

{
"success": true,
"data": {
"tables": {
"quiz-results": {
"id": "quiz-results",
"title": "Quiz Results",
"type": "table",
"exports": ["csv", "excel"]
}
},
"charts": {
"course-completion": {
"id": "course-completion",
"title": "Course Completion",
"type": "chart",
"chartType": "doughnut"
}
}
}
}

Get data for a specific table report.

Also accepts POST (for large filter payloads).

Permission: Administrator, instructor, or group leader

URL parameters:

Parameter Type Description
report_id string Report ID (e.g., quiz-results, essay-submissions)

Query parameters:

Parameter Type Default Description
course_id int 0 Filter by course ID
group_id int 0 Filter by group ID
lesson_id int 0 Filter by lesson ID
user_id int 0 Filter by user ID (auto-set for students)
status string all Filter by status
per_page int -1 Items per page (-1 for all)
page int 1 Page number

Response:

{
"success": true,
"data": {
"id": "quiz-results",
"title": "Quiz Results",
"type": "table",
"columns": [
{
"data": "student_name",
"title": "Student",
"visible": true,
"orderable": true
}
],
"data": [ /* row objects */ ],
"exports": ["csv", "excel"],
"meta": {
"report_id": "quiz-results",
"report_type": "table",
"total": 42,
"cached_at": "2026-02-20 14:00:00"
}
}
}

Report data is cached in WordPress transients for 1 hour (by default per get_cache_duration()).


Clear cached data for a specific report.

Permission: Administrator only

Response:

{
"success": true,
"message": "Cache cleared successfully."
}

Charts are served through the same /reports/{id} endpoint. The response structure differs for chart types.

Example chart response:

{
"success": true,
"data": {
"id": "course-completion",
"title": "Course Completion",
"type": "chart",
"chartType": "doughnut",
"chartData": {
"labels": ["Completed", "In Progress", "Not Started"],
"datasets": [
{
"label": "Course Completion",
"data": [45, 30, 25],
"backgroundColor": ["rgba(46,204,113,0.8)", "rgba(241,196,15,0.8)", "rgba(113,125,150,0.8)"],
"borderColor": ["rgba(46,204,113,1)", "rgba(241,196,15,1)", "rgba(113,125,150,1)"],
"borderWidth": 1
}
]
},
"options": {
"responsive": true,
"maintainAspectRatio": true,
"plugins": {
"legend": { "display": true, "position": "top" }
}
},
"meta": {
"report_id": "course-completion",
"report_type": "chart",
"chart_type": "doughnut",
"total": 3,
"cached_at": "2026-02-20 14:00:00"
}
}
}

Chart query parameters:

Parameter Type Default Description
course_id int 0 Filter by course
group_id int 0 Filter by group
filter string year Time range: year, month, or week
date_from string "" Start date in YYYY-MM-DD format
date_to string "" End date in YYYY-MM-DD format

Use these IDs as the report_id parameter in /reports/{report_id} requests.

Report ID Title Description
quiz-results Quiz Results Quiz attempt scores and pass/fail status per student
essay-submissions Essay Submissions Student essay submissions with grading status
assignment-status Assignment Status Assignment submissions with approval status
course-progress Course Progress Student progress through enrolled courses
time-by-course Time by Course Learning time totals broken down by course
time-by-student Time by Student Learning time totals broken down by student
time-by-content Time by Content Learning time broken down by lesson or topic
instructor-performance Instructor Performance Course completion rates and student counts per instructor
group-performance Group Performance Completion rates and activity per LearnDash group
quiz-question-analysis Quiz Question Analysis Per-question pass/fail rates across all attempts
Chart ID Title Chart Type Description
course-completion Course Completion Doughnut Completed vs. in-progress vs. not started
top-courses Top Courses Bar Courses ranked by enrollment or completion count
instructor-earnings Instructor Earnings Bar Commission earnings per instructor over time
time-spent Time Spent Bar Total learning time with week/month/year filter
time-trend Time Trend Line Learning time trend over a selected period
enrollment-trends Enrollment Trends Line New enrollments over time
revenue-per-course Revenue per Course Bar Revenue broken down by course
course-dropoff Course Drop-off Bar Where students stop progressing in a course

Use the ld_dashboard_reports_registered action to register your own report class after built-in reports load:

add_action( 'ld_dashboard_reports_registered', function( $registry ) {
LD_Dashboard_Report_Registry::register( 'my-report', 'My_Custom_Report_Class' );
} );

Your class must extend LD_Dashboard_Report_Base (table) or LD_Dashboard_Chart_Base (chart).


Namespace: ldd_report/v1

Get aggregate statistics for a specific user.

URL: /wp-json/ldd_report/v1/user/{id}/statistics

Permission: Administrator, instructor, or the user themselves

URL parameters:

Parameter Type Description
id int WordPress user ID

Query parameters:

Parameter Type Default Description
force bool false Bypass transient cache and recalculate fresh statistics

Response:

{
"success": true,
"cached": true,
"data": {
"user_id": 5,
"course_count": 12,
"lessons_count": 48,
"topics_count": 96,
"quizzes_count": 24,
"enrolled_course_count": 3,
"active_course_count": 2,
"completed_course_count": 1,
"approved_assignment_count": 7,
"not_approved_assignment_count": 3,
"graded_essays_count": 5,
"not_graded_essays_count": 2,
"students_count": 143,
"group_count": 4,
"certificate_count": 1,
"calculated_at": "2026-02-20 14:00:00"
}
}

cached is true when the response was served from the transient cache. Pass ?force=true to recalculate and refresh the cache. Statistics are cached for 1 hour per user.

Response field reference:

Field Description
course_count Courses created (instructors/admins) or completed quizzes (students)
lessons_count Lessons in the user’s courses
topics_count Topics in the user’s courses
quizzes_count Quizzes in the user’s courses (or completed quizzes for students)
enrolled_course_count Total courses the user is enrolled in
active_course_count Enrolled courses with status in_progress
completed_course_count Enrolled courses with status completed
approved_assignment_count Assignments with approval_status = 1
not_approved_assignment_count Assignments pending approval
graded_essays_count Essays marked as graded
not_graded_essays_count Essays pending grading
students_count Students enrolled in the user’s courses or groups
group_count LearnDash groups the user belongs to or manages
certificate_count Certificates earned by the user
calculated_at MySQL timestamp of when statistics were last calculated

All endpoints return standard WordPress REST error objects on failure:

{
"code": "ld_dashboard_forbidden",
"message": "You do not have permission to view this report.",
"data": { "status": 403 }
}
HTTP Status Code Meaning
401 rest_forbidden Not logged in
403 ld_dashboard_forbidden Insufficient permissions
404 ld_dashboard_not_found Report or message not found
500 ld_dashboard_error Server error during data fetch