Skip to content

API documentation

Every institution has its own interactive API documentation, available at /docs/ from your Eduvem’s address - for example, https://love.eduvem.com/docs/. This is the material the technical team responsible for the integration (HR, ERP, BI or any external system) will use to learn about and test the API before writing any code.

Institution’s Integrations tab, with the API Documentation link and the API URL field

The documentation brings together every endpoint of the integration API: accepted parameters, request and response schemas, and the scopes each call requires. The page is interactive - you can expand any endpoint, fill in the parameters and send the request straight from the browser, using a real token, with no need for Postman or any other external tool.

On the institution settings’ Integrations tab (Institution > Integrations), the API Configuration for Integrations section shows:

  • The API Documentation link, which opens your institution’s /docs/.
  • The API URL, ready to copy - the base address used in every integration call.

To test a call directly in the interactive documentation - or to set up a real integration - you need a valid API token. Creating, revoking and scoping tokens is managed on the same Integrations tab: see Integration API tokens. Without a token, the documentation stays browsable and every endpoint remains visible, but the send-request button returns an authentication error.

An integration that treats each lecture as its own task - a personal development plan in an HR system, for example - can fetch a content’s lecture list and, per enrollment, the status of each one:

  • GET /integrations/courseVersions/{courseVersionUUID}/lessons returns the read-only, ordered list of the published content’s lectures - wizard lectures grouped by module, the SCOs of a SCORM package, or the single coursebox unit.
  • GET /integrations/enrollments/{enrollmentUUID}/lessons returns the same list for a specific enrollment, with each lecture’s “visited”/“completed” status and the enrollment’s overall progress.

Both calls have their own usage limit: 120 requests per minute, per institution, for each one.

Every field, scope and full example for each endpoint is in your institution’s interactive API documentation (above).

An integration that follows a track - a set of classes that make up a single pathway - can fetch the track’s list of steps and each participant’s progress in it:

  • GET /integrations/categories/{categoryUUID}/steps returns the read-only, ordered list of steps (classes) that make up the track, with each one’s name and its configured deadline in days (0 when there is no deadline). Only works for a category marked as a track - for any other category, the call returns a “not found” error.
  • GET /integrations/categories/{categoryUUID}/progress returns, per participant, the total steps completed and the state of each step (not enrolled, enrolled, blocked by an earlier step, awaiting evaluation, or completed). Requires the Reports (read) permission on the token and has its own usage limit: 120 requests per minute.

As with a content’s lectures, every field of each response is in your institution’s interactive API documentation (above).

Integrations with the company’s SST system (SOC, Senior, TOTVS) can fetch the completed NR trainings, the same ones in the Exporting NR trainings report:

  • GET /integrations/reports/nrTrainingRecords returns, paginated, the list of NR trainings with a certificate issued in the period. It requires the Reports (read) permission on the token. The certifiedSince parameter is required (yyyy-mm-dd or an ISO-8601 instant with Z or an offset) and certifiedUntil is optional (the default is now); ps caps the page at 500 records. The response also carries the total, the number of anonymized people excluded and the eSocial Tabela 28 layout version.

The endpoint has its own usage limit (60 requests per minute) and only answers for institutions with the NR feature enabled; for the others, the call returns an error. All fields are in your institution’s interactive API documentation (above).

An integration that shows a class’s progress in another system (a BI dashboard, for example) can query its aggregate summary:

  • GET /integrations/reports/courseClasses/{courseClassUUID}/summary returns the class’s number of enrolled participants and certificates, the completion rate and the average score. It requires the Reports (read) permission on the token and has its own usage limit: 120 requests per minute.

A class that exists but has no enrollments yet answers normally (HTTP 200) with an empty summary: enrolledCount and certifiedCount equal to 0, and completionRate and averageAssessmentScore null. A class that does not exist, was deleted, is a test class or belongs to another institution still returns “not found” (HTTP 404, courseClassNotFound).

Your HR system’s identifier (externalId)

Section titled “Your HR system’s identifier (externalId)”

When the institution loads people through people sync, each person has an externalId: the code your HR system uses for them. The integration API now returns it, so the external system does not need to match by e-mail or CPF:

  • Users (GET /integrations/users and the single-user lookup): externalId field.
  • Enrollments (GET /integrations/enrollments): personExternalId field, in the person block.
  • Enrollment and learning path webhooks: person.externalId field in the notice’s person block.
  • Filter: GET /integrations/users?externalId=<code> returns only the person whose externalId is exactly equal to the given value.

The key is omitted when the person has no externalId. For that reason, the responses and signed notices of institutions that do not use people sync stay identical to before. Each field is described in the interactive documentation, in all four languages.

To copy every enrollment of the institution into another system (a BI tool or a data lake, for example), use the cursor of GET /integrations/enrollments instead of requesting pages by number:

  1. Make the first call without pn (or with pn=1). Every full page carries a nextCursor field.
  2. Call again sending cursor=<the nextCursor you received>, exactly as it came, until a response carries a null nextCursor.

Every cursor page costs the same, whether it is the first or the thousandth, while asking for page 500 by number forces the previous 499 to be read again. In cursor responses, count, pageCount and pageNumber are null.

  • Do not combine cursor with a pn above 1, lastModified or startedSince, and repeat the same courseClassUUID, userUUID and teamUUID filters as the call that produced the cursor. Otherwise the response is a cursorConflict error.
  • Recent changes: the cursor only returns enrollments changed more than 5 minutes ago. A change shows up in a cursor copy after that.
  • At-least-once delivery: an enrollment changed during the copy can come again later on. Update by enrollmentUUID instead of inserting again.
  • Incremental sync: keep the largest lastModificationDate received and, on the next run, start with lastModified=<that value minus 5 minutes>.