Skip to content

Training ​

← Workspace APIs

A course is a training offering and the credits it is worth. A class is a scheduled run of a course, with its sessions and instructors. People register for classes, and Engagifii grants them training credits for attending a class or records credits transferred in from elsewhere.

Classes ​

A class is one scheduled run of a course: its dates, capacity, sessions and instructors. A class can be offered by one or more events, or by none (a standalone class).

EndpointMeaning
GET /classesList classes.
GET /classes/idsThe id of every live class. See Keeping a copy in sync.
GET /classes/{id}One class.

Filters, besides those in Paging:

ParameterTypeMeaning
event_idUUIDOnly classes this event offers. An event that is deleted or not in this workspace returns an empty list.
course_idUUIDOnly classes of this course.
json
{
  "id": "3f0c…",
  "name": "Ethics for Public Officials - Spring",
  "code": "ETH-101-S",
  "course": { "id": "7a2d…", "name": "Ethics for Public Officials" },
  "description": "Two half-day sessions on ethics rules for elected officials.",
  "starts_at": "2026-04-14T13:00:00Z",
  "ends_at": "2026-04-15T17:00:00Z",
  "time_zone": "Eastern Standard Time",
  "capacity": 40,
  "online_capacity": 20,
  "registration_state": "Open",
  "state": "Scheduled",
  "is_active": true,
  "type": { "id": "4b8e…", "name": "In-Person" },
  "session_type": "multi_session",
  "format": "in_person",
  "location": {
    "venue": {
      "id": "c4d8…",
      "name": "Capitol Conference Center",
      "address_line_1": "500 State Street",
      "address_line_2": null,
      "city": "Springfield",
      "state": "IL",
      "postal_code": "62701",
      "country": "United States"
    },
    "room": { "id": "a8b1…", "name": "Room 210", "building": "East Wing", "capacity": 50, "venue_id": "c4d8…" },
    "online_url": null
  },
  "contact_person_ids": ["51ad…"],
  "registration": {
    "is_on": true,
    "opens_at": "2026-02-01T14:00:00Z",
    "allows_non_members": true,
    "windows": [
      {
        "tier": "early",
        "ends_at": "2026-03-15T03:59:00Z",
        "member_fee": { "amount": "150.00", "currency": "USD" },
        "non_member_fee": { "amount": "225.00", "currency": "USD" },
        "max_members": 30,
        "max_non_members": 10
      },
      {
        "tier": "regular",
        "ends_at": "2026-04-10T03:59:00Z",
        "member_fee": { "amount": "175.00", "currency": "USD" },
        "non_member_fee": { "amount": "250.00", "currency": "USD" },
        "max_members": null,
        "max_non_members": null
      }
    ]
  },
  "lms_course_id": null,
  "lms_course_name": null,
  "event_ids": ["9b41…"],
  "sessions": [
    {
      "id": "c5e8…",
      "sequence": 1,
      "starts_at": "2026-04-14T13:00:00Z",
      "ends_at": "2026-04-14T17:00:00Z",
      "time_zone": "Eastern Standard Time",
      "description": "Day 1",
      "cancelled": false,
      "format": "in_person",
      "location": {
        "venue": null,
        "room": { "id": "a8b1…", "name": "Room 210", "building": "East Wing", "capacity": 50, "venue_id": "c4d8…" },
        "online_url": null
      },
      "instructors": [
        { "person_id": "51ad…", "is_lead": true, "is_guest": false }
      ],
      "contact_person_ids": [],
      "credits": [
        { "credit_type": { "id": "e017…", "name": "CLE" }, "credits": 4 }
      ]
    }
  ],
  "instructors": [
    { "person_id": "51ad…", "is_lead": true, "is_guest": false }
  ],
  "created_at": "2026-01-20T15:42:10Z",
  "updated_at": "2026-03-02T09:14:55Z"
}
FieldTypeMeaning
idUUIDThe class id.
namestring or nullThe name Engagifii shows for the class: its section name, else its class name, else its course's name.
codestring or nullThe class code.
courseobject or nullThe course this class runs. null if the class has no course.
course.idUUIDThe course id, as in /courses.
course.namestring or nullThe course's name.
descriptionstring or nullThe class description.
starts_atdate-time or nullWhen the class starts.
ends_atdate-time or nullWhen the class ends.
time_zonestring or nullThe class's time zone as entered in Engagifii.
capacityinteger or nullThe number of registrants the class allows.
online_capacityinteger or nullThe number of online registrants the class allows.
registration_statestring or nullThe class's registration state as shown in Engagifii.
statestring or nullThe class's state as shown in Engagifii.
is_activebooleanWhether the class is active.
typeobject or nullThe class type, from the workspace's own list, for example In-Person or Virtual. null if none is set.
type.idUUIDThe class type's id.
type.namestring or nullThe class type's name.
session_typestring or nullsingle (one session), multi_session or on_demand. null if not set.
formatstring or nullHow the class is delivered: in_person, online, in_person_and_online or unspecified. null if not set.
locationobject or nullWhere the class takes place. null if no venue, room or online link is recorded. See Class locations.
contact_person_idsarray of UUIDThe class's contact people, as in /people.
registrationobject or nullThe class's registration settings and price list. null if the class has none.
registration.is_onbooleanWhether registration is switched on.
registration.opens_atdate-time or nullWhen registration opens. null if no date is set.
registration.allows_non_membersbooleanWhether non-members may register.
registration.windowsarray of objectThe registration windows switched on, in the order early, regular, late. A registration's price_tier on /class-registrations names one of these.
registration.windows.tierstringearly, regular or late.
registration.windows.ends_atdate-time or nullWhen the window closes. null if no date is set.
registration.windows.member_feeobject or nullThe per-seat fee for members in this window, as amount (string) and currency (USD).
registration.windows.non_member_feeobject or nullThe per-seat fee for non-members in this window.
registration.windows.max_membersinteger or nullThe most members who can register in this window.
registration.windows.max_non_membersinteger or nullThe most non-members who can register in this window.
lms_course_idstring or nullFor a class taken in the workspace's learning management system (LMS), the course's id there. Progress is on /class-registrations (lms). null otherwise.
lms_course_namestring or nullFor a class linked to an LMS course, the LMS course's name. null otherwise.
event_idsarray of UUIDThe live events that offer this class, as in /events. Empty for a standalone class.
sessionsarray of objectThe class's sessions, in sequence order and then by start time.
sessions.idUUIDThe session id.
sessions.sequenceinteger or nullThe session's position in the class.
sessions.starts_atdate-time or nullWhen the session starts.
sessions.ends_atdate-time or nullWhen the session ends.
sessions.time_zonestring or nullThe session's time zone as entered in Engagifii.
sessions.descriptionstring or nullThe session description.
sessions.cancelledbooleanWhether the session is cancelled.
sessions.formatstring or nullHow the session is delivered: in_person, online, in_person_and_online or unspecified. null if not set.
sessions.locationobject or nullWhere the session takes place, in the same shape as the class's location. null if none is recorded.
sessions.instructorsarray of objectThe session's own instructors, lead instructors first, in the same shape as the class's instructors.
sessions.contact_person_idsarray of UUIDThe session's contact people, as in /people.
sessions.creditsarray of objectThe credits the session is worth, one entry per credit type.
sessions.credits.credit_type.idUUIDThe credit type id.
sessions.credits.credit_type.namestring or nullThe credit type's name, for example CLE.
sessions.credits.creditsnumberThe credits of that type the session is worth.
instructorsarray of objectThe class's instructors, lead instructors first.
instructors.person_idUUIDThe instructor, as in /people.
instructors.is_leadbooleanWhether this is a lead instructor.
instructors.is_guestbooleanWhether this is a guest instructor.
created_atdate-time or nullWhen the class was created.
updated_atdate-timeWhen the class last changed.

Class locations ​

location on a class and on each session gives the venue and room inline. There is no venues endpoint. The shapes match days[].venue on /events and rooms[] on /event-sessions.

FieldTypeMeaning
location.venueobject or nullThe venue. null if none is set.
location.venue.idUUIDThe venue's id.
location.venue.namestring or nullThe venue's name.
location.venue.address_line_1string or nullFirst address line.
location.venue.address_line_2string or nullSecond address line.
location.venue.citystring or nullCity.
location.venue.statestring or nullState.
location.venue.postal_codestring or nullPostal code.
location.venue.countrystring or nullCountry.
location.roomobject or nullThe room. null if none is set.
location.room.idUUIDThe room's id.
location.room.namestring or nullThe room's name.
location.room.buildingstring or nullThe building the room is in.
location.room.capacityinteger or nullHow many people the room holds.
location.room.venue_idUUID or nullThe room's venue.
location.online_urlstring or nullThe online meeting link. See below.

online_url is the meeting link reduced to its scheme, host and path. The query string and anything after # are removed, because meeting links often carry the meeting passcode in them. A value that is not a plain http or https link is left out, and the access details text (dial-in numbers, passcodes, sign-in details) is never returned. For a class taken in an LMS, online_url is always null; see lms_course_name.

Keeping classes in sync ​

updated_at changes only when the class itself changes. Changes to its sessions, session credits, session locations, instructors, contact people, registration settings or the events that offer it do not move it. Reload classes in full from time to time to pick these up.

Courses ​

A course is a training offering and the credits it is worth for each credit type. Its scheduled runs are classes, linked by course.id.

EndpointMeaning
GET /coursesList courses.
GET /courses/idsThe id of every live course. See Keeping a copy in sync.
GET /courses/{id}One course.

/courses has no filters besides those in Paging.

json
{
  "id": "7a2d…",
  "name": "Ethics for Public Officials",
  "description": "Ethics rules and disclosure duties for elected officials.",
  "type": { "id": "9e12…", "name": "Board Development" },
  "format": "in_person_and_online",
  "is_offered": true,
  "time_zone": "Eastern Standard Time",
  "status": "active",
  "credits": [
    { "credit_type": { "id": "e017…", "name": "CLE" }, "credits": 8 }
  ],
  "created_at": "2025-11-03T16:20:00Z",
  "updated_at": "2025-11-03T16:20:00Z"
}
FieldTypeMeaning
idUUIDThe course id.
namestring or nullThe course name.
descriptionstring or nullThe course description.
typeobject or nullThe course type, from the workspace's own list, for example Board Development. null if none is set.
type.idUUIDThe course type's id.
type.namestring or nullThe course type's name.
formatstring or nullHow the course is delivered: in_person, online, in_person_and_online or unspecified.
is_offeredbooleanWhether the course is marked as offered.
time_zonestring or nullThe course's time zone as entered in Engagifii.
statusstringactive or inactive.
creditsarray of objectThe credits the course is worth, one entry per credit type.
credits.credit_type.idUUIDThe credit type id.
credits.credit_type.namestring or nullThe credit type's name.
credits.creditsnumberThe credits of that type the course is worth.
created_atdate-time or nullWhen the course was created.
updated_atdate-timeFor courses, the time the course was created.

Engagifii records no change time for courses or their credits, so updated_at is the creation time and never moves. updated_since finds new courses only. Reload courses in full on each sync and compare with /courses/ids to find deleted ones.

Class registrations ​

A class registration records that a person registered for a class, with its status, format, fee and attendance. Registrations of deleted classes are left out. Cancelled registrations are included with status: cancelled.

EndpointMeaning
GET /class-registrationsList class registrations.
GET /class-registrations/idsThe id of every live class registration. See Keeping a copy in sync.
GET /class-registrations/{id}One class registration.

Filters, besides those in Paging:

ParameterTypeMeaning
class_idUUIDOnly registrations for this class.
person_idUUIDOnly registrations of this person.
statusstringOnly registrations with these statuses, comma-separated, for example complete,submitted. Any of the status values below except other.
json
{
  "id": "d29f…",
  "class_id": "3f0c…",
  "person_id": "84c7…",
  "status": "complete",
  "registration_number": "CR-10482",
  "format": "in_person",
  "price_tier": "early",
  "enrollment": "self",
  "enrolled_by_person_id": null,
  "is_member": true,
  "fee": { "amount": "150.00", "currency": "USD" },
  "attendance": { "status": "finalized", "value": 100, "overridden": false },
  "credits_earned": null,
  "credits_granted_at": null,
  "invoice_id": "1e6b…",
  "payment_id": "f3a0…",
  "event_id": null,
  "cancelled_at": null,
  "cancellation": null,
  "lms": null,
  "is_imported": false,
  "is_active": true,
  "registered_at": "2026-02-11T18:05:32Z",
  "created_at": "2026-02-11T18:05:32Z",
  "updated_at": "2026-02-11T18:05:32Z"
}
FieldTypeMeaning
idUUIDThe class registration id.
class_idUUIDThe class, as in /classes.
person_idUUIDThe person registered, as in /people.
statusstring or nullThe registration status. See below. null if the registration has no status.
registration_numberstring or nullThe registration number.
formatstring or nullHow the person attends: in_person or online.
price_tierstring or nullThe price window the person registered in: early, regular or late.
enrollmentstring or nullHow the registration was made: self, enrolled_by_staff or registered_on_behalf.
enrolled_by_person_idUUID or nullThe person who made the registration for someone else, as in /people.
is_memberbooleanWhether the person registered as a member.
feeobject or nullThe registration fee.
fee.amountstringThe amount, as a decimal string with two places, for example "150.00".
fee.currencystringAlways USD.
attendanceobjectThe attendance recorded on the registration.
attendance.statusstring or nulldid_not_attend, marked, finalized or unknown. null if none is recorded.
attendance.valuenumber or nullThe attendance value. Given only when attendance.status is finalized; if attendance was overridden, this is the override value.
attendance.overriddenbooleanWhether the attendance value was overridden.
credits_earnednumber or nullCredits recorded on the registration.
credits_granted_atdate-time or nullWhen those credits were granted.
invoice_idUUID or nullThe invoice for the registration, as in /invoices.
payment_idUUID or nullThe payment for the registration, as in /payments.
event_idUUID or nullThe event the registration was made through, for a class offered at an event, as in /events. null for a standalone class registration.
cancelled_atdate-time or nullWhen the cancellation was entered. null if the registration is not cancelled, or was cancelled without a cancellation record.
cancellationobject or nullDetails of the cancellation. Present only when status is cancelled, otherwise null.
cancellation.reasonstring or nullThe cancellation reason picked, from the workspace's own list. null if none was recorded.
cancellation.commentstring or nullThe comment entered with the cancellation, as typed.
cancellation.cancelled_by_person_idUUID or nullThe person who entered the cancellation, as in /people.
lmsobject or nullProgress reported by the workspace's LMS, for classes taken there. null if the LMS has reported nothing.
lms.statusstring or nullThe completion status as the LMS reports it.
lms.completion_percentagenumber or nullHow much of the course is complete, as a percentage.
lms.total_timestring or nullTime spent, as the LMS reports it, for example 12m 7s.
is_importedbooleanWhether the registration was imported rather than made in Engagifii.
is_activebooleanWhether the registration is active.
registered_atdate-time or nullWhen the person registered.
created_atdate-time or nullWhen the registration was created. Where Engagifii has no creation time, this is the registration time.
updated_atdate-timeWhen the registration last changed, as far as Engagifii records it. See below.

status values ​

ValueMeaning
seat_fullThe class was full.
startedThe registration was started but not finished.
pending_approvalThe registration is waiting for approval.
pending_approval_eligibleThe registration is waiting for approval and the person is eligible.
rejectedThe registration was rejected.
completeThe registration is complete. Engagifii's class roster shows a complete registration as submitted while its event invoice is unpaid; use invoice_id to apply the same rule.
cancelledThe registration was cancelled.
submittedA registration made through an event without payment. Engagifii shows it as completed unless the event counts only paid registrations.
otherA status not in this list.

Notes:

  • Attendance and credits are usually recorded per credit grant in /training-credits, not on the registration. Credits per credit type are there, linked by class_registration_id.
  • The same person can appear twice on one class, for example after an import. Both registrations are returned, as Engagifii's class roster shows them.

Engagifii rarely records a change time on class registrations, so updated_since mostly finds new registrations, not status changes such as approvals or cancellations. updated_at does not include cancelled_at, and LMS progress does not move it either. Reload class registrations in full, or per class with class_id, to pick up these changes. When a class is deleted, its registrations leave the list and /class-registrations/ids without a deleted record.

Training credits ​

A training credit is one grant of credits to a person: credits for attending a class (source: class) or credits transferred in (source: transfer). Credits of deleted courses are left out.

EndpointMeaning
GET /training-creditsList credit grants.
GET /training-credits/idsThe id of every credit grant. See Keeping a copy in sync.
GET /training-credits/{id}One credit grant.

Filters, besides those in Paging:

ParameterTypeMeaning
person_idUUIDOnly grants to this person.
class_idUUIDOnly grants for this class.
course_idUUIDOnly grants for this course.
json
{
  "id": "a8b3…",
  "person_id": "84c7…",
  "course_id": "7a2d…",
  "class_id": "3f0c…",
  "class_registration_id": "d29f…",
  "source": "class",
  "credit_type": { "id": "e017…", "name": "CLE" },
  "credits": 8,
  "counts_in_total": false,
  "attendance": { "attended": true, "value": null, "percentage": 100 },
  "granted_by_person_id": "51ad…",
  "granted_at": "2026-04-16T14:00:00Z",
  "updated_at": "2026-04-16T14:00:03Z"
}
FieldTypeMeaning
idUUIDThe credit grant id.
person_idUUIDThe person who received the credits, as in /people.
course_idUUIDThe course the credits are for, as in /courses.
class_idUUID or nullThe class the credits are for, as in /classes.
class_registration_idUUID or nullThe class registration the credits were granted on, as in /class-registrations. null for transfers.
sourcestringclass for credits granted for attending a class, transfer for credits transferred in.
credit_typeobject or nullThe type of credit.
credit_type.idUUIDThe credit type id.
credit_type.namestring or nullThe credit type's name.
creditsnumber or nullThe credits granted.
counts_in_totalbooleanWhether this grant counts in the person's total under the workspace's credit rule. See How credits are totalled.
attendanceobject or nullThe attendance the credits were granted for. null for transfers.
attendance.attendedboolean or nullWhether the person attended.
attendance.valuenumber or nullThe attendance value.
attendance.percentagenumber or nullThe attendance as a percentage.
granted_by_person_idUUID or nullThe person who granted the credits, as in /people.
granted_atdate-time or nullWhen the credits were granted.
updated_atdate-timeWhen Engagifii recorded the grant.

Engagifii can change or remove a credit grant without recording a time. Removed grants never come back in the deleted short form, and changed grants keep their updated_at. Reload training credits in full from time to time and compare with /training-credits/ids. When a course is deleted, its credit grants leave the list and /ids without a deleted record.

Course credits ​

A course credit is a person's credit for one course and one credit type, transfers included. It holds the first, highest and latest credit Engagifii recorded, and the one the workspace's credit rule counts.

EndpointMeaning
GET /course-creditsList course credits.
GET /course-credits/idsThe id of every course credit. See Keeping a copy in sync.
GET /course-credits/{id}One course credit.

Filters, besides those in Paging:

ParameterTypeMeaning
person_idUUIDOnly course credits of this person.
course_idUUIDOnly course credits for this course.
json
{
  "id": "6c19…",
  "person_id": "84c7…",
  "course_id": "7a2d…",
  "credit_type": { "id": "e017…", "name": "CLE" },
  "credits": 8,
  "credited_at": "2026-04-16T14:00:00Z",
  "counting_rule": "highest",
  "counts_in_total": true,
  "first": { "credits": 6, "granted_at": "2025-10-08T15:30:00Z" },
  "highest": { "credits": 8, "granted_at": "2026-04-16T14:00:00Z" },
  "latest": { "credits": 8, "granted_at": "2026-04-16T14:00:00Z" },
  "includes_transfer": false,
  "created_at": "2025-10-08T15:30:02Z",
  "updated_at": "2026-04-16T14:00:03Z"
}
FieldTypeMeaning
idUUIDThe course credit id.
person_idUUIDThe person, as in /people.
course_idUUIDThe course, as in /courses.
credit_typeobject or nullThe type of credit.
credit_type.idUUIDThe credit type id.
credit_type.namestring or nullThe credit type's name.
creditsnumber or nullThe credits the workspace's rule counts: the first, highest or latest value. Under every_credit, the first value.
credited_atdate-time or nullWhen the counted credits were granted.
counting_rulestringThe workspace's credit rule: first, highest, latest or every_credit. Same as training_credit_rule from /workspace.
counts_in_totalbooleanWhether credits counts in the person's total. true unless the rule is every_credit. See How credits are totalled.
firstobjectThe first credit recorded.
first.creditsnumber or nullThe credits.
first.granted_atdate-time or nullWhen they were granted.
highestobjectThe highest credit recorded.
highest.creditsnumber or nullThe credits.
highest.granted_atdate-time or nullWhen they were granted.
latestobjectThe most recent credit recorded.
latest.creditsnumber or nullThe credits.
latest.granted_atdate-time or nullWhen they were granted.
includes_transferbooleanWhether the credit comes from a transfer.
created_atdate-time or nullWhen the course credit was created.
updated_atdate-timeWhen the course credit last changed.

Engagifii removes course credits without recording a time, so removals never come back in the deleted short form. Compare with /course-credits/ids to find them. When a course is deleted, its course credits leave the list and /ids without a deleted record.

How credits are totalled ​

The workspace's training_credit_rule, from GET /workspace, decides which records make up a person's total for a credit type:

RuleSum thisRecords with counts_in_total: true
first, highest or latestcredits from /course-credits, one record per person, course and credit type/course-credits
every_creditcredits from /training-credits, one record per grant/training-credits

So, to total a person's credits, sum credits over the records with counts_in_total: true from both endpoints, grouped by credit_type.id.

counts_in_total, counting_rule, and credits and credited_at on course credits follow the workspace's current rule. If the rule changes, these fields change on every record but updated_at does not. Reload both endpoints in full after a rule change.