Grow LMS API Documentation
Grow by Plenum — Data Schema Reference
Field-level reference for the records your integration consumes.
This is the companion reference to Webhooks and Pull-Based Data Access. It documents the structure of the four records a compliance integration works with day to day: learner progress, enrollment, certificate, and user. Use it to design the tables and mappings on your side.
It is intentionally focused, not exhaustive — Grow’s objects carry additional fields tied to commerce, community, and marketing that aren’t relevant to a workforce-training program; those are omitted here. Where a field matters to compliance reporting, it’s included.
Conventions used below
- Timestamps are Unix epoch values (seconds), unless noted. Fields that are empty until an event occurs (e.g. completion) are explicitly nullable.
- IDs are opaque strings — treat them as stable keys, not as anything to parse.
- Enums list the allowed values exactly as your integration will receive them.
1. UserProgress
The heart of compliance reporting: where a learner stands in a course. (A variant, UserProgressWithCourse, is identical but adds a course_id field so the record is self-identifying when returned in a list — noted at the end.)
| Field | Type | Description |
|---|---|---|
status |
string (enum) | Overall progress state. One of not_started, completed, not_completed. |
progress_rate |
number (float) | Percent of the course completed. |
average_score_rate |
number (float) | Average assessment score, as a percentage. |
time_on_course |
integer | Total time the learner has spent in the course, in seconds. |
total_units |
integer | Total number of learning activities (units) in the course. |
completed_units |
integer | Number of those units the learner has completed. |
completed_at |
number or null | Completion timestamp (Unix). Null while status is not_started or not_completed — only populated on actual completion. |
progress_per_section_unit |
array of objects | Per-section / per-unit breakdown (see below). |
progress_per_section_unit[] — each element carries a section_id (string) and a units array, letting you report progress at section and individual-unit granularity rather than only at the course level.
UserProgressWithCourseadds one field —course_id(string) — and is otherwise identical. It’s the shape you get when pulling progress across multiple courses, so each row says which course it belongs to.
2. Enrollment
Represents a learner’s access to a course — distinct from their completion of it.
| Field | Type | Description |
|---|---|---|
created |
number (float) | When access was granted, as a Unix timestamp. |
expires |
number (float) or null | When access ends, as a Unix timestamp. Null for access that does not expire. |
course |
object | The course the enrollment is for — includes id (string) and title (string), plus course metadata. |
Completion vs. access — the distinction to hold onto. Enrollment carries
createdandexpires; it does not carry a completion timestamp. Completion lives onUserProgress.completed_at. A learner can have active access without having completed, or have completed a course whose access later expires. Key compliance logic offcompleted_at; key access logic off theexpireswindow.
3. Certificate
An issued credential — the artifact your renewal clocks and credential records key off.
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier of the certificate. |
title |
string | Title of the certificate. |
issued |
number (float) | When the certificate was issued, as a Unix timestamp. |
attempts |
integer | Number of attempts made. |
type |
string (enum) | One of completion, certificate. |
status |
string (enum) | One of active, deleted. A revoked/invalidated certificate moves to deleted. |
score |
string | Score associated with the certificate. |
short_url |
string or null | A short link to the certificate, when available. |
provider |
string | The credentialing provider — Grow’s native certificate engine, or a third-party credentialing service where one is configured (e.g. Accredible, Credly). |
external_url |
string or null | The certificate’s URL when issued by an external credentialing service; null when issued by the native engine. |
form |
object or null | Display data printed on the certificate (see below). |
user |
object | The recipient — id (string) and email (string). |
course_id |
string | The course the certificate is for. |
form{} — the values rendered onto the certificate PDF: firstname, lastname, and ptin — an optional free-text field for a professional registration or license number to display on the credential.
4. User
The learner record — identity plus the attributes your reporting is keyed to. (Commerce- and affiliate-related fields exist on this object but are omitted here as out of scope for compliance integration.)
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier of the user. |
email |
string | The user’s email account. |
username |
string | Username; derived from first/last name in name-based mode. |
first_name |
string | First name. |
last_name |
string | Last name. |
created |
number (float) | When the user record was created, as a Unix timestamp. |
tags |
array of strings | Classification tags applied to the learner — commonly used to drive cohorts (region, crew, contractor vs. employee). |
fields |
object | Custom fields you define and populate (e.g. employee ID). Keys are your configured custom-field names. |
role |
object | The user’s role: level (enum) and name (string). |
is_suspended |
boolean | Whether the learner is currently suspended (access blocked) in the environment. |
last_login |
number (float) or null | Timestamp of the user’s last sign-in; null if they’ve never signed in. |
eu_customer |
boolean or null | Whether the user is located in Europe (relevant to data-handling obligations). |
role.level — one of admin, instructor, reporter, seat_manager, license_reporter, user. For a typical learner population this is user; the others denote administrative and reporting roles you may grant to your own staff.
There are also boolean role indicators (is_admin, is_instructor, is_reporter) that mirror the role level as convenience flags.
5. Cross-cutting notes
- Everything ties together by ID.
UserProgress/UserProgressWithCourse,Enrollment, andCertificateall reference a course byidand a learner by userid/email— those are your join keys into theUserrecord and your own systems. - Timestamps are uniform. Every date field above is a Unix epoch value, so a single conversion routine handles them all.
- Nullability is meaningful.
completed_at,expires,external_url, andlast_loginare null in specific, documented states — treat null as information (not yet completed, never expires, native-issued, never logged in), not as missing data.
6. Where to go next
- Pull-Based Data Access — how to retrieve these records and page through collections.
- Real-Time Data: Webhooks — the events that deliver these records in real time.
- Data Integration Overview — the high-level push/pull picture these records sit inside.
Prepared by Plenum Solutions for your evaluation. “Grow by Plenum” is operated and supported by Plenum on your behalf. Field availability is confirmed for your environment during onboarding. For integration design support, contact your Plenum engagement lead.


