List Students
Retrieve a paginated list of the course's buyers with visits and progress, newest order first unless you set sort. The list is not filtered by the summary window, so pagination.total can be larger than students_count on Get Summary.
Request
GET /players/{id}/analytics/students
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Course UUID. See Identifiers. |
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number. A missing, non-numeric, zero, or negative value is treated as 1. A page past the end returns an empty data array and 200. |
per_page | integer | 25 | Items per page (min: 1, max: 100). Anything else is 422. |
query | string | — | Part of the student's name, or the student's whole email address. Part of an email does not match. Longer than 255 characters is 422. |
sort | string | -ordered_at | full_name, ordered_at, first_visited_at, last_visited_at, visits_count, or progress_percent. A leading - sorts descending. null values sort last. Anything else is 422. |
Example Request
curl -X GET "https://app.easy.tools/api/v1/players/8f3c1a62-d047-4e89-9b25-1c6a4d8e0f71/analytics/students?sort=-progress_percent&per_page=25" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
Response
Success Response (200)
{
"data": [
{
"id": "1f7c2d9e4b6a48d3a5e09c71b2f4d8a6",
"full_name": "John Smith",
"email": "john@example.com",
"ordered_at": "2026-04-01T14:20:00.000Z",
"first_visited_at": "2026-04-02T09:05:00.000Z",
"last_visited_at": "2026-05-02T18:40:00.000Z",
"visits_count": 4,
"progress_percent": 50,
"has_certificate": false,
"order_url": "https://cart.easy.tools/creator/orders?uuid=5d2e8b14-9c63-4a7f-b081-3e6f2a9c7d45",
"customer_url": "https://cart.easy.tools/creator/customers?uuid=b7a41f30-2e9d-4c58-8f16-0d3c5e7a9b82"
},
{
"id": null,
"full_name": "Jane Doe",
"email": "jane@example.com",
"ordered_at": "2026-03-18T10:00:00.000Z",
"first_visited_at": null,
"last_visited_at": null,
"visits_count": 0,
"progress_percent": null,
"has_certificate": false,
"order_url": "https://cart.easy.tools/creator/orders?uuid=e3c9a72b-6f14-4d08-a5b3-91c2e8f04d67",
"customer_url": "https://cart.easy.tools/creator/customers?uuid=4a8d1e6c-0b52-4f97-8c3a-7e9f2d1b5c06"
}
],
"pagination": {
"current_page": 1,
"total_pages": 1,
"per_page": 25,
"total": 2
}
}
Response Fields
Each entry in data has the fields described in Student Object. id is the value List Student Lessons takes. A row with id null has no Easytools account and no lessons to read.
Pagination Object
See Pagination Object. total is the number of students that match query.
Error Responses
Not Found Error (404)
See Identifiers.
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found"
}
}
Validation Error (422 Unprocessable Entity)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The given data was invalid",
"details": {
"per_page": ["per_page must not be greater than 100"]
}
}
}
A bad sort or a query longer than 255 characters uses the same envelope, with details keyed by that parameter.
Bad Gateway Error (502)
Easycart answered, but not with a result the API can use.
{
"error": {
"code": "UPSTREAM_ERROR",
"message": "EasyCart rejected the request"
}
}
Service Unavailable Error (503)
Easycart is unreachable or failing. Retry later.
{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "EasyCart is unavailable"
}
}
Authentication, permission, and rate-limit errors are described in Authorization.