Install our app for a better experience!

Results & Progress API

Results & Progress API

Bring your students' PrepareBuddy scores into your own system — a CRM, a student information system, a spreadsheet, a BI dashboard — on any schedule. It is the same organization API key and base URL as the provisioning endpoints, and it only reads: a read-only key is all it needs. New to APIs? Start with the API Quick Start; for a ready-made spreadsheet, see Recipe: Scores into Google Sheets.

Base URL: https://www.preparebuddy.com/api/v1/ (or your own PrepareBuddy address)

X-API-Key: <your-key>
Method & path Use it for
GET /results/ Every final result — language tests, quizzes and assessments — with a cursor so a nightly job gets only what changed.
GET /progress/daily/ A trend: one row per student per day per test type (attempts, average and best score).

Want results pushed as they happen? See Webhooks — the payload is the same result object.

Which results you get

  • Your students only: people who are members of your organization. Language-test practice they do is included; work assigned by another organization is not. (Details: Scope.)
  • Final results only, at the moment the student sees them:
  • a language test when it is finished — or, if your teachers review results first, when it is released;
  • a quiz when it is submitted;
  • an assessment when its feedback is released to the student.
  • Re-marks: if a result is re-scored later (for example a speaking answer finishes AI grading, or a teacher releases revised feedback), the same result appears again with the new score. Always upsert by id.

GET /results/

curl -s "https://www.preparebuddy.com/api/v1/results/?limit=100" -H "X-API-Key: <key>"

Query parameters

Parameter Meaning
cursor The next_cursor from your previous call. Omit it the first time.
since, until Only results that became final in this window (ISO 8601: 2026-09-01 or 2026-09-01T00:00:00Z).
kind test, quiz, assessment, or several: test,quiz. Default: all.
test_type Language-test type, e.g. ielts, toefl, pte_academic, sat.
email / user_id One student.
course_id Students enrolled in one of your courses (ids from GET /courses/).
limit 1–500 (default 100).
tz Write timestamps in your time zone, e.g. Asia/Kolkata (default UTC).

Response

{
  "status": "ok",
  "count": 1,
  "has_more": false,
  "next_cursor": "WyIyMDI2LTA5LTI3VDEwOjE1OjAzKzAwOjAwIiwgMCwgNDEyXQ",
  "results": [
    {
      "id": "test:3f8b2c1e-6a0d-4c7e-9b1a-2d4e5f6a7b8c",
      "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", "type_label": "IELTS"},
      "attempt": "practice",
      "section_practiced": null,
      "started_at": "2026-09-27T08:02:11+00:00",
      "completed_at": "2026-09-27T10:15:03+00:00",
      "released_at": null,
      "score": 7.5,
      "max_score": 9,
      "percentage": 83.3,
      "score_label": "IELTS band 7.5 / 9",
      "sections": {"listening": 8.0, "reading": 7.5, "writing": 6.5, "speaking": 7.0},
      "result_url": "https://www.preparebuddy.com/language-tests/session/3f8b2c1e-…/result/"
    }
  ]
}
Field Meaning
id Stable: test:<session>, quiz:<assignment>, assessment:<assignment>:<student>. Upsert by it.
kind test, quiz or assessment.
attempt practice (the student chose it), assigned (a teacher assigned it), testing_center (a conducted sitting), section_practice (one section only — see section_practiced).
score, max_score On the test's own scale (IELTS out of 9, TOEFL out of 120, SAT out of 1600 or 800 for one section…); a quiz as a percentage out of 100; an assessment as rubric points out of the rubric total.
percentage score ÷ max_score × 100 — comparable across test types.
sections Section scores on each test's own section scale (language tests only).
released_at When a result held for teacher review was released (language tests), or when assessment feedback was released.

Nightly sync, the whole recipe

  1. First run: call /results/ without a cursor; keep calling with cursor=<next_cursor> while has_more is true. Store the last next_cursor.
  2. Every night: call /results/?cursor=<stored cursor> the same way, and store the new next_cursor.
  3. Upsert each result by id.

next_cursor always points after the last result you received, so you never miss or double-count one, even if your job fails half-way — just run it again from the last cursor you stored.


GET /progress/daily/

A ready-made trend: per student, per day, per test type.

curl -s "https://www.preparebuddy.com/api/v1/progress/daily/?email=asha.rao@uni.example&from=2026-09-01&to=2026-09-30&tz=Asia/Kolkata" \
     -H "X-API-Key: <key>"
Parameter Meaning
from, to Dates (default: the last 30 days). Up to 366 days for one student, 92 days for everyone.
tz Time zone for "day", e.g. Asia/Kolkata (default UTC).
email / user_id / course_id / kind / test_type Same filters as /results/.
{
  "status": "ok", "from": "2026-09-01", "to": "2026-09-30", "timezone": "Asia/Kolkata", "count": 2,
  "days": [
    {"student": {"user_id": 812, "email": "asha.rao@uni.example", "first_name": "Asha", "last_name": "Rao"},
     "date": "2026-09-26", "kind": "test", "type": "ielts", "type_label": "IELTS",
     "attempts": 2, "average_percentage": 80.6, "best_percentage": 83.3,
     "average_score": 7.25, "best_score": 7.5, "max_score": 9},
    {"student": {"user_id": 812, "email": "asha.rao@uni.example", "first_name": "Asha", "last_name": "Rao"},
     "date": "2026-09-27", "kind": "quiz", "type": "quiz", "type_label": "Quiz",
     "attempts": 1, "average_percentage": 75.0, "best_percentage": 75.0,
     "average_score": 75, "best_score": 75, "max_score": 100}
  ]
}

average_score, best_score and max_score are on the test's own scale and are null when that day mixes different scales (for example a full SAT and a one-section SAT practice); average_percentage is always given. Days with no finished work are not listed.


Scope

Included Not included
Students of your organization: active members (student role) and anyone with an active or grace-period enrolment in one of your courses. Your staff (admins, examiners).
Their language-test attempts: practice they chose, tests you assigned, your Testing Center sittings, one-section practice. Work another organization assigned to the same student, and another organization's private tests.
Quizzes from your exam library and your assessments. Results still held for teacher review (they appear once released) and assessment feedback not yet sent to the student.

A student who belongs to two organizations is therefore reported to each only for their own and self-chosen practice work, never for the other organization's assignments.

Errors

Status Meaning
400 A parameter is invalid; error says which and how to fix it.
401 Missing, wrong or revoked API key.
404 email / user_id is not one of your organization's students.