Install our app for a better experience!

Roster, Assignments & Activity API

Roster, Assignments & Activity API

Keep your own systems in step with PrepareBuddy: who your students are, what is assigned to them, how active they are — and assign work automatically. New to APIs? Start with the API Quick Start.

Base address: https://www.preparebuddy.com/api/v1/ · Header on every request: X-API-Key: <your-key>

Method & path Key needed Use it for
GET /students/ read-only or full Your whole roster: who, their access, their courses.
GET /catalog/ read-only or full Everything you can assign: language tests, quizzes, assessments — with their ids.
GET /assignments/ read-only or full What is assigned to whom, its status, due date — and the result it produced.
POST /assignments/ full Assign a test, quiz or assessment to a student.
GET /activity/daily/ read-only or full Engagement: time on the platform, tests started/finished, per student per day.

Paging (every list): the first call returns up to limit rows plus has_more and next_cursor. While has_more is true, call again adding cursor=<next_cursor>. Store the last next_cursor to continue later.

Times: timestamps are in UTC (+00:00). Add tz=Asia/Kolkata (any zone name such as Europe/London, America/New_York) to get them in local time instead.


GET /students/ — your roster

Every student of your organization: people with the student role, and anyone enrolled in one of your courses. Staff are not listed.

curl -H "X-API-Key: YOUR_KEY" "https://www.preparebuddy.com/api/v1/students/?status=active&limit=100"
Parameter Meaning
status active (a student with access now) or inactive (left, or access ended). Default: both.
course_id Only students enrolled in this course (ids from GET /courses/).
tz, limit (1–500, default 100), cursor See above.
{
  "status": "ok", "count": 1, "has_more": false, "next_cursor": "WzgxMl0",
  "students": [{
    "user_id": 812, "email": "asha.rao@uni.example", "first_name": "Asha", "last_name": "Rao",
    "has_set_password": true, "joined_at": "2026-08-01T09:12:00+00:00", "last_login": "2026-09-27T08:00:00+00:00",
    "membership": {"role": "member", "status": "active"},
    "enrollments": [{"course_id": 31, "course_name": "IELTS Batch A", "course_type": "ielts", "status": "active",
                     "start_date": "2026-08-01", "end_date": "2026-10-31", "grace_period_end": "2026-11-07",
                     "has_access": true}]
  }]
}
  • has_access — can the student use PrepareBuddy for that course today (including any grace period).
  • has_set_password — false means they have not signed in with a password yet (e.g. only from an LMS).

To look up one student, keep using GET /students/?email=… (API Reference).


GET /catalog/ — what you can assign

curl -H "X-API-Key: YOUR_KEY" "https://www.preparebuddy.com/api/v1/catalog/?kind=quiz"

kind is optional: test, quiz, assessment (comma-separate several).

{
  "status": "ok", "count": 2,
  "items": [
    {"kind": "test", "item_id": 57, "title": "IELTS Academic Mock 3", "type": "ielts", "type_label": "IELTS",
     "max_score": 9.0, "lti_link": "https://www.preparebuddy.com/lti/test/57/"},
    {"kind": "quiz", "item_id": 88, "title": "Grammar check 4", "type": "quiz", "type_label": "Quiz · 20 questions",
     "max_score": 100.0, "lti_link": "https://www.preparebuddy.com/lti/quiz/88/"}
  ]
}

Use kind + item_id with POST /assignments/. lti_link is the address for an LMS (LTI 1.1) link.


POST /assignments/ — assign work (full-access key)

Assign one test, quiz or assessment to one student — for example, when someone buys a mock test.

curl -X POST https://www.preparebuddy.com/api/v1/assignments/ \
     -H "X-API-Key: YOUR_FULL_ACCESS_KEY" -H "Content-Type: application/json" \
     -d '{"email": "asha.rao@uni.example", "kind": "test", "item_id": 57, "due_date": "2026-10-31"}'
Field Required Meaning
email or user_id yes The student. They must already be a student of your organization with access — onboard them first (Complete Onboarding Walkthrough).
kind yes test, quiz or assessment.
item_id yes From GET /catalog/.
due_date no 2026-10-31 (= end of that day) or an exact time 2026-10-31T18:00:00+05:30.
notify no false to skip the in-app "you have a new test" notice/email for language tests (default true).

Answer — assigned now (201):

{
  "status": "ok", "created": true,
  "assignment": {"id": "test-assignment:1f2e9c4a-…", "kind": "test",
                 "student": {"user_id": 812, "email": "asha.rao@uni.example", "first_name": "Asha", "last_name": "Rao"},
                 "item": {"id": 57, "title": "IELTS Academic Mock 3", "type": "ielts"},
                 "status": "pending", "overdue": false, "assigned_at": "2026-09-27T10:00:00+00:00",
                 "due_date": "2026-10-31T18:29:59+00:00", "completed_at": null, "result_id": null}
}

Answer — already assigned (200, "created": false): the student already has that work open, so the existing assignment is returned and nothing new is created. It is safe to repeat a call (a retried automation never assigns twice).

Error Why
403 read-only Use a full-access key.
404 student Not a student of your organization.
404 item Wrong item_id, or not yours — check GET /catalog/.
409 The student exists but currently has no access.

GET /assignments/ — what is assigned

curl -H "X-API-Key: YOUR_KEY" "https://www.preparebuddy.com/api/v1/assignments/?status=overdue&tz=Asia/Kolkata"
Parameter Meaning
status open (not finished), completed, or overdue (past due, not finished).
kind test, quiz, assessment.
email / user_id / course_id Narrow to students.
since Only assignments made on/after this date (e.g. 2026-09-01).
tz, limit (1–500), cursor See the top of this page.

Each row is the same object POST /assignments/ returns. status is pending, in_progress, submitted (an assessment handed in, awaiting marking), completed, or the assignment's own state such as expired. result_id matches the id in GET /results/ and in the result.final webhook — use it to join an assignment to its score.


GET /activity/daily/ — engagement

One row per student per day they were active, from PrepareBuddy's attendance register.

curl -H "X-API-Key: YOUR_KEY" "https://www.preparebuddy.com/api/v1/activity/daily/?from=2026-09-01&to=2026-09-30"
Parameter Meaning
from, to Dates (default: the last 30 days; at most 366 days per call).
email / user_id / course_id Narrow to students.
tz Writes first_seen_at / last_seen_at in your zone.
limit (1–1000, default 500), cursor Paging.
{
  "status": "ok", "from": "2026-09-01", "to": "2026-09-30", "day_timezone": "Asia/Kolkata",
  "count": 1, "has_more": false, "next_cursor": "…",
  "days": [{
    "student": {"user_id": 812, "email": "asha.rao@uni.example", "first_name": "Asha", "last_name": "Rao"},
    "date": "2026-09-26", "first_seen_at": "2026-09-26T03:10:00+00:00", "last_seen_at": "2026-09-26T05:02:00+00:00",
    "visits": 2, "active_minutes": 74, "page_views": 58, "tests_started": 1, "tests_completed": 1
  }]
}
  • date is a calendar day in day_timezone (the platform's register, India Standard Time). tz changes how the times are written, not which day a row belongs to.
  • A day with no activity has no row. The register is compiled once a day: yesterday is complete, today appears tomorrow.

For scores per day, use GET /progress/daily/.